|
|
1.1 root 1: #define MARK (-1)
2: #define SYMTABSZ 4096
3: #define OUTFILE "a_out.c"
4: #define OUTFILE2 "a_out.o"
5: #define N 200
6: #define ON 77
7: #define OB 200
8:
9: char *symtout "a.out"; /* symbol table filename */
10: extern int unixfmt; /* if set, use unix format floating point */
11: extern int unsign; /* 1 for unsigned allowed, 0 for not */
12: static struct obj {
13: int type,size;
14: char text[2];
15: };
16: static char ib[N],ugb[N];
17: static int ibp {N}, ugbp {0};
18: static int ifp,ofp;
19: static char ob[OB];
20: static int obp,lpos;
21: static inputno;
22: static popt,nopt,vopt,qopt,uopt;
23: static eopt; /* use -E option */
24: static char *infile;
25: #define SHARPBUFL 256 /* chars in # lines max */
26: #define HEADLEN 4 /* chars in Q object header */
27: #define SHARPLEN 80 /* max characters in filename from # lines */
28: static char sharptext[SHARPLEN];
29: static int sharpn0,sharpn1; /* n1 = value from line n0 = inputno */
30:
31: main(ac,av)
32: int ac;
33: char **av;
34: {
35: int i;
36: char *s;
37: if(ac<2) {
38: printf("usage: fcc progname.c -options\n");
39: printf(" options: 'P' halt after text conversion\n");
40: printf(" 'n' norgen-format floating point constants\n");
41: printf(" 'v' verbose mode: lots of commentary\n");
42: printf(" 'q' quiet mode: warnings do not print\n");
43: printf(" 'u' no unsigned declaration generated\n");
44: printf(" 'E' use source line numbers if possible\n");
45: exit(0);
46: }
47: if(ac>2) {
48: s=av[2];
49: if(*s!='-') {
50: if(av[1][0]=='-') {
51: av[2]=av[1];
52: av[1]=s;
53: s=av[2];
54: }
55: else abt("bad option, expect -nPvqu");
56: }
57: while(*++s) {
58: nopt=| *s=='n';
59: popt=| *s=='P';
60: vopt=| *s=='v';
61: qopt=| *s=='q';
62: uopt=| *s=='u';
63: eopt=| *s=='E';
64: }
65: }
66: /* change to "!eopt" to reverse default meaning of E option */
67: if(eopt) {
68: system4("cc -E ",av[1]," >",OUTFILE); /* .i output */
69: for(i=0; av[1][i]; i++); av[1][--i]='i';
70: if(av[1][i-1]!='.')abt("need '.c' name");
71: system4("mv ",OUTFILE," ",av[1]);
72: }
73: else system4("cc -P ",av[1],"","");
74: for(i=0; av[1][i]; i++);
75: av[1][--i]='i';
76: if(--i<=0||av[1][i]!='.')abt("need '.c' name");
77: infile=av[1];
78: if((ifp=open(av[1],0))<0)abt("can't open .i for read");
79: if((ofp=creat(OUTFILE,0666))<0)abt("can't open fcc temp file");
80: symtab(SYMTABSZ);
81:
82: if(nopt) {
83: unixfmt=0;
84: if(vopt)printf("using -n: norgen-format float\n");
85: }
86: else unixfmt=1;
87:
88: if(uopt)unsign=0; /* no unsigned declaration in output */
89: else unsign=1; /* declare _ftou() and _ntou() unsigned */
90:
91: if(vopt)printf("begin %s-float conversion: file %s to %s\n",
92: unixfmt?"unix":"norgen",av[1],OUTFILE);
93: file();
94: flushout();
95: close(ifp);
96: close(ofp);
97: if(popt==0) system4("rm ",av[1],"","");
98: else {
99: if(vopt)printf("conversion input is %s\n",av[1]);
100: if(vopt)printf("conversion output is %s\n",OUTFILE);
101: if(vopt)printf("-P option: quit.\n");
102: exit(0);
103: }
104: system4("cc -c -O ",OUTFILE,"","");
105: system4("rm ",OUTFILE,"","");
106: for(i=0; av[1][i]; i++);
107: av[1][--i]='o';
108: system4("mv ",OUTFILE2," ",av[1]);
109: exit(0);
110: }
111: system4(s1,s2,s3,s4)
112: char *s1,*s2,*s3,*s4;
113: {
114: char s[100];
115: int i;
116: i=0; while(*s1)s[i++]= *s1++;
117: while(*s2)s[i++]= *s2++;
118: while(*s3)s[i++]= *s3++;
119: while(*s4)s[i++]= *s4++;
120: s[i]=0;
121: if(vopt)printf("%s\n",s);
122: if(fork()==0) execl("/bin/sh","sh","-c",s,0);
123: wait(&i);
124: if(i) {
125: printf("bad termination status from %s\n",s);
126: exit(1);
127: }
128: return ;
129: }
130:
131: abt(s)
132: char *s;
133: {
134: printif();
135: printf("%s line %d abort in fcc\n",infile,inputno+1);
136: printf(" %s\n",s);
137: flushout();
138: exit(1);
139: }
140:
141: warn(s)
142: char *s;
143: {
144: if(qopt)return;
145: printif();
146: printf("%s line %d warn: %s\n",infile,inputno+1,s);
147: }
148:
149: gc() /* get a character */
150: {
151: int i,j;
152: if((i=gc2())!='/')return(i); /* not a comment */
153: if((j=gc2())!='*') {
154: ug(j); /* not a comment */
155: return(i);
156: }
157: /* skip till end of comment */
158: while(1) {
159: while((i=gc2())!='*') if(i==0)abt("unclosed comment");
160: if((i=gc2())=='/') return(' '); /*replace comment by blank*/
161: ug(i);
162: }
163: }
164:
165: gc2() /* used to be gc(): this entry doesn't strip comments */
166: {
167: int i,j,k;
168: char *temp; /* buffer for # line */
169: char outtemp[16]; /* buffer for # number on line numbers */
170: static int newline 1; /* if 1, next char starts a new line. check for # */
171: if(ugbp==0) {
172: gc2top: if(ibp>=N) {
173: j=read(ifp,&ib,N);
174: if(j<0)j=0;
175: for(i=j; i<N; i++) ib[i]=0;
176: ibp=0;
177: }
178: if(newline) { /* check for # line to skip */
179: newline=0;
180: if(sharptext[0]) { /* toss out # n file if ever seen # */
181: for(k=0; outtemp[k]="# "[k]; k++);
182: outtemp[i=k+5]=0; /* convert 5 digits */
183: j=inputno-sharpn0+sharpn1;
184: while(j) {
185: outtemp[--i]=j%10+'0';
186: j=/10;
187: }
188: while(outtemp[k++]=outtemp[i++]);
189: outtemp[k-1]='\n';
190: write(ofp,outtemp,k);
191: }
192: if(ib[ibp]=='#') {
193: temp=getq(SHARPBUFL-HEADLEN); /* get buffer for line */
194: for(i=0; i<SHARPBUFL;) {
195: if((temp[i++]=gc2())=='\n')break;
196: }
197: write(ofp,temp,i);
198: sharpn0=inputno;
199: j=1; while(temp[j]==' ')j++;
200: if(temp[j]=='\n')goto skipx;
201: sharpn1=0;
202: while(temp[j]>='0'&&temp[j]<='9')sharpn1=sharpn1*10
203: +temp[j++]-'0';
204: while(temp[j]==' ')j++;
205: if(temp[j]=='\n')goto skipx;
206: i=0;
207: while(temp[j]!='\n'&&i<SHARPLEN-1)
208: sharptext[i++]=temp[j++];
209: sharptext[i]=0;
210: skipx:
211: free(temp);
212: goto gc2top;
213: }
214: }
215: inputno=+newline=ib[ibp]=='\n'; /* ha! */
216: while((j=ib[ibp++])=='\\') {
217: if((i=gc())!='\n') {
218: ug(i);
219: return('\\');
220: }
221: }
222: return(j);
223: }
224: return(ugb[ugbp--]);
225: }
226:
227: ug(c) /* unget a character */
228: int c;
229: {
230: ugb[++ugbp]=c;
231: if(ugbp>=N-1)abt("unget buffer overflow");
232: return(c);
233: }
234:
235:
236: outq(op)
237: struct obj *op;
238: {
239: int i,j,k;
240: int c;
241: char *s;
242: k=op->size;
243: s=op->text;
244: for(i=0; i<k; i++) {
245: c= *s++;
246: ob[obp++]=c;
247: if(c=='\n') flushout();
248: lpos=+ c!=MARK;
249: if(lpos>ON||obp>=OB) partial();
250: }
251: }
252:
253: flushout()
254: {
255: int i,j,k;
256: if(obp<=0)return(0);
257: for(i=j=0; i<obp; i++) {
258: if(ob[i]!=MARK)ob[j++]=ob[i];
259: }
260: if(j==0)ob[j++]='\n';
261: if(ob[j-1]!='\n')ob[j++]='\n';
262: if(write(ofp,ob,j)<=0) {
263: obp=0;
264: abt("write error");
265: }
266: lpos=obp=0;
267: }
268:
269: partial()
270: {
271: int i,j,k,l;
272: for(i=j=k=0; i<obp; i++) {
273: if(ob[i]==MARK) {
274: if(k<ON) j=i;
275: }
276: else k++;
277: }
278: if(j==0) {
279: l=obp;
280: for(i=ON; i>0; --i)if(ob[i-1]!='\\')break;
281: if(i==0)abt("funny line in 'partial()'");
282: k=ob[i];
283: j=ob[i+1];
284: ob[i]='\\';
285: ob[i+1]='\n';
286: obp=i+2;
287: flushout();
288: obp=l;
289: ob[i]=k;
290: ob[i+1]=j;
291: for(j=lpos=0; i<l; i++) {
292: lpos=+ (ob[j++]=ob[i])!=MARK;
293: }
294: obp=j;
295: return(0);
296: }
297: else {
298: ob[j++]='\n';
299: l=obp;
300: obp=j;
301: flushout();
302: for(i=lpos=0; j<l; j++) {
303: lpos=+ (ob[i++]=ob[j])!=MARK;
304: }
305: obp=i;
306: return(0);
307: }
308: }
309: static printif() {
310: if(sharptext[0]==0)return;
311: printf("%s line %d & ",sharptext,inputno-sharpn0+sharpn1);
312: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.