rds95@leah.Albany.Edu ( Robert Seals) (08/27/87)
Yo, There is a problem - I'm sure you've heard about it already - in the otherwise wonderful ptc program posted to comp.sources.unix recently. It doesn't handle files correctly. Both the C and Pascal versions do the same thing. Perhaps I can illustrate... program ptcbug(input, output, f); var f: text; c: char; begin reset(f, 'ptcbug.p'); while not eof(f) do begin while not eoln(f) do begin read(f, c); write(c) end; readln(f); writeln end end. This is a reasonable program for 4.2 pc (did I say Ultrix?). It works, and even produces the correct result. But when the translated program is cc'ed, here is what happens... % ptc <ptcbug.p >ptcbug.c % cc ptcbug.c "ptcbug.c", line 66: operands of : have incompatible types "ptcbug.c", line 120: redeclaration of rewind So, I tracked down the problem, and it is in the `reset' - but the whole thing is done with macros, and upon expansion by cpp, here is what you get { ..... stuff ..... } main() { (f).init = (f).init ? ( ((f).out && !(f).eoln) ? ( ( f).buf = ('\n'), ( f).eoln = (( f).buf == '\n'), (void)fputc(( f).buf, ( f).fp), 0) : 0, rewind((f).fp)) : (((f).fp = Fopen( "ptcbug.p", Rmode)), 1), (f).eof = (f).out = 0, (f).init = 1, (f).eoln = (((f).buf = fgetc((f).fp)) == '\n') ? (((f).buf = ' '), 1) : 0; while (! ((((f).init == 0) ? ( fread((char *)&(f).buf, sizeof((f).buf), 1, (f).fp)) : 0, ((f).eof ? 1 : ((((f).fp)->_flag& 00020)!=0))) ? (boolean)1 : (boolean)0)) { while (! ((f).eoln ? (boolean)1 : (boolean)0)) { c = (f).buf, (f).init = 1, (f).eoln = (((f).buf = fgetc((f).fp)) == '\n') ? (((f).buf = ' '), 1) : 0; ( output).buf = (c), ( output).eoln = (( output).buf == '\n'), (void)fputc(( output).buf, ( output).fp); } Getl(&f); ( output).buf = ('\n'), ( output).eoln = (( output).buf == '\n'), (void)fputc(( output).buf, ( output).fp); } exit(0); { ....... more stuff ........} It's like, wow man, like I can't handle this action at all, ya no? So, somewhere up in the first line, there is an error in : . As far as the redefinition of rewind(), I am puzzled, because it puts the definition at the very end of the new C program. Hmm. Has anybody come up with anything that will make it work? Programs that use stdin and out all work fine, and this is a real bummer drag, because very few of my programs don't use files. HELP rob Robert Seals Atmospheric Sciences Research Center Try this one: rob@asrcmv.albany.edu It might work... This is more likely: ...leah.albany.edu!asrcmv!rob Or just use "r"! Or follow the From: path. I WANT TO MARRY LIZ FRASER AND I'VE NEVER EVEN MET HER --------------
wescott@sauron.Columbia.NCR.COM (Mike Wescott) (08/28/87)
In article <490@leah.Albany.Edu> rds95@leah.Albany.Edu ( Robert Seals) writes: > .......<stuff deleted>..... > % cc ptcbug.c > "ptcbug.c", line 66: operands of : have incompatible types > "ptcbug.c", line 120: redeclaration of rewind > > Has anybody come up with anything that will make it work? Programs that > use stdin and out all work fine, and this is a real bummer drag, > because very few of my programs don't use files. One fix is to replace the call to rewind with an equivalent fseek. There is also a bug in the way filenames are handled in the code emited for Fopen(). The bug can result in garbage or spaces in filenames opened. A third bug is the way colno is calculated - if a tab occurs in just before a tabstop colno is pushed one tabstop too far. I also added getchar() and putchar() to the cname list (this maybe just a SysV anomaly). I ran into problems porting TeX if changes weren't made in the defmach routine. These changes are included and force all arithmetic to be signed (on the C side). The emitted code for switch was changed to include a cast to int -- my C compiler complains if enums are switched. There is an initialization problem in the handling of the node created when a case statement is parsed. In some cases (pun) the generation of a nchoise-variant record can have the tchocon and tchostmt elements left uninitialized. For many implementations this ends up with nil or 0 in it. However if malloc or new cannot guareentee zero filled memory on mallocs then an occasional SIGSEGV may occur in linkup(). As patched, I have had no further while using it on an NCR-Tower32 (68020 and SystemV) in trying to port TeX to the Tower32. I'm still testing with initex but it looks very promising and I have gotten much further in the effort than with any of the Pascal compilers available for the Tower32. Patch below: *** ptc.p Mon Aug 24 10:02:22 1987 --- orig/ptc.p Thu Jul 30 22:10:58 1987 *************** *** 42,48 **** (** The code generated by the translator assumes that there is a **) (** C-implementation with at least a reasonable <stdio> library **) (** since all input/output is implemented in terms of C functions **) ! (** like fprintf(), getc(), fopen(), fseek() etc. **) (** If the source-program uses Pascal functions like sin(), sqrt() **) (** etc, there must also exist such functions in the C-library. **) (** **) --- 42,48 ---- (** The code generated by the translator assumes that there is a **) (** C-implementation with at least a reasonable <stdio> library **) (** since all input/output is implemented in terms of C functions **) ! (** like fprintf(), getc(), fopen(), rewind() etc. **) (** If the source-program uses Pascal functions like sin(), sqrt() **) (** etc, there must also exist such functions in the C-library. **) (** **) *************** *** 639,648 **** cetext, cextern, cfgetc, cfclose, cfflush, cfloat, cfloor, cfprintf, cfputc, cfread, cfscanf, cfwrite, ! cgetc, cgetchar, cgetpid, cint, cinclude, clong, clog, cmain, cmalloc, ! cprintf, cpower, cputc, cputchar, cread, ! creturn, cregister, cfseek, cscanf, csetbits, csetword, csetptr, cshort, csigned, csizeof, csprintf, cstdin, cstdout, cstderr, cstrncmp, cstrncpy, --- 639,648 ---- cetext, cextern, cfgetc, cfclose, cfflush, cfloat, cfloor, cfprintf, cfputc, cfread, cfscanf, cfwrite, ! cgetc, cgetpid, cint, cinclude, clong, clog, cmain, cmalloc, ! cprintf, cpower, cputc, cread, ! creturn, cregister, crewind, cscanf, csetbits, csetword, csetptr, cshort, csigned, csizeof, csprintf, cstdin, cstdout, cstderr, cstrncmp, cstrncpy, *************** *** 1235,1241 **** else write(c); if c = tab1 then ! colno := (((colno-1) div tabwidth) + 1) * tabwidth end; if lastchr > 0 then begin --- 1235,1241 ---- else write(c); if c = tab1 then ! colno := ((colno div tabwidth) + 1) * tabwidth end; if lastchr > 0 then begin *************** *** 3651,3664 **** tq^.tnext := mknode(nchoise); tq := tq^.tnext end; - tq^.tchocon := nil; - tq^.tchostmt := nil; tv := nil; repeat nextsymbol([sid, sinteger, schar, splus, sminus, send, sother]); if currsym.st in [send, sother] then ! goto 9959; if tv = nil then begin tv := pconstant(false); --- 3651,3662 ---- tq^.tnext := mknode(nchoise); tq := tq^.tnext end; tv := nil; repeat nextsymbol([sid, sinteger, schar, splus, sminus, send, sother]); if currsym.st in [send, sother] then ! goto 999; if tv = nil then begin tv := pconstant(false); *************** *** 7870,7879 **** ncase: begin indent; ! write('switch ((int)('); increment; eexpr(tp^.tcasxp); ! writeln(')) {'); decrement; echoise(tp^.tcaslst); indent; --- 7870,7879 ---- ncase: begin indent; ! write('switch ('); increment; eexpr(tp^.tcasxp); ! writeln(') {'); decrement; echoise(tp^.tcaslst); indent; *************** *** 8342,8348 **** if use(dreset) or use(drewrite) or use(dclose) then writeln(define, 'Finish(f) ((f).out && !(f).eoln) ? ', '(Putchr(', nlchr, ', f), 0) : 0, ', ! 'fseek((f).fp,0L,0)'); (* LIB *) if use(dclose) then begin writeln(define, 'Close(f) (f).init = ', --- 8342,8348 ---- if use(dreset) or use(drewrite) or use(dclose) then writeln(define, 'Finish(f) ((f).out && !(f).eoln) ? ', '(Putchr(', nlchr, ', f), 0) : 0, ', ! 'rewind((f).fp)'); (* LIB *) if use(dclose) then begin writeln(define, 'Close(f) (f).init = ', *************** *** 8363,8374 **** writeln(static, chartyp, tab1, 'Rmode[] = "r+";'); writeln(endif); writeln(define, 'Reset(f, n) (f).init = ', ! '(f).init ? fseek((f).fp,0L,0) : ', (* LIB *) ! '(((f).fp = Fopen(n, Rmode, sizeof(n))), 1), ', '(f).eof = (f).out = 0, Get(f)'); writeln(define, 'Resetx(f, n) (f).init = ', '(f).init ? (Finish(f)) : ', ! '(((f).fp = Fopen(n, Rmode, sizeof(n))), 1), ', '(f).eof = (f).out = 0, Getx(f)'); usefopn := true end; --- 8363,8374 ---- writeln(static, chartyp, tab1, 'Rmode[] = "r+";'); writeln(endif); writeln(define, 'Reset(f, n) (f).init = ', ! '(f).init ? rewind((f).fp) : ', (* LIB *) ! '(((f).fp = Fopen(n, Rmode)), 1), ', '(f).eof = (f).out = 0, Get(f)'); writeln(define, 'Resetx(f, n) (f).init = ', '(f).init ? (Finish(f)) : ', ! '(((f).fp = Fopen(n, Rmode)), 1), ', '(f).eof = (f).out = 0, Getx(f)'); usefopn := true end; *************** *** 8380,8391 **** writeln(static, chartyp, tab1, 'Wmode[] = "w+";'); writeln(endif); writeln(define, 'Rewrite(f, n) (f).init = ', ! '(f).init ? fseek((f).fp,0L,0) : ', (* LIB *) ! '(((f).fp = Fopen(n, Wmode, sizeof(n))), 1), ', '(f).out = (f).eof = 1'); writeln(define, 'Rewritex(f, n) (f).init = ', '(f).init ? (Finish(f)) : ', ! '(((f).fp = Fopen(n, Wmode, sizeof(n))), 1), ', '(f).out = (f).eof = (f).eoln = 1'); usefopn := true end; --- 8380,8391 ---- writeln(static, chartyp, tab1, 'Wmode[] = "w+";'); writeln(endif); writeln(define, 'Rewrite(f, n) (f).init = ', ! '(f).init ? rewind((f).fp) : ', (* LIB *) ! '(((f).fp = Fopen(n, Wmode)), 1), ', '(f).out = (f).eof = 1'); writeln(define, 'Rewritex(f, n) (f).init = ', '(f).init ? (Finish(f)) : ', ! '(((f).fp = Fopen(n, Wmode)), 1), ', '(f).out = (f).eof = (f).eoln = 1'); usefopn := true end; *************** *** 8752,8760 **** begin writeln; writeln(static, 'FILE *'); ! writeln('Fopen(n, m, l)'); writeln(chartyp, tab1, '*n, *m;'); - writeln(inttyp, tab1, 'l;'); writeln('{'); writeln(tab1, 'FILE', tab2, '*f;'); writeln(tab1, registr, chartyp, tab1, '*s;'); --- 8752,8759 ---- begin writeln; writeln(static, 'FILE *'); ! writeln('Fopen(n, m)'); writeln(chartyp, tab1, '*n, *m;'); writeln('{'); writeln(tab1, 'FILE', tab2, '*f;'); writeln(tab1, registr, chartyp, tab1, '*s;'); *************** *** 8766,8776 **** writeln(tab1, 'if (n == NULL)'); writeln(tab2, 'sprintf(tmp, ', tmpfilename, 'ch++);'); writeln(tab1, 'else {'); ! writeln(tab2, 'l = l < MAXFILENAME-1 ? l : MAXFILENAME-2;'); ! writeln(tab2, 'strncpy(tmp, n, l);'); ! writeln(tab2, 'tmp[l+1] = ', nulchr, ';'); ! writeln(tab2, 'for (s = tmp; *s; s++);'); ! writeln(tab2, 'for (; *s == ', spchr, ' || *s == ', nulchr, '; *s-- = ', nulchr,');'); writeln(tab1, '}'); writeln(tab1, 's = tmp;'); writeln(tab1, 'if ((f = fopen(s, m)) == NULL) {'); --- 8765,8779 ---- writeln(tab1, 'if (n == NULL)'); writeln(tab2, 'sprintf(tmp, ', tmpfilename, 'ch++);'); writeln(tab1, 'else {'); ! writeln(tab2, 'strncpy(tmp, n, sizeof(tmp));'); ! writeln(tab2, 'for (s = &tmp[sizeof(tmp)-1]; *s == ', ! spchr, ' || *s == ', nulchr, '; )'); ! writeln(tab3, '*s-- = ', nulchr, ';'); ! writeln(tab2, 'if (tmp[sizeof(tmp)-1]) {'); ! writeln(tab3, voidcast, 'fprintf(stderr, "Too long filename ', ! quote, '%s', quote, '\n", n);'); ! writeln(tab3, 'exit(1);'); ! writeln(tab2, '}'); writeln(tab1, '}'); writeln(tab1, 's = tmp;'); writeln(tab1, 'if ((f = fopen(s, m)) == NULL) {'); *************** *** 8782,8788 **** writeln(tab2, 'unlink(tmp);'); (* OS *) writeln(tab1, 'return (f);'); writeln('}'); ! writeln(xtern, inttyp, tab1, 'fseek();') end; if setcnt > 0 then econset(setlst, setcnt); --- 8785,8791 ---- writeln(tab2, 'unlink(tmp);'); (* OS *) writeln(tab1, 'return (f);'); writeln('}'); ! writeln(xtern, inttyp, tab1, 'rewind();') end; if setcnt > 0 then econset(setlst, setcnt); *************** *** 9506,9512 **** defname(cfscanf, 'fscanf '); (* LIB *) defname(cfwrite, 'fwrite '); (* LIB *) defname(cgetc, 'getc '); (* OS *) - defname(cgetchar, 'getchar '); (* LIB *) defname(cgetpid, 'getpid '); (* OS *) defname(cint, 'int '); defname(cinclude, 'include '); --- 9509,9514 ---- *************** *** 9517,9527 **** defname(cprintf, 'printf '); (* LIB *) defname(cpower, 'pow '); (* OS *) defname(cputc, 'putc '); (* LIB *) - defname(cputchar, 'putchar '); (* LIB *) defname(cread, 'read '); (* OS *) defname(creturn, 'return '); defname(cregister, 'register '); ! defname(cfseek, 'fseek '); (* LIB *) defname(cscanf, 'scanf '); (* LIB *) defname(csetbits, 'setbits '); defname(csetword, 'setword '); --- 9519,9528 ---- defname(cprintf, 'printf '); (* LIB *) defname(cpower, 'pow '); (* OS *) defname(cputc, 'putc '); (* LIB *) defname(cread, 'read '); (* OS *) defname(creturn, 'return '); defname(cregister, 'register '); ! defname(crewind, 'rewind '); (* LIB *) defname(cscanf, 'scanf '); (* LIB *) defname(csetbits, 'setbits '); defname(csetword, 'setword '); *************** *** 9686,9702 **** deftab[dmessage]^.tfuntyp := typnods[tnone]; deftab[dunpack]^.tfuntyp := typnods[tnone]; ! (* set up definitions for integer subranges CPU *) nmachdefs := 0; ! { defmach(0, 255, 'unsigned char ');} ! defmach(-128, 127, 'char '); ! { defmach(0, 65535, 'unsigned short ');} ! defmach(-32768, 32767, 'short '); ! defmach(-2147483647, 2147483647, 'long '); ! { defmach(0, 4294967295, 'unsigned long ');} end; (* initialize *) ! procedure exit(i : integer); forward; (* OS *) (* Action to take when an error is detected. *) procedure error; --- 9687,9703 ---- deftab[dmessage]^.tfuntyp := typnods[tnone]; deftab[dunpack]^.tfuntyp := typnods[tnone]; ! (* set up definitions for integer subranges *) nmachdefs := 0; ! defmach(0, 255, 'unsigned char '); (* CPU *) ! defmach(-128, 127, 'char '); (* CPU *) ! defmach(0, 65535, 'unsigned short '); (* CPU *) ! defmach(-32768, 32767, 'short '); (* CPU *) ! defmach(-2147483647, 2147483647, 'long '); (* CPU *) ! { defmach(0, 4294967295, 'unsigned long ');}(* CPU *) end; (* initialize *) ! procedure exit(i : integer); external; (* OS *) (* Action to take when an error is detected. *) procedure error; -- -Mike Wescott wescott@ncrcae.Columbia.NCR.COM
jerry@oliveb.UUCP (Jerry F Aguirre) (08/28/87)
In article <490@leah.Albany.Edu> rds95@leah.Albany.Edu ( Robert Seals) writes: >"ptcbug.c", line 66: operands of : have incompatible types >"ptcbug.c", line 120: redeclaration of rewind >As far as the redefinition of rewind(), I am puzzled, because it puts >the definition at the very end of the new C program. Hmm. While there doesn't seem to be enough of the code to prove this I have a suggestion as to what might be wrong. I have seen this type of error before and it is usually something like this. main() { ... x = somefunc(...); ... } char * somefunc(...) { ... } The problem is that the first usage of somefunc causes its returned type to default to "int". The subsequent declaration of "char *" or whatever will cause the "redeclaration of" error message. Of course if the function is later defined as really returning "int" then there is no conflict. The sollution is to declare the type of all non-int functions before using them. You can either put all the sub-function definitions before they are used, (yucky bottom down pascal style,) or just declare the type as in: char *somefunc(); main() ... How this relates to the pascal version I don't know. Jerry Aguirre