int HtmlCheck(int WriteOutput, FILE *InputFile, char *s, int sSize, char *CurrentFilename, int *CurrentLineAll, int *CurrentLineInFile) { static int StyleBox = 0, StyleBoxWidth = 75, StyleUser = 0; static char StyleUserStart[2049] = "", StyleUserEnd[1025] = ""; int Width, Pos = 0; int i, j; char c = 0, *ss; extern int inHeader; //if (WriteOutput) // printf("HTML -> %s", s); // Process default style file at startup. if (!StyleInitialized) { FILE *Defaults; StyleInitialized = 1; Defaults = fopen("Default.style", "r"); if (Defaults != NULL) { Line_t s = { 0 }; StyleOnly = 1; while (NULL != fgets(s, sizeof(s) - 1, Defaults)) HtmlCheck(0, Defaults, s, sizeof(s), "", &i, &j); StyleOnly = 0; fclose(Defaults); } } if (StyleOnly) goto ProcessStyle; Retry: Pos = 0; c = 0; // First, take care of directives to include HTML from a // file. There are two forms: // <HTML "filename"> // or // ### FILE="filename" if (!strncmp(s, "<HTML \"", 7)) Pos = 7; else if (!strncmp(s, "### FILE=\"", 10)) Pos = 10; if (Pos) { FILE *Include; if (!WriteOutput || !Html || HtmlOut == NULL) return (1); for (ss = &s[Pos]; *ss && *ss != '\"'; ss++) ; if (*ss != '\"') return (1); *ss = 0; Include = fopen(&s[Pos], "r"); *ss = '\"'; if (Include == NULL) return (1); fprintf(HtmlOut, "%s", HTML_STYLE_END); while (NULL != fgets(s, sSize - 1, Include)) fprintf(HtmlOut, "%s", s); fprintf(HtmlOut, "%s", HTML_STYLE_START); fclose(Include); return (1); } // Take care of the addition of destinations for hyperlinks. if (!strncmp(s, "### ANCHOR=", 11)) { if (!WriteOutput || !Html || HtmlOut == NULL) return (1); for (ss = s; *ss && *ss != '\n'; ss++) ; *ss = 0; fprintf(HtmlOut, "<a name=\"%s\">\n", &s[11]); return (1); } // Now take care of style pragmas. The allowed forms are // ### STYLE=NONE // or // ### STYLE=BOX n% // or // ### STYLE=START stuff // ### STYLE=START+ stuff // ### STYLE=END stuff // or // ### STYLE=USER // The latter just re-enables STYLE=START/STYLE=END styles which // may have been defined earlier but then disabled temporarily // with STYLE=NONE or STYLE=BOX. STYLE=START/STYLE=START+/STYLE=END // is a user-defined style, in which you can give // both the HTML to initiate the style and the HTML to end // the style to allow returning to the default style. In other // words, when a block of comments in "## htmlstuff" format // is encountered, the style-start stuff will be output, // followed by all of the htmlstuff in the ## comments, followed // by the style-end stuff. STYLE=START gives the starting commands, // but since such commands are sometimes gargantuan, they may not // fit conveniently on a single line, so what STYLE=START+ does is // to *add* stuff to the end of a previous STYLE=START or // STYLE=START+. if (!strncmp(s, "### STYLE=", 10)) { if (!WriteOutput || !Html || HtmlOut == NULL) return (1); ProcessStyle: ss = &s[10]; if (!strncmp(ss, "NONE", 4)) { StyleBox = 0; StyleUser = 0; } else if (!strncmp(ss, "BOX ", 4) && sscanf(ss + 4, "%d%c", &i, &c) == 2 && i >= 1 && i <= 100 && c == '%') { StyleBox = 1; StyleBoxWidth = i; StyleUser = 0; } else if (!strncmp(ss, "USER", 4)) { StyleBox = 0; StyleUser = 1; } else if (!strncmp(ss, "START ", 6)) { StyleBox = 0; StyleUser = 1; strcpy(StyleUserStart, &ss[6]); } else if (!strncmp(ss, "START+ ", 7)) { strcat(StyleUserStart, &ss[7]); } else if (!strncmp(ss, "END ", 4)) { StyleBox = 0; StyleUser = 1; strcpy(StyleUserEnd, &ss[4]); } return (1); } // Now take care of HTML embedded with // ## stuff // JL 2010-02-17 Don't try to process Page meta-comments. // RSB 2010-02-20 ... if --unpound-page is used. Otherwise, // process them normally. //if (WriteOutput) // printf("inHeader=%d match=%d UnpoundPage=%d\n", inHeader, strncmp(s + 3, "Page", 4), UnpoundPage); if ((!strncmp(s, "## ", 3) || !strncmp(s, "##\t", 3)) && !inHeader && (strncmp(s + 3, "Page", 4) != 0 || !UnpoundPage)) { //if (WriteOutput) // printf("HERE\n"); // Set proper style and output the line. if (WriteOutput && Html && HtmlOut != NULL) { fprintf(HtmlOut, "%s", HTML_STYLE_END); if (StyleBox) fprintf(HtmlOut, HTML_TABLE_START, StyleBoxWidth); else if (StyleUser) fprintf(HtmlOut, "%s", StyleUserStart); fprintf(HtmlOut, "%s", &s[3]); } // Loop on the lines of the insert. while (1) { ss = fgets(s, sSize - 1, InputFile); if (ss == NULL) break; (*CurrentLineAll)++; (*CurrentLineInFile)++; if (strncmp(s, "## ", 3) && strncmp(s, "##\t", 3)) break; if (WriteOutput && Html && HtmlOut != NULL) fprintf(HtmlOut, "%s", &s[3]); } // Restore default style. if (WriteOutput && Html && HtmlOut != NULL) { if (StyleBox) fprintf(HtmlOut, "%s", HTML_TABLE_END); else if (StyleUser) fprintf(HtmlOut, "%s", StyleUserEnd); fprintf(HtmlOut, "%s", HTML_STYLE_START); } if (ss == NULL) return (1); goto Retry; } // Now take care of the <HTML> or <HTMLnn> tags. However, // the ## style described above is preferred. if (!strncmp(s, "<HTML>", 6) || (2 == sscanf(s, "<HTML%d%c", &Width, &c) && Width > 0 && Width <= 99 && c == '>')) { // Turn off default HTML styling. if (WriteOutput && Html && HtmlOut != NULL) { fprintf(HtmlOut, "%s", HTML_STYLE_END); if (c == '>') fprintf(HtmlOut, HTML_TABLE_START, Width); } // Loop on the lines of the insert. while (1) { ss = fgets(s, sSize - 1, InputFile); if (ss == NULL) { printf("Premature end-of-file.\n"); fprintf(stderr, "%s:%d: Premature end-of-file.\n", CurrentFilename, *CurrentLineInFile); goto Done; } (*CurrentLineAll)++; (*CurrentLineInFile)++; if (!strncmp(s, "</HTML>", 7)) { Done: // Turn default HTML styling back on and return // to normal source processing. if (WriteOutput && Html && HtmlOut != NULL) { if (c == '>') fprintf(HtmlOut, "%s", HTML_TABLE_END); fprintf(HtmlOut, "%s", HTML_STYLE_START); } break; } if (WriteOutput && Html && HtmlOut != NULL) fprintf(HtmlOut, "%s", s); } return (1); } return (0); }
void SymbolPass (const char *InputFilename) { Line_t CurrentFilename; Line_t s; char *Comment, *Label, *FalseLabel, *Operator, *Operand, *Mod1, *Mod2; FILE *InputFile; int CurrentLineAll = 0, CurrentLineInFile = 0; int i; // dummies. char *ss; // dummies. // Open the input file. strcpy (CurrentFilename, InputFilename); InputFile = fopen (CurrentFilename, "r"); if (InputFile == NULL) goto Done; // Loop on the lines of the input file. s[sizeof (s) - 1] = 0; for (;;) { // Get the next line from the file. ss = fgets (s, sizeof (s) - 1, InputFile); // At end of the file? if (NULL == ss) { // We've reached the end of this input file. Need to switch // files (if we were within an include-file) or to end the pass. if (NumStackedIncludes) { fclose (InputFile); NumStackedIncludes--; InputFile = StackedIncludes[NumStackedIncludes].InputFile; strcpy (CurrentFilename, StackedIncludes[NumStackedIncludes].InputFilename); CurrentLineInFile = StackedIncludes[NumStackedIncludes].CurrentLineInFile; continue; } else { // All done! break; } } else { // No, not at end of file, so we've just read a new line. CurrentLineAll++; CurrentLineInFile++; } if (HtmlCheck (0, InputFile, s, sizeof (s), CurrentFilename, &CurrentLineAll, &CurrentLineInFile)) continue; // Analyze the input line. Is it an "include" directive? if (s[0] == '$') { // This is a directive to include another file. if (NumStackedIncludes == MAX_STACKED_INCLUDES) { printf ("Too many levels of include-files.\n"); goto Done; } StackedIncludes[NumStackedIncludes].InputFile = InputFile; strcpy (StackedIncludes[NumStackedIncludes].InputFilename, CurrentFilename); StackedIncludes[NumStackedIncludes].CurrentLineInFile = CurrentLineInFile; NumStackedIncludes++; if (1 != sscanf (s, "$%s", CurrentFilename)) { printf ("Include-directive has no filename.\n"); goto Done; } CurrentLineInFile = 0; InputFile = fopen (CurrentFilename, "r"); if (InputFile == NULL) { printf ("Include-file \"%s\" does not exist.\n", CurrentFilename); goto Done; } continue; } // Set up appropriate default values for various fields. Label = FalseLabel = Operator = Operand = Mod1 = Mod2 = ""; // Find and remove the comment field, if any. for (Comment = s; *Comment && *Comment != COMMENT_SEPARATOR; Comment++); if (*Comment == '#') { *Comment++ = 0; // Trim the newline at the end: for (ss = Comment; *ss; ss++) if (*ss == '\n') *ss = 0; } // Suck in all other fields. NumFields = sscanf (s, "%s%s%s%s%s%s", Fields[0], Fields[1], Fields[2], Fields[3], Fields[4], Fields[5]); if (NumFields >= 1) { i = 0; if (*s && !isspace (*s)) Label = Fields[i++]; else if (*Fields[0] == '+' || *Fields[0] == '-') FalseLabel = Fields[i++]; if (i < NumFields) Operator = Fields[i++]; if (i < NumFields) Operand = Fields[i++]; if (i < NumFields) Mod1 = Fields[i++]; if (i < NumFields) Mod2 = Fields[i++]; } if (*Label != 0 && strcmp(Operator, "MEMORY") && strcmp(Operator, "CHECK=")) { //if (!strcmp (Label, "ATMAGAD")) // printf ("***** %s, %d, %d, %s", CurrentFilename, CurrentLineAll, CurrentLineInFile, s); if (AddSymbol (Label)) { printf ("Out of memory (2).\n"); goto Done; } } } // Done with this pass. Done: if (InputFile != NULL) fclose (InputFile); for (i = 0; i < NumStackedIncludes; i++) fclose (StackedIncludes[i].InputFile); NumStackedIncludes = 0; }