X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Futils%2Funlit%2Funlit.c;h=7ab293220cc549a8a2d9748f9b2f4fa16d323790;hb=027587234cb35e5c9d9ace090c2fe8d1d8df93f4;hp=4212907d9077e1c23cd8fceba6c370969278c9d8;hpb=9e5c5b07fc8f957adfa507955e5c40069cabc5c3;p=ghc-hetmet.git diff --git a/ghc/utils/unlit/unlit.c b/ghc/utils/unlit/unlit.c index 4212907..7ab2932 100644 --- a/ghc/utils/unlit/unlit.c +++ b/ghc/utils/unlit/unlit.c @@ -41,14 +41,17 @@ */ #include +#include #include #define NULLSTR ((char *)0) #define DEFNCHAR '>' #define MISSINGBLANK "unlit: Program line next to comment" #define EMPTYSCRIPT "unlit: No definitions in file (perhaps you forgot the '>'s?)" -#define USAGE "usage: unlit [-q] [-n] [-c] file1 file2\n" +#define USAGE "usage: unlit [-q] [-n] [-c] [-#] [-P] [-h label] file1 file2\n" #define CANNOTOPEN "unlit: cannot open \"%s\"\n" +#define CANNOTWRITE "unlit: error writing \"%s\"\n" +#define CANNOTWRITESTDOUT "unlit: error writing standard output\n" #define DISTINCTNAMES "unlit: input and output filenames must differ\n" #define MISSINGENDCODE "unlit: missing \\end{code}\n" @@ -65,14 +68,20 @@ #define LENENDPSEUDOCODE 16 #endif -typedef enum { START, BLANK, TEXT, DEFN, BEGIN, /*PSEUDO,*/ END, HASH } line; -#define isWhitespace(c) (c==' ' || c=='\t') +typedef enum { START, BLANK, TEXT, DEFN, BEGIN, /*PSEUDO,*/ END, HASH, SHEBANG } line; +#define isWhitespace(c) (c==' ' || c=='\t' || c=='\r') #define isLineTerm(c) (c=='\n' || c==EOF) static int noisy = 1; /* 0 => keep quiet about errors, 1 => report errors */ static int errors = 0; /* count the number of errors reported */ static int crunchnl = 0; /* don't print \n for removed lines */ static int leavecpp = 1; /* leave preprocessor lines */ +static int ignore_shebang = 1; /* Leave out shebang (#!) lines */ +static int no_line_pragma = 0; /* Leave out initial line pragma */ + +static char* prefix_str = NULL; /* Prefix output with a string */ + +static char *ofilename = NULL; /* complain(file,line,what) * @@ -92,6 +101,24 @@ int lin; { } } +writeerror() +{ + if (!strcmp(ofilename,"-")) { + fprintf(stderr, CANNOTWRITESTDOUT); + } else { + fprintf(stderr, CANNOTWRITE, ofilename); + } + exit(1); +} + +myputc(c, ostream) +char c; +FILE *ostream; { + if (putc(c,ostream) == EOF) { + writeerror(); + } +} + #define TABPOS 8 /* As getc, but does TAB expansion */ @@ -147,31 +174,44 @@ FILE *istream; line readline(istream,ostream) FILE *istream, *ostream; { - int c = egetc(istream); + int c, c1; char buf[100]; int i; + c = egetc(istream); + if (c==EOF) return END; - - if (leavecpp && c=='#') { - putc(c, ostream); + + if ( c == '#' ) { + if ( ignore_shebang ) { + c1 = egetc(istream); + if ( c1 == '!' ) { + while (c=egetc(istream), !isLineTerm(c)) ; + return SHEBANG; + } + myputc(c, ostream); + c=c1; + } + if ( leavecpp ) { + myputc(c, ostream); while (c=egetc(istream), !isLineTerm(c)) - putc(c,ostream); - putc('\n',ostream); + myputc(c,ostream); + myputc('\n',ostream); return HASH; + } } if (c==DEFNCHAR) { -/* putc(' ',ostream);*/ +/* myputc(' ',ostream);*/ while (c=egetc(istream), !isLineTerm(c)) - putc(c,ostream); - putc('\n',ostream); + myputc(c,ostream); + myputc('\n',ostream); return DEFN; } if (!crunchnl) - putc('\n',ostream); + myputc('\n',ostream); while (isWhitespace(c)) c=egetc(istream); @@ -234,7 +274,7 @@ FILE *ostream; { } linesread++; if (strncmp(lineb,ENDCODE,LENENDCODE) == 0) { - putc('\n', ostream); + myputc('\n', ostream); break; } fputs(lineb, ostream); @@ -250,7 +290,7 @@ FILE *ostream; { exit(1); } linesread++; - putc('\n', ostream); + myputc('\n', ostream); if (strncmp(lineb,ENDPSEUDOCODE,LENENDPSEUDOCODE) == 0) { break; } @@ -267,7 +307,9 @@ FILE *ostream; { * * Main program. Processes command line arguments, looking for leading: * -q quiet mode - do not complain about bad literate script files - * -n noisy mpde - complain about bad literate script files. + * -n noisy mode - complain about bad literate script files. + * -r remove cpp droppings in output. + * -P don't output any CPP line pragmas. * Expects two additional arguments, a file name for the input and a file * name for the output file. These two names must normally be distinct. * An exception is made for the special name "-" which can be used in either @@ -287,6 +329,19 @@ char **argv; { noisy = 0; else if (strcmp(*argv,"-c")==0) crunchnl = 1; + else if (strcmp(*argv,"-P")==0) + no_line_pragma = 1; + else if (strcmp(*argv,"-h")==0) { + if (argc > 1) { + argc--; argv++; + if (prefix_str) + free(prefix_str); + prefix_str = (char*)malloc(sizeof(char)*(1+strlen(*argv))); + if (prefix_str) + strcpy(prefix_str, *argv); + } + } else if (strcmp(*argv,"-#")==0) + ignore_shebang = 0; else break; @@ -311,6 +366,7 @@ char **argv; { exit(1); } + ofilename=argv[1]; if (strcmp(argv[1], "-")==0) ostream = stdout; else @@ -319,10 +375,26 @@ char **argv; { exit(1); } + /* Prefix the output with line pragmas */ + if (!no_line_pragma && prefix_str) { + /* Both GHC and CPP understand the #line pragma. + * We used to throw in both a #line and a {-# LINE #-} pragma + * here, but CPP doesn't understand {-# LINE #-} so it thought + * the line numbers were off by one. We could put the {-# LINE + * #-} before the #line, but there's no point since GHC + * understands #line anyhow. --SDM 8/2003 + */ + fprintf(ostream, "#line 1 \"%s\"\n", prefix_str); + } + unlit(file, istream, ostream); - fclose(istream); - fclose(ostream); + if (istream != stdin) fclose(istream); + if (ostream != stdout) { + if (fclose(ostream) == EOF) { + writeerror(); + } + } exit(errors==0 ? 0 : 1); }