/* * util.c -- general utility functions. */ #include #include "..\h\config.h" #include "general.h" #include "tproto.h" #include "..\h\cpuconf.h" #include "globals.h" #include "trans.h" #include "tree.h" extern int optind; extern char *ofile; /* * The following code is operating-system dependent [@util.01]. Define the * characters that terminate a file name prefix. */ #if PORT #define Prefix "/" Deliberate Syntax Error #endif /* PORT */ #if AMIGA #define Prefix "/:" #endif /* AMIGA */ #if ATARI_ST #define Prefix "/:\\" #endif /* ATARI_ST */ #if HIGHC_386 || MSDOS || OS2 #define Prefix "/:\\" #endif /* HIGHC_386 || MSDOS || OS2 */ #if MACINTOSH #define Prefix ":" #endif /* MACINTOSH */ #if MVS || VM #define Prefix "" #endif /* MVS || VM */ #if UNIX #define Prefix "/" #endif /* UNIX */ #if VMS #define Prefix "]:" #endif /* VMS */ /* * End of operating-system specific code. */ /* * Information about Icon functions. */ /* * Number of arguments. */ /* * Names of Icon functions. */ char *ftable[] = { #define FncDef(p,n) Lit(p), #define FncDefV(p) Lit(p), #include "..\h\fdefs.h" #undef FncDef #undef FncDefV }; int ftbsize = sizeof(ftable)/sizeof(char *); /* * alloc - allocate n bytes */ pointer alloc(n) unsigned int n; { pointer a; if (!(a = malloc((msize)n))) quit("out of memory"); return a; } /* * salloc - allocate and initialize string */ char *salloc(s) char *s; { return strcpy((char *)alloc((unsigned int)(strlen(s)+1)),s); } /* * tcalloc - allocate and zero m*n bytes */ pointer tcalloc(m,n) unsigned int m, n; { pointer a; if (!(a = calloc(m,n))) quit("out of memory"); return a; } /* * fparse - break a file name down into component parts. * Result is a pointer to a struct of static pointers good until the next call. */ struct fileparts *fparse(s) char *s; { static char buf[MaxFileName+2]; static struct fileparts fp; int n; char *p, *q; char *index(); #if MVS /* for any compiler which takes member names */ static char extbuf [MaxFileName+2] ; p = index(s, '('); if (p) { fp.member = p+1; memcpy(extbuf, s, p-s); extbuf [p-s] = '\0'; s = extbuf; } else fp.member = s + strlen(s); #endif /* MVS */ q = s; fp.ext = p = s + strlen(s); while (--p >= s) { if (*p == '.' && *fp.ext == '\0') fp.ext = p; else if (index(Prefix,*p)) { q = p+1; break; } } fp.dir = buf; n = q - s; strncpy(fp.dir,s,n); fp.dir[n] = '\0'; fp.name = buf + n + 1; n = fp.ext - q; strncpy(fp.name,q,n); fp.name[n] = '\0'; return &fp; } /* * makename - make a file name, optionally substituting a new dir and/or ext */ char *makename(dest,d,name,e) char *dest, *d, *name, *e; { struct fileparts fp; fp = *fparse(name); if (d != NULL) fp.dir = d; if (e != NULL) fp.ext = e; #if MVS if (*fp.member) sprintf(dest,"%s%s%s(%s", fp.dir, fp.name, fp.ext, fp.member); else #endif /* MVS */ sprintf(dest,"%s%s%s",fp.dir,fp.name,fp.ext); return dest; } /* * quit - immediate exit with error message */ novalue quit(msg) char *msg; { quitf(msg,""); } /* * quitf - immediate exit with message format and argument */ novalue quitf(msg,arg) char *msg, *arg; { extern char *progname; fprintf(stderr,"%s: ",progname); fprintf(stderr,msg,arg); fprintf(stderr,"\n"); #ifndef VarTran if (ofile) unlink(ofile); /* remove bad icode file */ #endif /* VarTran */ exit(ErrorExit); } /* * tsyserr is called for fatal errors. The message s is produced and the * translator exits. */ novalue tsyserr(s) char *s; { if (tok_loc.n_file) fprintf(stderr, "File %s; ", tok_loc.n_file); fprintf(stderr, "Line %d # %s\n", in_line, s); exit(ErrorExit); } /* * round2 - round an integer up to the next power of 2. */ unsigned int round2(n) unsigned int n; { unsigned int b = 1; while (b < n) b <<= 1; return b; } /* * sizearg - process -S command option. */ struct keyptr { /* structure for listing option chars */ char *cmd; /* option character(s) */ unsigned int *valp; /* pointer to value word */ }; static struct keyptr keytable[] = { /* maps keys to store addresses */ #define Size(cmd,vname,defalt) cmd, &vname, #define MinSize(x,y,z) #include "sizes.h" \* initialize from "sizes.h" data *\ #undef Size #undef MinSize 0, 0, /* terminate with null entry */ }; novalue sizearg(arg,argv) char *arg; char **argv; { struct keyptr *k; /* key table pointer */ char *s; /* value string pointer */ int v; /* option value */ for (k = keytable; k->cmd; k++) /* search for key match */ if (arg[0] == k->cmd[0] && (arg[0] != 'h' || arg[1] == k->cmd[1])) break; if (k->cmd == NULL) /* abort if not found */ quitf("unrecognized -S option: -S%s",arg); if (arg[0] == 'h') s = &arg[2]; /* find value */ else s = &arg[1]; if (*s == '\0') { /* if value is in next arg */ s = argv[optind++]; if (s == NULL) quitf("missing value: -S%s", arg); } v = (int)atol(s); /* convert integer -- check */ if (v <= 0) quitf("illegal value: -S%s", arg); *k->valp = v; /* store result */ } /* * smatch - case-insensitive string match - returns nonzero if they match */ int smatch(s,t) char *s, *t; { char a, b; for (;;) { while (*s == *t) if (*s++ == '\0') return 1; else t++; a = *s++; b = *t++; if (isupper(a)) a = tolower(a); if (isupper(b)) b = tolower(b); if (a != b) return 0; } }