Mercurial > ~dholland > hg > ag > index.cgi
view help2html/mhh6.syn @ 14:a02e9434072e
Fix friend declaration for gcc10.
XXX: did not check it against the IBM compiler, might end up needing
XXX: to be conditional.
author | David A. Holland |
---|---|
date | Tue, 31 May 2022 00:59:42 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/* * October 30, 2007. mhh6: use C, not C++. * * Sept 5, 2006. mhh5.syn modified for XML_OUTPUT option. * * June 20, 2001. mhh5.syn * Modifying mhh4 to create HTML output * (mhh4 sorts a help.src file case-insensitively by title line while * cleaning it up a bit.) * * June 16 2001 * Unlike mhh3b, mhh4 stores and sorts title *lines*, not titles, * from help.src. Another AgStringDirectory has been added to hold * topic bodies. * * Change mhh3b.syn to store title lines in string dicts. * Change mhh3a.syn to use AgStringDictionary for titles. * Jun 8/01 Change mhh3.syn to add main and some reduc. procedures * * June 8, 2001 - mhh3.syn now parses Jerry's current help.src (b8) * with no conflicts or keyword anomalies but spaces (and tabs) are * not allowed in blank lines. Why the eof line tolerates spaces is * something of a mystery. */ // -- CONFIGURATION SECTION ---------------------------- [ pointer input no cr // no carr. ret. in output parser parser file name = "#.c" line numbers ] //------------------------------------------------------ eof = 0 char = ~eof lead title char = char - blank - tab - ',' - bullet - '\n' - '\r' title char = char - ',' - bullet - '\n' - '\r' lead topic char = char - blank - tab - bullet - '\n' - '\r' text char = char - bullet - '\n' - '\r' table char = char - tab - '\n' - '\r' blank = 0x20 tab = 9 bullet = 7 //blank line // -> blank?..., '\n' blank line -> '\n' /* Don't allow spaces in line */ -> '\r','\n' eof line -> blank?..., eof eol -> '\n' -> '\r','\n' (void) help sourcefile $ // ** Grammar token ** -> topic..., blank line?, eof line topic -> blank line?..., title line, eol, blank line?..., topic lines, end topic title line -> title line too = { title_line_count++; // buffer_append(&titleLine, "</h3>\n<p>"); saveTitleLine(); } title line too -> title = title_count++, putTitle(); -> title line too, ',', blank?..., title = title_count++, appendTitle(); title -> lead title char:c = buffer_start(&title, c), buffer_start(&title1, toupper(c)); -> title, title char:c = buffer_add(&title, c), buffer_add(&title1, toupper(c)); end topic -> "##", blank?..., eol -> "\n##", blank?..., eol -> "\r\n##", blank?..., eol topic lines -> topic lines too = { saveTopicBody(); } topic lines too -> text parag =buffer_append(&topicBody,"\n"); -> topic lines too, blank line..., parag=buffer_append(&topicBody,"\n"); parag -> text parag -> table parag -> list1 parag = finishList(Tlist1); -> list2 parag = finishList(Tlist2); -> listtab parag = finishList(Tlisttab); -> code parag text parag -> partial text parag -> partial text parag, table parag -> text block, list1 parag = finishList(Tlist1); -> text block, listtab parag = finishList(Tlisttab); -> text block, code parag -> text block, code parag, text block partial text parag -> text block -> partial text parag, table parag, text block text block -> !buffer_append(&topicBody, "<p>");, first text line, other text line?... = buffer_append(&topicBody, "</p>"); table parag -> table parag too = buffer_append(&topicBody, "\n</table>\n\n"); table parag too -> first table line -> table parag too, other table line list1 parag -> list1 block, list1 block?... list1 block -> first list1 line, other list1 line?... = buffer_append(&topicBody, "</li>\n"); -> first list1 line, other list1 line?..., table parag = buffer_append(&topicBody, "</li>\n"); -> first list1 line, other list1 line?..., code parag = buffer_append(&topicBody, "</li>\n"); list2 parag -> first list2 line, other list2 line?... = buffer_append(&topicBody, "</li>\n"); listtab parag -> listtab block, listtab block?... listtab block -> first listtab line, other listtab line?... = buffer_append(&topicBody, "</li>\n"); -> first listtab line, other listtab line?..., table parag = buffer_append(&topicBody, "</li>\n"); code parag -> code parag too = buffer_append(&topicBody, "\n</pre>"); code parag too -> first code line -> code parag too, other code line first text line -> lead topic char:c, text frag?, eol = { total1sttextline++; appendEnd(c); } -> blank, lead topic char:c, text frag?,eol = { total1sttextlineb++; buffer_add(&topicBody, 0x20); appendEnd(c); } other text line -> lead topic char:c, text frag?, eol = appendEnd(c); //################# OLD #################################################### //first table line // -> tab seq, blank seq?, lead topic char:c, text frag?, '\n' = { // total1sttableline++; // buffer_append(&topicBody, "\n<pre> "); // appendEnd(c); // buffer_clear(&tabFrag); // buffer_clear(&blankFrag); // } // //other table line // -> tab seq, blank seq?, lead topic char:c, text frag?, '\n' = { // buffer_append(&topicBody, " "); // appendEnd(c); // buffer_clear(&tabFrag); // buffer_clear(&blankFrag); // } //############################################################################ first table line -> first table line body, eol = buffer_append(&topicBody, "</td></tr>"); first table line body -> tab seq, blank seq?, lead topic char:c, table frag? = { total1sttableline++; buffer_append(&topicBody, "\n\n<table cellpadding=\"7\" cellspacing=\"2\" >\n<tr><td> "); appendTableCell(c); buffer_clear(&tabFrag); buffer_clear(&blankFrag); } -> first table line body, tab seq, blank seq?, lead topic char:c, table frag? = { buffer_append(&topicBody, "</td>\n<td> "); appendTableCell(c); buffer_clear(&tabFrag); buffer_clear(&blankFrag); } other table line -> other table line body, eol = buffer_append(&topicBody, "</td></tr>"); other table line body -> tab seq, blank seq?, lead topic char:c, table frag? = { buffer_append(&topicBody, "\n\n<tr><td> "); appendTableCell(c); buffer_clear(&tabFrag); buffer_clear(&blankFrag); } -> other table line body, tab seq, blank seq?, lead topic char:c, table frag? = { buffer_append(&topicBody, "</td>\n<td> "); appendTableCell(c); buffer_clear(&tabFrag); buffer_clear(&blankFrag); } first list1 line -> bullet, blank, lead topic char:c, text frag?, eol = { total1stlist1line++; if (intstack_top(¶gType) != Tlist1) { intstack_push(¶gType, Tlist1); buffer_append(&topicBody, "\n<ul>"); } buffer_append(&topicBody, "\n<li>"); buffer_add(&topicBody, 0x20); appendEnd(c); } other list1 line -> lead topic char:c, text frag?, eol = appendEnd(c); first list2 line -> bullet, blank, blank, lead topic char:c, text frag?, eol = { total1stlist2line++; if (intstack_top(¶gType) != Tlist2) { intstack_push(¶gType, Tlist2); buffer_append(&topicBody, "\n<ul>"); } buffer_append(&topicBody, "\n<li>"); buffer_append(&topicBody, " "); appendEnd(c); } other list2 line -> lead topic char:c, text frag?, eol = appendEnd(c); first listtab line -> bullet, tab:t, lead topic char:c, text frag?, eol = { total1stlisttabline++; if (intstack_top(¶gType) != Tlisttab) { intstack_push(¶gType, Tlisttab); buffer_append(&topicBody, "\n<ul>"); } buffer_append(&topicBody, "\n<li>"); buffer_add(&topicBody, t); appendEnd(c); } other listtab line -> lead topic char:c, text frag?, eol = appendEnd(c); first code line -> " ", lead topic char:c, text frag?, eol = { total1stcodeline++; buffer_append(&topicBody, "\n<pre> "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { total1stcodeline++; buffer_append(&topicBody, "\n<pre> "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { total1stcodeline++; buffer_append(&topicBody, "\n<pre> "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { total1stcodeline++; buffer_append(&topicBody, "\n<pre> "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { total1stcodeline++; buffer_append(&topicBody, "\n<pre> "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { total1stcodeline++; buffer_append(&topicBody, "\n<pre> "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { total1stcodeline++; buffer_append(&topicBody, "\n<pre> "); appendEnd(c); } other code line -> " ", lead topic char:c, text frag?, eol = { buffer_append(&topicBody, " "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { buffer_append(&topicBody, " "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { buffer_append(&topicBody, " "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { buffer_append(&topicBody, " "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { buffer_append(&topicBody, " "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { buffer_append(&topicBody, " "); appendEnd(c); } -> " ", lead topic char:c, text frag?, eol = { buffer_append(&topicBody, " "); appendEnd(c); } text frag -> text char:c = buffer_start(&topicFrag, c); -> text frag, text char:c = buffer_add(&topicFrag, c); table frag -> table char:c = buffer_start(&topicFrag, c); -> table frag, table char:c = buffer_add(&topicFrag, c); tab seq -> tab:t = buffer_start(&tabFrag, t); -> tab seq, tab:t = buffer_add(&tabFrag, t); blank seq -> blank = buffer_start(&blankFrag, 0x20); -> blank seq, blank = buffer_add(&blankFrag, 0x20); { /* ----- Embedded C --------------------------------------------*/ #include <stdio.h> #include <string.h> #include <malloc.h> #include <assert.h> #include <ctype.h> #include <assert.h> #include <err.h> #include "uintarray.h" #include "support.h" #include "buffer.h" #include "stringdict.h" #include "must.h" int verbose = 0; int total1sttextline = 0; int total1sttextlineb = 0; int total1sttableline = 0; int total1stlist1line = 0; int total1stlist2line = 0; int total1stlisttabline = 0; int total1stcodeline = 0; int title_count =0; int title_line_count = 0; char *helpentStr; struct buffer title; struct buffer title1; struct buffer titleLine; struct buffer titleLine1; struct stringdict *titleDict; struct stringdict *titleDict1; // upper case struct stringdict *titleLineDict; struct stringdict *titleLineDict1; // upper case struct buffer topicFrag; struct buffer tabFrag; struct buffer blankFrag; struct buffer topicBody; struct stringdict *topicBodyDict; struct uintarray titleToTitleLine; struct intstack paragType; enum paragTypes {Tnone=0, Ttext=1, Ttable=2, Tlist1=3, Tlist2=4, Tlisttab=5, Tcode=6}; char *charToEntity(const char *instring); void putTitle(void); void appendTitle(void); void saveTitleLine(void); void appendEnd(int c); void removeFinalNewline(void); void saveTopicBody(void); void printDict(const struct stringdict *dictionary); void writeSortedHtml(FILE *output); void writeFullTopics(FILE *output, const struct stringdict *dictionary, const struct stringdict *dictionary1, const struct stringdict *dictionaryb); void writeTitles(FILE *output, const struct stringdict *dictionary, const struct stringdict *dictionary1); int processLinkString(FILE *filein, FILE *fileout); // replace &, <, > in S with entities char *charToEntity(const char *s) { char *ret; int i, j, len=0; for (i=0; s[i]; i++) { if (s[i] == '&') len += 5; /* & */ else if (s[i] == '<') len += 4; /* < */ else if (s[i] == '>') len += 4; /* > */ else len++; } ret = malloc(len+1); if (!ret) { errx(1, "Out of memory"); } for (i=j=0; s[i]; i++) { if (s[i] == '&') { strcpy(ret+j, "&"); j += 5; } else if (s[i] == '<' ) { strcpy(ret+j, "<"); j += 4; } else if (s[i] == '>' ) { strcpy(ret+j, ">"); j += 4; } else ret[j++] = s[i]; } ret[j] = 0; return ret; } // Save title both ways, make map entry for title<--->title line void saveTitle(void) { if (stringdict_exists(titleDict, title.text)) { fprintf( stderr, "Warning: Repeated title %s\n", title.text ); } #if 0 else if (!strcmp(title.text, "Secret of Life")) { // Do not save "Secret of Life" title return; } #endif else { // Save title in dictionary unsigned titleIndex = stringdict_intern(titleDict, title.text); // Save title in upper case dictionary stringdict_intern(titleDict1, title1.text); // count() should give next index unsigned titleLineIndex = stringdict_count(titleLineDict); // use an array for this (the keys are array indexes anyway) if (titleIndex >= uintarray_num(&titleToTitleLine)) { unsigned x, old = uintarray_num(&titleToTitleLine); uintarray_setsize(&titleToTitleLine, titleIndex+1); for (x=old; x<titleIndex; x++) { uintarray_set(&titleToTitleLine, x, (unsigned) -1); } } // Store indices in map uintarray_set(&titleToTitleLine, titleIndex, titleLineIndex); } } void putTitle(void) { // Save title itself in both reg. and upper case title dicts saveTitle(); buffer_append(&titleLine, title.text); buffer_append(&titleLine1, title1.text); } void appendTitle() { // Save title itself in both reg. and upper case title dicts saveTitle(); buffer_append(&titleLine, ", "); buffer_append(&titleLine1, ", "); buffer_append(&titleLine, title.text); buffer_append(&titleLine1, title1.text); } void saveTitleLine() { #if 0 static int foundSoL=0; if (stringdict_count(titleLineDict)==0 && strcmp(titleLine.text, "Secret of Life")!=0 && foundSoL==0) { fprintf(stderr, "Warning: Secret of Life does not lead file!\n"); } #endif #if 0 if (!strcmp(titleLine.text, "Secret of Life")) { // Don't save title line in dicts. // Should be at beginning of help file assert(stringdict_count(titleLineDict)==0); foundSoL = 1; if (verbose) { printf( "\n Found Secret of Life!\n\n" ); } } else #endif if ( stringdict_exists(titleLineDict, titleLine.text) ) { fprintf( stderr, "Warning: Repeated title line %s\n", titleLine.text ); } else { // Save title line in dictionary stringdict_intern(titleLineDict, titleLine.text); // Save title line in upper case dictionary stringdict_intern(titleLineDict1, titleLine1.text); } buffer_clear(&titleLine); buffer_clear(&titleLine1); } // Append the latter part of the line void appendEnd(int c) { buffer_add(&topicBody, c); buffer_append(&topicBody, topicFrag.text); buffer_append(&topicBody, "\n" ); buffer_clear(&topicFrag); } // Append a cell to the table row void appendTableCell(int c) { // Could insert <pre> </pre> or <code> </code> tags here for cell buffer_append(&topicBody, "<code> " ); buffer_add(&topicBody, c); buffer_append(&topicBody, topicFrag.text); buffer_append(&topicBody, "</code>" ); //buffer_append(&topicBody, "\n" ); buffer_clear(&topicFrag); } void removeFinalNewline(void) { int x = topicBody.len; assert(topicBody.text[x-2]=='\n' && topicBody.text[x-1]=='\n'); topicBody.text[x-1] = 0; } void saveTopicBody(void) { #if 0 // do not save Secret of Life topic body if (stringdict_count(titleLineDict) != 0) { #endif // save topic body stringdict_intern(topicBodyDict, topicBody.text); #if 0 } #endif buffer_clear(&topicBody); } /* void startTable(void) { // If we don't currently have table, start a new one if (paragType.top() != Ttable) { // Start table paragType.push( Ttable ); } } */ void finishList(int listtype){ //printf( "\nfinishList() - top type = %d, listtype = %d, " // "stack size = %d\n" // " titleLineDict size = %d\n", // paragType.top(), listtype, paragType.size(), // titleLineDict.size() ); assert(intstack_top(¶gType) == listtype); intstack_pop(¶gType); buffer_append(&topicBody, "\n</ul>"); } void printDict(const struct stringdict *dictionary) { unsigned i; for (i=0; i<stringdict_count(dictionary); i++) { printf("%4d: %s\n", i, stringdict_getbynum(dictionary, i)); } } char *SqueezeWS(const char *Input) { /* return a (strdup()-like) copy of Input, with whitespace squeezed out */ char *copy; int cnt, outcnt; copy = must_malloc(strlen(Input)+1); for (cnt=0, outcnt=0; Input[cnt]; cnt++) { unsigned char ch = Input[cnt]; if (!isspace(ch)) { copy[outcnt]=ch; outcnt++; } } copy[outcnt]=0; return copy; } void writeFullTopics(FILE *output, const struct stringdict *dictionary, /* title lines */ const struct stringdict *dictionary1, /* UC titlelines*/ const struct stringdict *dictionaryb) /* topic bodies */ { unsigned i; #if 0 /* Write "Secret of Life" topic at beginning of topics */ //fprintf(output, "Secret of Life>\n\n"); //fprintf(output, "No help message for this topic.\n##\n"); #endif assert( stringdict_count(dictionary) == stringdict_count(dictionary1) ); struct permutation *perm = mySort(dictionary1); // Sort dictionary1 /* Write out topics in a definition list <dl> */ fprintf( output, "\n\n<dl>\n\n" ); // write dictionary, sorted according to dict1 for (i = 0; i < stringdict_count(dictionary); i++) { //fprintf(output, "<dt><b><a name=\"%04d\">%s</a></b></dt>\n" // "<dd>%s\n</dd><br/>\n\n", // perm->v[i], // stringdict_getbynum(dictionary, perm->v[i]), // stringdict_getbynum(dictionaryb, perm->v[i]) ); char *anchorname=SqueezeWS(stringdict_getbynum(dictionary, perm->v[i])); fprintf(output, "<dt><b><a name=\"%s\">%s</a></b></dt>\n" "<dd>%s\n</dd>\n\n", anchorname, stringdict_getbynum(dictionary, perm->v[i]), stringdict_getbynum(dictionaryb, perm->v[i]) ); free(anchorname); } fprintf( output, "\n\n</dl>\n\n" ); permutation_destroy(perm); } void writeTitles(FILE *output, const struct stringdict *dictionary, /* titles */ const struct stringdict *dictionary1) /* uppercase titles */ { assert( stringdict_count(dictionary) == stringdict_count(dictionary1) ); struct permutation *perm = mySort(dictionary1); // Sort dictionary1 /* Write 2-column table of titles */ /* // n_t is true title count w/o Secret of Life int n_t = stringdict_count(dictionary); // we better have some titles assert( n_t >= 2 ); // n_t1 is #titles in 1st column int n_t1 = n_t%2 ? n_t/2 +1 : n_t/2; // n_t2 is #titles in 2nd column int n_t2 = n_t%2; int i; fprintf( output, "\n\n<table width=\"100%%\" " "style=\"margin-left: auto ; margin-right: auto\" \n" " cellpadding=\"15\" cellspacing=\"5\" >\n" "<tr align=\"left\">\n" "<td valign=\"top\" style=\"white-space: nowrap\">" "\n\n\n"); // Write out dictionary sorted acc. to dictionary1 // write out the first half, sorted for (i = 0; i < n_t1; i++) { fprintf(output, " \xA9%s\xAA\n<br/>", stringdict_getbynum(dictionary, perm->v[i])); } fprintf(output, "</td>\n\n"); fprintf(output, "<td valign=\"top\" style=\"white-space: nowrap\">\n\n"); // write out the last half, sorted for ( i = n_t1; i < n_t; i++) { fprintf(output, " \xA9%s\xAA\n<br/>", stringdict_getbynum(dictionary, perm->v[i])); } fprintf(output, "</td>\n</tr>\n</table>\n\n<hr><br/><br/>\n\n" ); */ /* Write 1-column list of titles */ // n_t is true title count w/o Secret of Life unsigned n_t = stringdict_count(dictionary); // we better have some titles assert( n_t >= 2 ); unsigned i; fprintf(output, "<h2>Help Topic Index</h2>\n\n" ); // Write out the index, sorted acc. to dictionary1 for (i = 0; i < n_t; i++) { fprintf(output, "\xA9%s\xAA\n<br/>", stringdict_getbynum(dictionary, perm->v[i])); } } void writeSortedHtml( FILE *output ) { /* Leading HTML */ #ifdef XML_OUTPUT fprintf(output, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" "<?xml-stylesheet type=\"text/xsl\" href=\"../ag_web.xml\"?>\n" "\n" "<body rootdir=\"..\" navname=\"Documentation: AnaGram Help\">\n"); #else fprintf(output, "<html>\n<head>\n"); fprintf(output, "<title>AnaGram Help Topics - HTML version</title>\n"); fprintf(output, "</head>\n\n\n"); fprintf(output, "<body bgcolor=\"#ffffff\" text=\"#000000\""); fprintf(output, " link=\"#0033CC\" vlink=\"#CC0033\" alink=\"#CC0099\">"); fprintf(output, "\n\n\n"); #endif /* Write page title */ #ifdef XML_OUTPUT fprintf(output, "<h1>AnaGram Help</h1>\n\n"); #else fprintf(output, "<hr><h2>AnaGram Help Topics - HTML Version</h2><hr>\n\n"); #endif /* Write 2-column table of titles */ writeTitles( output, titleDict, titleDict1 ); /* Write full topics in single- column table */ //fprintf( output, "\n\n<table width=\"100%%\">\n<tr><td>\n<p>\n\n"); //writeFullTopics( output, titleLineDict, titleLineDict1, topicBodyDict ); //fprintf( output, "</td></tr>\n</table>\n" ); /* Write full topics directly to the output page */ writeFullTopics( output, titleLineDict, titleLineDict1, topicBodyDict ); #ifdef XML_OUTPUT fprintf(output,"\n</body>\n"); #else /* Ending HTML */ fprintf( output, "\n<p><br/><address><a " "NAME=\"copyright\">AnaGram Help Topics, HTML version.</a>\n" "<br> Copyright © Parsifal Software, 2001.<br>\n" "All Rights Reserved.</address>" "\n\n</body>\n</html>\n\n" ); #endif } int processLinkString( FILE *filein, FILE *fileout ) { struct buffer linkString; // lower case struct buffer linkString1; // upper case version unsigned index; int c; int wspaceFlag =0; buffer_init(&linkString); buffer_init(&linkString1); while ( (c=fgetc(filein)) != EOF ) { if ( c != 0xAA) { // test for end of link char if ( c == 0x20 || c == 0x0D || c == 0x0A ) { // don't append these chars wspaceFlag = 1; } else { if (wspaceFlag) { // Replace space, cr, lf with single space buffer_add(&linkString, 0x20); buffer_add(&linkString1, toupper(0x20)); } buffer_add(&linkString, c); buffer_add(&linkString1, toupper(c)); wspaceFlag = 0; } } else { // end of link - look up using upper case string if (!stringdict_exists(titleDict1, linkString1.text)) { // try match w/o final S if ( linkString1.text[linkString1.len - 1] == 'S' ) { linkString1.text[linkString1.len - 1] = 0; if (stringdict_exists(titleDict1, linkString1.text)) { goto matched; // Eccch - a goto! } } fprintf(stderr, "Can't find this link in titleDict1: %s\n", linkString1.text); return 21; } /* find corresp. index in title line direc. */ matched: index = stringdict_findbyname(titleDict1, linkString1.text); unsigned ilink = uintarray_get(&titleToTitleLine, index); assert(ilink != (unsigned) -1); // Write out string, linked to title line char *linkname=SqueezeWS(stringdict_getbynum(titleLineDict, ilink)); //fprintf(fileout, "<a href=\"#%04d\">%s</a>", ilink, linkString.text); fprintf( fileout, "<a href=\"#%s\">%s</a>", linkname, linkString.text); free(linkname); buffer_cleanup(&linkString); buffer_cleanup(&linkString1); return 0; // normal return - have found and written link } } // Error - unexpected end of file fprintf(stderr, "Error: EOF detected while searching for end of link.\n"); fprintf(stderr, " Current link string is: %s\n", linkString.text ); return 23; } static void init(void) { buffer_init(&title); buffer_init(&title1); buffer_init(&titleLine); buffer_init(&titleLine1); titleDict = stringdict_create(); titleDict1 = stringdict_create(); titleLineDict = stringdict_create(); titleLineDict1 = stringdict_create(); topicBodyDict = stringdict_create(); buffer_init(&topicFrag); buffer_init(&tabFrag); buffer_init(&blankFrag); buffer_init(&topicBody); intstack_init(¶gType); uintarray_init(&titleToTitleLine); } /* -- Main Program -- */ int main(int argc, char *argv[]) { FILE *input; long fileLength; size_t stringLength; char *helpsrcString; init(); if (verbose) { printf( "\n This program reads a help.src-type file, " "replaces &, <, > with entities,\n" "sorts in a case-insensitive manner and writes " "to output file as HTML\n" "with a preceding list of the help topics. \n\n" ); } /* Check for enough arguments */ if (argc != 3) { fprintf(stderr, "Usage: mhh6 helpdata.src help.html\n"); return 1; } /* Open input file */ input = fopen(argv[1],"r"); if (input == NULL) { fprintf(stderr, "Cannot open %s\n", argv[1]); return 2; } /* find out how big the input file is */ if (fseek(input, SEEK_SET, SEEK_END)) { fprintf(stderr, "Strange problems with %s\n", argv[1]); return 3; } fileLength = ftell(input); if (fileLength < 0 ) { // -1L is error return fprintf(stderr, "Error getting file length (%ld) of %s\n", fileLength, argv[1]); return 4; } /* fseek to beginning of file */ if (fseek(input, 0, SEEK_SET)) { fprintf(stderr, "Strange problems with %s\n", argv[1]); return 5; } /* Allocate storage for input string */ helpsrcString = must_malloc(fileLength + 1); /* read file */ stringLength = fread(helpsrcString, 1, (unsigned)fileLength, input); if (stringLength == 0) { fprintf(stderr, "Unable to read %s\n", argv[1]); free(helpsrcString); fclose(input); return 7; } // Terminate string with null helpsrcString[stringLength] = 0; /* first, replace < > & with entities */ helpentStr = charToEntity( helpsrcString ); /* no more need for input string or file */ free(helpsrcString); fclose(input); /* initialize stack of parag types */ intstack_push(¶gType, Tnone); /* call parser */ PCB.pointer = (unsigned char *)(const char *)helpentStr; mhh6(); /* Print file statistics */ if (verbose) { printf("No. of title lines in line dict.= %d\n", stringdict_count(titleLineDict) ); printDict(titleLineDict); // print title lines printf( "\n\n" ); printf( "title count = %d, includes Secret of Life \n\n", title_count ); printf( "title line count = %d, includes Secret of Life \n\n", title_line_count ); printf( "total1sttextline = %d, \n", total1sttextline ); printf( "total1sttextlineb = %d \n", total1sttextlineb ); printf( "total1sttableline = %d \n", total1sttableline ); printf( "total1stlist1line = %d \n", total1stlist1line ); printf( "total1stlist2line = %d \n", total1stlist2line ); printf( "total1stlisttabline = %d \n", total1stlisttabline ); printf( "total1stcodeline = %d \n", total1stcodeline ); } /* check for error */ if (verbose) { printf( "PCB.exit_flag = %d (%d for success)\n", PCB.exit_flag, AG_SUCCESS_CODE); } if (PCB.exit_flag != AG_SUCCESS_CODE) { fprintf(stderr, "File %s: error at line %d, column %d\n", argv[1], PCB.line, PCB.column); return 8; } // Write sorted title lines & topics as HTML to intermediate file FILE *intermed; const char *filename = "intermed.html"; /* Open intermediate file */ intermed = fopen(filename ,"w+"); // create intermediate text file if (intermed == NULL) { fprintf(stderr, "Cannot open %s\n", filename); return 9; } if (verbose) { printf( "Writing sorted title lines & topic bodies to " "intermediate file in HTML format...\n"); } writeSortedHtml(intermed); rewind(intermed); /* Create output HTML file, inserting links */ FILE *output; /* Open output file */ output = fopen(argv[2] ,"w"); if (output == NULL) { fprintf(stderr, "Cannot open %s\n", argv[2]); return 10; } if (verbose) { printf( "Writing output file with HTML links...\n"); } int c = 0; int ctest = 0; while ( (c=fgetc(intermed)) != EOF ){ if ( c == 0xA9 ) { // begins link string // printf( "\n Found beginning of link" ); int itest = processLinkString(intermed, output); if (itest !=0) return itest; // error return } else { ctest = fputc( c, output ); // write out current character if (ctest == EOF) return 11; } } fclose(intermed); fclose(output); /* done */ if (verbose) { printf( "All done.\n" ); } return 0; // normal return } /* -- End of main() function -- */ } /* ---- End of embedded C ----------------------------------------- */