Files
sics/tecs/util.c
2000-03-15 10:10:22 +00:00

193 lines
4.1 KiB
C

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include "errhdl.h"
#include "util.h"
/* when changing FBUF_LEN, change also the constant in the fscanf call in subroutine LscExeCmd */
#define FBUF_LEN 132
char *str_split(char *str, char sep, char *list[], int *n) {
int i;
char *s, *e;
s=str;
for (i=0; i<*n; i++) {
list[i]=s;
e=strchr(s, sep);
if (e==NULL) { *n=i+1; return(NULL); }
s=e+1;
e--;
while (e>str && *e==' ') e--; /* trim sequence */
e[1]='\0';
}
return(s);
}
char *str_split1(char *str, char sep) {
char *s, *e;
e=strchr(str, sep);
if (e==NULL) {
s=NULL;
e=str+strlen(str);
} else {
s=e+1;
}
e--;
while (e>str && *e==' ') e--; /* trim sequence */
e[1]='\0';
return(s);
}
char *str_ntrim(char *dest, int ldest, const char *src, int lsrc) {
char *s, *e;
if (lsrc<ldest) ldest=lsrc;
if (dest!=src) strncpy(dest, src, ldest);
e=dest+ldest-2;
while (e>dest && *e==' ') e--; /* trim sequence */
e[1]='\0';
return(s);
}
char *str_read_until(FILE *fil, char *term, char *buf, char *end) {
char *s;
char fmt[24];
int i, l, siz;
char ch;
siz=end-buf-1;
if (siz<1) return(NULL);
sprintf(fmt, "%s%d[^%s%s", "%", siz, term, "]%n%c");
i=fscanf(fil, fmt, buf, &l, &ch);
if (i<0) { /* eof */
buf[0]='\0';
return(&buf[0]);
} else if (i==0) { /* fscanf returns 0 if first char is terminator */
buf[0]=fgetc(fil);
return(&buf[0]);
} else if (i==1) { /* terminator not found -> read until eof */
buf[l]='\0';
return(&buf[l]);
} else {
buf[l]=ch;
if (l==siz && NULL==strchr(term, ch)) return(NULL);
return(&buf[l]);
}
}
char *str_read_arg(char *file, char *args[], int nargs) {
FILE *fil;
char *str, *s, *e, *p, *q;
char ch;
int i, l, size;
struct stat statbuf;
i=stat(file, &statbuf);
if (i<0) ERR_MSG("file not found");
size=statbuf.st_size+4;
if (nargs>0) size+=size/2+100; /* max size */
while (1) {
ERR_SP(str=malloc(size));
e=&str[size-1];
ERR_SP(fil=fopen(file, "r"));
s=str;
while (1) {
p=str_read_until(fil, "#!", s, e);
if (p==NULL) break;
if (*p=='!') {
q=str_read_until(fil, "\n", p, e);
if (q==NULL) { p=NULL; break; }
s=p; *s='\n'; s++;
} else if (*p=='#') {
ch=fgetc(fil);
i=ch-'0';
if (i<0 || i>=nargs) {
s=p+1; *s=ch; s++;
} else {
l=strlen(args[i]);
if (s+l>=e) { p=NULL; break; }
strcpy(p, args[i]);
s=p+l;
}
} else {
assert(*p=='\0');
break;
}
}
ERR_SI(fclose(fil));
if (p!=NULL) break;
size=size*3/2; /* allocation not sufficient -> try again */
free(str);
}
assert(strlen(str)<size);
return(str);
OnError: return(NULL);
}
void str_replace_char(char *str, char ch, char rep) {
char *s;
assert(ch!='\0' && ch!=rep);
s=strchr(str, ch);
while (s!=NULL) {
*s=rep;
s=strchr(s, ch);
}
}
void str_upcase(char *str) {
while (*str!='\0') {
*str=toupper(*str); str++;
}
}
int str_cmp(const char *str1, const char *str2) {
int i;
char ch1, ch2;
ch1=tolower(*(str1++)); ch2=tolower(*(str2++));
i=1;
while (ch1!='\0' && ch2!='\0' && ch1==ch2) {
ch1=tolower(*(str1++)); ch2=tolower(*(str2++)); i++;
}
if (ch1<ch2) {
return(-i);
} else if (ch1>ch2) {
return(i);
}
return(0);
}
int str_ncpy(char *dst, const char *src, int maxdest) {
strncpy(dst, src, maxdest);
if (dst[maxdest-1]!='\0') {
dst[maxdest-1]='\0';
ERR_MSG("destination string too short");
}
return(0);
OnError: return(-1);
}
int str_ncat(char *dst, const char *src, int maxdest) {
strncat(dst, src, maxdest-strlen(dst)-1);
if (dst[maxdest-1]!='\0') {
dst[maxdest-1]='\0';
ERR_MSG("destination string too short");
}
return(0);
OnError: return(-1);
}
void util_delay(int tmo_msec) {
struct timeval tmo;
tmo.tv_sec=tmo_msec / 1000;
tmo.tv_usec=(tmo_msec % 1000)*1000+1;
select(1,NULL,NULL,NULL,&tmo);
}