flaps@dgp.toronto.edu (Alan J Rosenthal) (06/07/88)
I wrote these routines before seeing Richard O'Keefe's, but I decided to post them anyway because I think they're a little more complete. There is a program to warn about trigraphs, one to trigraph-ize, another to de-trigraph-ize. I am placing them in the public domain. If your compiler doesn't have options to do these functions, distribute these programs or ones like them with your compiler. ajr This is the LAST posting that should be missing my .signature: -- - Any questions? - Well, I thought I had some questions, but they turned out to be a trigraph. -- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # tri.c # untri.c # warnt.c # This archive created: Mon Jun 6 22:58:59 1988 # By: Alan J Rosenthal (University of Toronto) export PATH; PATH=/bin:$PATH if test -f 'tri.c' then echo shar: will not over-write existing file "'tri.c'" else cat << \SHAR_EOF > 'tri.c' /* * tri.c - convert everything in sight to trigraphs. * * If you have index() instead of strchr(), compile with -Dstrchr=index. * * The #ifdef unix lines just provide better arg checking. * * Alan J Rosenthal <flaps@gpu.utcs.toronto.edu>, 2 June 1988. */ #include <stdio.h> #ifdef unix #include <sys/types.h> #include <sys/stat.h> #endif #define TRUE 1 #define FALSE 0 #define SUCCESS 0 #define FAILURE (-1) #define STREQ(s,t)(*(s) == *(t) && strcmp((s),(t)) == 0) char *progname; main(argc,argv) int argc; char **argv; { int status; FILE *in,*fopen(); #ifdef unix struct stat statbuf; #endif progname = argv[0]; status = 0; if(argc < 1) /* only some systems */ { fprintf(stderr,"usage: %s [file ...]\n",progname); exit(1); } else if(argc == 1) { status += process(stdin,"stdin"); } else { while(--argc > 0) { argv++; if(STREQ(*argv,"-")) { status += process(stdin,"-"); } else { if((in = fopen(*argv,"r"))) { #ifdef unix if(fstat(fileno(in),&statbuf) != 0) { /* shouldn't happen */ fprintf(stderr,"%s: can't fstat\n",*argv); exit(1); } if((statbuf.st_mode & S_IFMT) == S_IFDIR) { fprintf(stderr,"%s is a directory!\n",*argv); status++; } else { status += process(in,*argv); } #else status += process(in,*argv); #endif (void)fclose(in); } else { perror(*argv); } } } } exit(status); } /* process - process input file */ int process(fp,name) FILE *fp; char *name; { char buf[300],*p,*trip; static char triable[] = "#[\\]^{|}~"; /* the lining up is suboptimal.. */ static char trigraph[] = "=(/)\'<!>-"; extern char *fgets(),*strchr(); extern void movedown(); while(fgets(buf,100,fp)) { for(trip = triable; *trip; trip++) { while((p = strchr(buf,*trip))) { movedown(p,2); p[0] = p[1] = '?'; p[2] = trigraph[trip - triable]; } } fputs(buf,stdout); } return(0); } void movedown(s,count) char *s; int count; { int i; for(i = strlen(s); i >= 0; i--) s[i+count] = s[i]; } SHAR_EOF if test 2112 -ne "`wc -c < 'tri.c'`" then echo shar: error transmitting "'tri.c'" '(should have been 2112 characters)' fi fi # end of overwriting check if test -f 'untri.c' then echo shar: will not over-write existing file "'untri.c'" else cat << \SHAR_EOF > 'untri.c' /* * untri.c - convert trigraphs to the previously standard C character set. * * If you have index() instead of strchr(), compile with -Dstrchr=index. * * The #ifdef unix lines just provide better arg checking. * * Alan J Rosenthal <flaps@gpu.utcs.toronto.edu>, 2 June 1988. */ #include <stdio.h> #ifdef unix #include <sys/types.h> #include <sys/stat.h> #endif #define TRUE 1 #define FALSE 0 #define SUCCESS 0 #define FAILURE (-1) #define STREQ(s,t)(*(s) == *(t) && strcmp((s),(t)) == 0) char *progname; main(argc,argv) int argc; char **argv; { int status; FILE *in,*fopen(); #ifdef unix struct stat statbuf; #endif progname = argv[0]; status = 0; if(argc < 1) /* only some systems */ { fprintf(stderr,"usage: %s [file ...]\n",progname); exit(1); } else if(argc == 1) { status += process(stdin,"stdin"); } else { while(--argc > 0) { argv++; if(STREQ(*argv,"-")) { status += process(stdin,"-"); } else { if((in = fopen(*argv,"r"))) { #ifdef unix if(fstat(fileno(in),&statbuf) != 0) { /* shouldn't happen */ fprintf(stderr,"%s: can't fstat\n",*argv); exit(1); } if((statbuf.st_mode & S_IFMT) == S_IFDIR) { fprintf(stderr,"%s is a directory!\n",*argv); status++; } else { status += process(in,*argv); } #else status += process(in,*argv); #endif (void)fclose(in); } else { perror(*argv); } } } } exit(status); } /* process - process input file */ int process(fp,name) FILE *fp; char *name; { char buf[100],*p,*trip; static char trigraph[] = "=(/)\'<!>-"; /* the lining up is suboptimal.. */ static char untrichar[] = "#[\\]^{|}~"; extern char *fgets(),*strchr(); extern void moveup(); while(fgets(buf,100,fp)) { for(p = buf; p; p = strchr(p+1,'?')) { if(p[1] == '?' && (trip = strchr(trigraph,p[2]))) { moveup(p,2); *p = untrichar[trip - trigraph]; } } fputs(buf,stdout); } return(0); } /* * Using strcpy for moveup() is unportable due to the overlapping areas * problem, but basically it is a strcpy(s,s+count). */ void moveup(s,count) char *s; int count; { s += count; while(*s) { s[-count] = s[0]; s++; } s[-count] = '\0'; } SHAR_EOF if test 2278 -ne "`wc -c < 'untri.c'`" then echo shar: error transmitting "'untri.c'" '(should have been 2278 characters)' fi fi # end of overwriting check if test -f 'warnt.c' then echo shar: will not over-write existing file "'warnt.c'" else cat << \SHAR_EOF > 'warnt.c' /* * warnt.c - print warnings about trigraphs. * * If you have index() instead of strchr(), compile with -Dstrchr=index. * * The #ifdef unix lines just provide better arg checking. * * Alan J Rosenthal <flaps@gpu.utcs.toronto.edu>, 2 June 1988. */ #include <stdio.h> #ifdef unix #include <sys/types.h> #include <sys/stat.h> #endif #define TRUE 1 #define FALSE 0 #define SUCCESS 0 #define FAILURE (-1) #define STREQ(s,t)(*(s) == *(t) && strcmp((s),(t)) == 0) char *progname; main(argc,argv) int argc; char **argv; { int status; FILE *in,*fopen(); #ifdef unix struct stat statbuf; #endif progname = argv[0]; status = 0; if(argc < 1) /* only some systems */ { fprintf(stderr,"usage: %s [file ...]\n",progname); exit(1); } else if(argc == 1) { status += process(stdin,"stdin"); } else { while(--argc > 0) { argv++; if(STREQ(*argv,"-")) { status += process(stdin,"-"); } else { if((in = fopen(*argv,"r"))) { #ifdef unix if(fstat(fileno(in),&statbuf) != 0) { /* shouldn't happen */ fprintf(stderr,"%s: can't fstat\n",*argv); exit(1); } if((statbuf.st_mode & S_IFMT) == S_IFDIR) { fprintf(stderr,"%s is a directory!\n",*argv); status++; } else { status += process(in,*argv); } #else status += process(in,*argv); #endif (void)fclose(in); } else { perror(*argv); } } } } exit(status); } /* process - process input file */ int process(fp,name) FILE *fp; char *name; { int line; char buf[100],*p; extern char *fgets(),*strchr(); for(line = 1; fgets(buf,100,fp); line++) { for(p = buf; p; p = strchr(p+1,'?')) if(p[1] == '?' && strchr("=(/)\'<!>-",p[2])) printf("%s(%d) ??%c: %s",name,line,p[2],buf); } return(0); } SHAR_EOF if test 1809 -ne "`wc -c < 'warnt.c'`" then echo shar: error transmitting "'warnt.c'" '(should have been 1809 characters)' fi fi # end of overwriting check # End of shell archive exit 0