X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Futils%2Funlit%2Funlit.c;h=52e64156a7a4a06ef35a0b6828c55bbc284b78fa;hb=ea7a05cd38ae85303e1b9efb2647c9658ea39c3c;hp=ff9c6781aa55213279306ddc7ee999fba8ebd109;hpb=e7d21ee4f8ac907665a7e170c71d59e13a01da09;p=ghc-hetmet.git diff --git a/ghc/utils/unlit/unlit.c b/ghc/utils/unlit/unlit.c index ff9c678..52e6415 100644 --- a/ghc/utils/unlit/unlit.c +++ b/ghc/utils/unlit/unlit.c @@ -41,16 +41,19 @@ */ #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 CANNOTOPEN "unlit: cannot open \"%s\"\n" -#define DISTINCTNAMES "unlit: input and output filenames must differ\n" -#define MISSINGCODE "unlit: missing %s\n" +#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 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" #define BEGINCODE "\\begin{code}" #define LENBEGINCODE 12 @@ -58,13 +61,14 @@ #define LENENDCODE 10 #ifdef PSEUDOCODE /* According to Will Partain, the inventor of pseudocode, this gone now. */ +#define MISSINGENDPSEUDOCODE "unlit: missing \\end{pseudocode}\n" #define BEGINPSEUDOCODE "\\begin{pseudocode}" #define LENBEGINPSEUDOCODE 18 #define ENDPSEUDOCODE "\\end{pseudocode}" #define LENENDPSEUDOCODE 16 #endif -typedef enum { START, BLANK, TEXT, DEFN, BEGIN, /*PSEUDO,*/ END, HASH } line; +typedef enum { START, BLANK, TEXT, DEFN, BEGIN, /*PSEUDO,*/ END, HASH, SHEBANG } line; #define isWhitespace(c) (c==' ' || c=='\t') #define isLineTerm(c) (c=='\n' || c==EOF) @@ -72,6 +76,11 @@ 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 char* prefix_str = NULL; /* Prefix output with a string */ + +static char *ofilename = NULL; /* complain(file,line,what) * @@ -91,6 +100,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 */ @@ -146,31 +173,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); @@ -228,12 +268,12 @@ FILE *ostream; { char lineb[1000]; for(;;) { if (fgets(lineb, sizeof lineb, istream) == NULL) { - fprintf(stderr, MISSINGCODE, ENDCODE); + complain(file, linesread, MISSINGENDCODE); exit(1); } linesread++; if (strncmp(lineb,ENDCODE,LENENDCODE) == 0) { - putc('\n', ostream); + myputc('\n', ostream); break; } fputs(lineb, ostream); @@ -245,11 +285,11 @@ FILE *ostream; { char lineb[1000]; for(;;) { if (fgets(lineb, sizeof lineb, istream) == NULL) { - fprintf(stderr, MISSINGCODE, ENDPSEUDOCODE); + complain(file, linesread, MISSINGENDPSEUDOCODE); exit(1); } linesread++; - putc('\n', ostream); + myputc('\n', ostream); if (strncmp(lineb,ENDPSEUDOCODE,LENENDPSEUDOCODE) == 0) { break; } @@ -266,7 +306,8 @@ 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. * 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 @@ -286,6 +327,17 @@ char **argv; { noisy = 0; else if (strcmp(*argv,"-c")==0) crunchnl = 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; @@ -310,6 +362,7 @@ char **argv; { exit(1); } + ofilename=argv[1]; if (strcmp(argv[1], "-")==0) ostream = stdout; else @@ -318,10 +371,26 @@ char **argv; { exit(1); } + /* Prefix the output with line pragmas */ + if (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, 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); }