mp-utils/src/support.h

210 lines
4.1 KiB
C

#include <iso646.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
/* Error constants */
enum
{
UNKNOWN_FAIL = 1,
MALLOC_FAIL,
NEEDARG_FAIL,
FOPEN_FAIL,
WRITE_FAIL,
TIME_FAIL,
MISC_FAIL
};
/* Standard data identifiers for nodes */
enum
{
CHAR = 1,
INT,
LONG,
DOUBLE,
CHARP,
INTP,
LONGP,
DOUBLEP,
NODEP
};
/* node - node type suitable for being a member in a linked list. */
/* name - the name of the data in this node */
/* data - pointer to arbitrary data */
/* type - implementation-defined identifier for what kind of data this node holds */
typedef struct LNODE
{
struct LNODE *previous;
char *name;
void *data;
int type;
struct LNODE *next;
} node;
/* Condition should be one of the above enum'd strings. Info is optional; it can just be NULL when irrelevant. */
void throw(long unsigned int condition, void *info)
{
switch(condition)
{
case UNKNOWN_FAIL: printf("unknown failure\n");
exit(UNKNOWN_FAIL);
case MALLOC_FAIL: printf("malloc failure\n");
exit(MALLOC_FAIL);
case NEEDARG_FAIL: printf("usage: %s\n", (char *) info);
exit(NEEDARG_FAIL);
case FOPEN_FAIL: printf("failed to open: %s\n", (char *) info);
exit(FOPEN_FAIL);
case WRITE_FAIL: printf("failed to write: %s\n", (char *) info);
exit(WRITE_FAIL);
case TIME_FAIL: printf("time error: %s\n", (char *) info);
exit(TIME_FAIL);
case MISC_FAIL: printf("%s\n", (char *) info);
exit(MISC_FAIL);
default: printf("You shouldn't be seeing this.\nSomething is very wrong.\n");
exit(-256);
}
}
/* mid_mempcpy -- copy n bytes from s2 to s1 starting at position p */
int mid_mempcpy(char *s1, char *s2, int n, int p)
{
int i;
i = 0;
for(i = 0; i <= n; i++, p++)
{
s1[p] = s2[i];
}
return(0);
}
/* arrccat -- function to copy arr2len bytes from arr2 to the arr1len'th position of arr1. returns *newarr, and stores the length */
/* of newarr[] in arr1len (that's why it needs to be a pointer to arr1len and not just a long unsigned integer). */
char *arrccat(char *arr1, char *arr2, size_t *arr1len, size_t arr2len)
{
char *newarr;
unsigned int i, i2;
newarr = malloc(*arr1len+arr2len);
i = i2 = 0;
for(i = 0; i < *arr1len; i++)
{
newarr[i] = arr1[i];
}
for(i2 = 0; i2 < arr2len; i2++, i++)
{
newarr[i] = arr2[i2];
}
*arr1len = *arr1len+arr2len;
return newarr;
}
/* mastrcat -- improved string concat function. returns a pointer to the first element in a buffer containing the strings str1 */
/* and str2 joined end-to-end. */
char *mastrcat(char *str1, char *str2)
{
unsigned long int nbi, stri, nbsize;
char *nbuf;
nbi = stri = 0;
nbsize = (strlen(str1) + strlen(str2));
nbuf = malloc(nbsize);
for(stri = 0; str1[stri] != '\0'; nbi++, stri++)
{
nbuf[nbi] = str1[stri];
}
for(stri = 0; str2[stri] != '\0'; nbi++, stri++)
{
nbuf[nbi] = str2[stri];
}
return nbuf;
}
/* open stdin if path is null */
FILE *file_open(char *path, char *mode)
{
FILE *fd;
fd = 0;
if(!mode)
{
return(NULL);
}
if(path == NULL || !strcmp(path, "-"))
{
fd = fopen("/dev/stdin", mode);
}
else
{
fd = fopen(path, mode);
}
if(!fd)
{
return(NULL);
}
return(fd);
}
/* return a buffer containing the contents of fd, or NULL if failure. Store the size of the new buffer in newsize; -1 on fail. */
char *file_read(FILE *fd, int *newsize)
{
int bufsize, c, i;
char *buf, *tmpbuf;
/* bufsize is arbitrary */
bufsize = 4096;
c = i = 0;
buf = tmpbuf = 0;
if( !(buf = malloc(bufsize)))
{
*newsize = -1;
return(NULL);
}
for(i = 0; (c = fgetc(fd)) != EOF; i++)
{
if(i >= bufsize)
{
if( !(tmpbuf = malloc(bufsize *= 2)))
{
*newsize = -1;
return(NULL);
}
memcpy(tmpbuf, buf, i-1);
free(buf);
buf = tmpbuf;
}
buf[i] = c;
}
*newsize = i;
return(buf);
}