📄 misc.c
字号:
/************************************************************* * File: tools/misc.c * Purpose: provide common routines for the pmcc compiler drivers * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970303 Added getStrn() & str2file(). * 970303 extent: added quick return if '.' not found. * 981028 Added do_board() and getStdArgs(). * 990108 Added -DBDMRxxxx to -board option. * 990112 Added pmon as a fake board type. */#include <stdio.h>#include <malloc.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#ifdef MSDOS#include <process.h>#endif#include "../include/defines.h"#define HEAPSZ 3000long malloc_mem[HEAPSZ];long *malloc_ptr;int long_cmds_ok;int prom,mips4k,mips16,xflash;char *stdcrt0;int striequ(char *s1,char *s2);/************************************************************** Malloc(sz)* For some reason we run out of memory really quickly* under MSDOS. So I provide my own simple malloc.*/char *Malloc(sz)int sz;{char *p;#ifdef MSDOSif (malloc_ptr == 0) malloc_ptr = malloc_mem;p = malloc_ptr;sz = ((sz+7)&~3)/sizeof(long);malloc_ptr += sz;if (malloc_ptr >= &malloc_mem[HEAPSZ]) p = 0;#elsep = malloc(sz);#endifif (!p) { fprintf(stderr,"Malloc: out of memory\n"); exit(1); }return(p);}/* This include must be here. Not earlier in the file. */#include "misc.h"Str crt0;/************************************************************** appendFile(dst,src)*/appendFile(dst,src)char *dst,*src;{int c;FILE *dfp,*sfp;if (vflag) fprintf(stderr,"cat %s >> %s\n",src,dst);sfp = fopen(src,"r");if (sfp == 0) { fprintf(stderr,"Can't open %s\n",src); Exit(1); }dfp = fopen(dst,"a+");if (dfp == 0) { fprintf(stderr,"Can't open %s\n",dst); Exit(1); }for (;;) { c = getc(sfp); if (c == EOF) break; putc(c,dfp); }fclose(sfp);fclose(dfp);}/************************************************************** str2file(fname,str)* write a string to a file*/str2file(fname,str)char *fname,*str;{FILE *dfp;if (vflag) fprintf(stderr,"echo %s > %s\n",str,fname);dfp = fopen(fname,"w");if (dfp == 0) { fprintf(stderr,"Can't open %s\n",fname); Exit(1); }fprintf(dfp,"%s\n",str);fclose(dfp);}/************************************************************** fileExists(p)* returns true if the file exists*/fileExists(p)char *p;{struct stat st;if (stat(p,&st)) return(0);return(1);}/************************************************************** getHead(d,s)* isolates the file name, e.g. "jim/fred.o" returns "fred" in d.*/char *getHead(d,s)char *d,*s;{char *b,*e;b = strrchr(s,'/');if (b) b++;else b = s;e = strrchr(s,'.');strncpy(d,b,e-b);d[e-b] = 0;return(d);}/************************************************************** getRoot(d,s)* isolates the root, e.g. "jim/fred.o" returns "jim" in d.*/char *getRoot(d,s)char *d,*s;{char *b,*e;b = strrchr(s,'/');if (!b) b = s;strncpy(d,s,b-s);d[b-s] = 0;if (*d == 0) strcpy(d,".");return(d);}/************************************************************** char *extent(s)* returns a pointer to the extent portion of a filename*/char *extent(s)char *s;{char *p;p = strrchr(s,'.');if (!p) return(0);return(p+1);}/************************************************************** int argvize(av,s) * place address of each word in s into the array av* If av==0, only return number of words.*/int argvize(av,s)char *av[];char *s;{char **pav = av, c;int ac;for (ac=0;;ac++) { /* step over cntrls and spaces */ while(*s && *s <= ' ') ++s; /* if eos quit */ if (!*s) break; c = *s; /* find end of word */ if (pav) *pav++ = s; while(' ' < *s) ++s; /* not eos inc ptr */ if(*s) *s++ = 0; }return(ac);}/************************************************************** addarg(d,s)* add an argument to a growing list*/addarg(d,s)Str *d;char *s;{Strcat(d," ");Strcat(d,s);}/************************************************************** mkfile(name,str)*/mkfile(name,str)char *name,*str;{FILE *fp;char *p;fp = fopen(name,"w");if (fp == 0) { fprintf(stderr,"can't open %s\n",name); Exit(1); }for (p=strtok(str," ");p;p=strtok(0L," ")) { fprintf(fp,"%s\n",p); }fclose(fp);}/************************************************************** prfile(name)* print a file. Used by the vflag*/prfile(name)char *name;{FILE *fp;int c;fp = fopen(name,"r");if (fp == 0) { fprintf(stderr,"can't open %s\n",name); Exit(1); }printf("%s: ",name);while ((c=getc(fp)) != EOF) { if (c == '\n') c = ' '; putchar(c); }printf("\n");fclose(fp);}/************************************************************** fixstruct(in,out)* used for some assemblers that don't support the .struct* directive. This is a hack, not especially robust.*/fixstruct(in,out)char *in,*out;{FILE *ifp,*ofp;char *p;char plabel[100],pval[100];char label[100],val[100],direct[100];int structflg;ifp = fopen(in,"r");ofp = fopen(out,"w");structflg = 0;while (fgets(tmp,LNMAX,ifp) != NULL) { if (tmp[0] == '#') { fputs(tmp,ofp); continue; } strcpy(tmp2,tmp); tmp2[strlen(tmp2)-1] = 0; /* remove terminating \n */ p = strtok(tmp2," \t"); if (p == NULL) ; else if (structflg) { if (strequ(p,".data")||strequ(p,".text")) structflg = 0; else { tmp[strlen(tmp)-1] = 0; /* remove terminating \n */ /* terminate line at /* */ if (p=strstr(tmp,"/*")) *p = 0; /* replace ':' with ' '*/ if (p=strchr(tmp,':')) *p = ' '; if (!(p=strtok(tmp," \t"))) continue; if (*p != '.') { strcpy(label,p); p = strtok(0," \t"); } if (!p) p = ""; strcpy(direct,p); strcpy(val,p+(strlen(p)+1)); if (strlen(label)) sprintf(tmp,"#define %s (%s+(%s))\n",label, plabel,pval); strcpy(plabel,label); if (strequ(direct,".space")) strcpy(pval,val); else if (strequ(direct,".word")) strcpy(pval,"4"); else if (strequ(direct,".half")) strcpy(pval,"2"); else if (strequ(direct,".byte")) strcpy(pval,"1"); else strcpy(pval,"0"); strcpy(label,""); } } else if (strequ(p,".struct")) { structflg = 1; strcpy(tmp,"\t/* struct 0 */\n"); strcpy(plabel,"0"); strcpy(pval,"0"); } fputs(tmp,ofp); }fclose(ifp);fclose(ofp);}/************************************************************** char *strdchr(p) * deletes the first char from the string p */char *strdchr(p)char *p;{char *t;if (!p) return(p);for (t=p;*t;t++) *t = *(t+1);return(p);}/************************************************************** fixhash(in,out)* used for some preprocessors to remove the mips '#' style* assembly comments.*/fixhash(in,out)char *in,*out;{FILE *ifp,*ofp;int c,state,col,deol;ifp = fopen(in,"r");ofp = fopen(out,"w");col = deol = state = 0;while (1) { c = getc(ifp); if (c == EOF) break; col++; if (c == '\n') { col = 0; deol = 0; } if (deol) continue; switch (state) { case 0 : if (c == '/') state = 1; break; case 1 : if (c == '*') state = 2; else state = 0; break; case 2 : if (c == '*') state = 3; break; case 3 : if (c == '/') state = 0; else state = 2; } if (c == '#' && col > 1 && state == 0) { deol = 1; continue; } putc(c,ofp); }fclose(ifp);fclose(ofp);}#ifdef MSDOS/************************************************************** System(cmd)* a system() function for MSDOS.*/System(cmd)char *cmd;{int i,hasredir,len;char *p,*av[40],*arglist,*fname,*vtmp;hasredir = 0;if (vflag) fprintf(stderr,"%s\n",cmd);len = strlen(cmd);for (p=cmd;*p;p++) if (*p == '\'') strdchr(p); /* delete quotes */for (p=cmd;*p && *p != ' ';p++) ; /* find end of cmdname */*p = 0; arglist = p+1;for (p=cmd;*p;p++) if (*p == '/') *p = '\\'; /* fix forw slashes */vtmp = malloc(len+20);if (p=strchr(arglist,'>')) { /* find redirection */ *p = 0; fname = p+1; hasredir = 1; }if (!long_cmds_ok && len > 100) { sprintf(vtmp,"%s %scmdfile",cmd,cmdchar); mkfile(cmdfile,arglist); /* create the cmdfile */ if (vflag) prfile(cmdfile); }else sprintf(vtmp,"%s %s",cmd,arglist);if (hasredir) { strcat(vtmp," > "); strcat(vtmp,fname); }if (vflag) fprintf(stderr,"%s\n",vtmp);/* If the cmd uses redirection we must use system(). * However, system() doesn't set the return codes properly, so * use spawnvp() if we can. */if (hasredir) { i = system(vtmp); free(vtmp); return(i); }for (i=0,p=strtok(vtmp," ");p;p=strtok(0," ")) { if (i >= 40) { fprintf(stderr,"System: too many args\n"); exit(1); } av[i++] = p; }av[i] = 0;i = _spawnvp(_P_WAIT,av[0],av);free(vtmp);return(i);}#else /* Unix */System(x)char *x;{if (vflag) fprintf(stderr,"%s\n",x);return system(x);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -