static char rcsid[] = "$Header: /usr/jjc/dvitops/RCS/util.c,v 1.7 90/10/16 07:56:29 jjc Exp $"; #include "util.h" enum message_type history = INFORMATION; #ifdef STDARG void message(enum message_type type, char *format,...) #else void message(va_alist) va_dcl #endif { int c, n; char *s; #ifndef STDARG enum message_type type; char *format; #endif va_list ap; #ifdef STDARG va_start(ap, format); #else va_start(ap); type = va_arg(ap, enum message_type); format = va_arg(ap, char *); #endif if (program_name != NULL) { fputs(program_name, stderr); fputs(": ", stderr); } switch (type) { case FATAL_ERROR: fputs("fatal error: ", stderr); break; case ERROR: fputs("error: ", stderr); break; case WARNING: fputs("warning: ", stderr); break; } while ((c = *format++) != '\0') if (c == '%') { c = *format++; switch(c) { case '%': putc('%', stderr); break; case 'd': n = va_arg(ap, int); fprintf(stderr, "%d", n); break; case 's': s = va_arg(ap, char *); fputs(s, stderr); break; default: fprintf(stderr, "...whoops! error while handling error\n"); exit(FATAL_ERROR); } } else putc(c, stderr); fputc('\n', stderr); va_end(ap); if (type == FATAL_ERROR) exit(FATAL_ERROR); if ((int)type > (int)history) history = type; } static int safecat(s1, s2, n) char *s1, *s2; int n; { if (strlen(s1) + strlen(s2) + 1 > n) return FALSE; strcat(s1, s2); return TRUE; } /* does s1 end with s2 ? */ static int strends(s1, s2) char *s1, *s2; { int n2 = strlen(s2); int n1 = strlen(s1); if (n1 < n2) return FALSE; #ifdef CASE_INSENSITIVE_FILENAMES return stricmp(s1 + n1 - n2, s2) == 0; #else return strcmp(s1 + n1 - n2, s2) == 0; #endif } /* if ext is not NULL and filename does not end with ext, ext will be appended to filename */ FILE *xfopen(filename, is_binary, al, ext) char *filename, *al, *ext; int is_binary; { char path[FILENAME_MAX+1]; static char list_sep[2] = {AREA_LIST_SEP, '\0'}; #ifdef AREA_SEP static char sep[2] = {AREA_SEP , '\0'}; #endif /* AREA_SEP */ char *area; char area_list[FILENAME_MAX*4]; if (al == NULL || FILENAME_HAS_AREA(filename)) { if (ext != NULL && !strends(filename, ext)) { path[0] = '\0'; safecat(path, filename, sizeof(path)); safecat(path, ext, sizeof(path)); if (is_binary) return FOPEN_RB(path); else return fopen(path, "r"); } else { if (is_binary) return FOPEN_RB(filename); else return fopen(filename, "r"); } } if (strlen(al)+1 > sizeof(area_list)) message(FATAL_ERROR, "directory list too long: %s", al); strcpy(area_list, al); for (area = strtok(area_list, list_sep); area != NULL; area = strtok(NULL, list_sep)) { #ifdef AREA_SEP char *p; #endif /* AREA_SEP */ FILE *fp; path[0] = '\0'; #ifndef POSTFIX_AREA if (!safecat(path, area, sizeof(path))) continue; #ifdef AREA_SEP p = path + strlen(path); if (p > path && p[-1] != AREA_SEP #ifdef AREA_SEP2 && p[-1] != AREA_SEP2 #endif /* AREA_SEP2 */ ) { if (!safecat(path, sep, sizeof(path))) continue; } #endif /* AREA_SEP */ #endif /* not POSTFIX_AREA */ if (!safecat(path, filename, sizeof(path))) continue; if (ext != NULL && !strends(filename, ext)) safecat(path, ext, sizeof(path)); #ifdef POSTFIX_AREA #ifdef AREA_SEP if (area[0] != AREA_SEP #ifdef AREA_SEP2 && area[0] != AREA_SEP2 #endif /* AREA_SEP2 */ ) { if (!safecat(path, sep, sizeof(path))) continue; } #endif /* AREA_SEP */ if (!safecat(path, area, sizeof(path))) continue; #endif /* POSTFIX_AREA */ if (is_binary) { if ((fp = FOPEN_RB(path)) != NULL) return fp; } else { if ((fp = fopen(path, "r")) != NULL) return fp; } } return NULL; } #ifdef CASE_INSENSITIVE_FILENAMES int stricmp(s1, s2) char *s1, *s2; { for (;;) { char c1 = *s1, c2 = *s2; if (c1 == '\0') { if (c2 == '\0') return 0; else return -1; } else if (c2 == '\0') return 1; if (isascii(c1) && isupper(c1)) c1 = tolower(c1); if (isascii(c2) && isupper(c2)) c2 = tolower(c2); if (c1 != c2) return c1 - c2; s1++; s2++; } } #endif /* CASE_INSENSITIVE_FILENAMES */ #ifdef NEED_MEM_FUNCTIONS int memcmp(s1, s2, n) char *s1, *s2; int n; { for (; --n >= 0; s1++, s2++) if (*s1 != *s2) return *s1 - *s2; return 0; } char *memcpy(s1, s2, n) char *s1, *s2; int n; { char *p = s1; while (--n >= 0) *p++ = *s2++; return s1; } char *memset(s, c, n) char *s; int c, n; { char *p = s; while (--n >= 0) *p++ = c; return s; } #endif /* NEED_MEM_FUNCTIONS */ #ifdef NEED_QSORT /* This is a heap sort. */ void qsort(v, n, width, compar) char *v; int n, width; int (*compar)(); { char *ip; char *buf; char *last = v + (n - 1)*width; if ((buf = malloc(width)) == 0) out_of_memory(); for (ip = v + (n/2)*width; ip >= v; ip -= width) { char *jp = ip; memcpy(buf, ip, width); for (;;) { char *cp = jp + (jp - v) + width; if (cp < last) { char *ocp = cp + width; if ((*compar)(ocp, cp) > 0) cp = ocp; } else if (cp != last) break; if ((*compar)(buf, cp) >= 0) break; memcpy(jp, cp, width); jp = cp; } memcpy(jp, buf, width); } ip = last; while (ip > v) { char *jp = v; int j; memcpy(buf, ip, width); memcpy(ip, v, width); ip -= width; for (;;) { char *cp = jp + (jp - v) + width; if (cp < ip) { char *ocp = cp + width; if ((*compar)(ocp, cp) > 0) cp = ocp; } else if (cp != ip) break; memcpy(jp, cp, width); jp = cp; } j = (jp - v)/width; while (j != 0) { char *kp; j = (j - 1)/2; kp = v + j*width; if ((*compar)(kp, buf) >= 0) break; memcpy(jp, kp, width); jp = kp; } memcpy(jp, buf, width); } free(buf); } #endif /* NEED_QSORT */ #ifdef NEED_STRTOK char *strtok(s1, s2) char *s1, *s2; { static char *next; register char *s = s1 != NULL ? s1 : next; char *start; for (;;) { register char *p; register char c = *s; if (c == '\0') { next = s; return NULL; } for (p = s2; *p != '\0' && *p != c; p++) ; if (*p == '\0') break; s++; } start = s; for (;;) { register char *p; register char c = *++s; if (c == '\0') { next = s; return start; } for (p = s2; *p != '\0'; p++) if (*p == c) { *s = '\0'; next = s + 1; return start; } } } #endif /* NEED_STRTOK */ #ifdef PRIMOS_GETENV /* Prime C doesn't provide a getenv function, but there are 'global variables' that are like enviroment variables. The routine gvget will retrieve the value of one of these, so we can write a getenv using it. */ char *getenv(name) char *name; { char temp[32]; extern char *strncat(), *gvget(); strcpy(temp,"."); return(gvget(strncat(temp,name,32))); } #endif /* PRIMOS_GETENV */ #ifdef EBCDIC static int cnva[]={ 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, 215,216,217,226,227,228,229,230,231,232,233,173,224,189,113,109, 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, 151,152,153,162,163,164,165,166,167,168,169,192, 79,208, 95, 7, 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,225, 65, 66, 74,114, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87, 88, 89, 98, 99,100,101,102,103,104,105,112, 67, 68,115,116,117, 118,119,120,128,138,139,140,141,142,143,144,154,155,156,157,158, 159,160,170,171,172,161,174,175,176,177,178,179,180,181,182,183, 184,185,186,187,188,106,190,191,202,203,204,205,206,207,218,219, 220,221,222,223,234,235,236,237,238,239,250,251,252,253,254,255 }; char atoe(char c) /* convert the c from ascii to ebcdic */ { return(cnva[c]); } #endif /* EBCDIC */ /* Local Variables: c-indent-level: 4 c-continued-statement-offset: 4 c-brace-offset: -4 c-argdecl-indent: 0 c-label-offset: -4 tab-width: 4 End: */