/* #module GloBldLab "2-001" *********************************************************************** * * * The software was developed at the Monsanto Company and is provided * * "as-is". Monsanto Company and the auther disclaim all warranties * * on the software, including without limitation, all implied warran- * * ties of merchantabilitiy and fitness. * * * * This software does not contain any technical data or information * * that is proprietary in nature. It may be copied, modified, and * * distributed on a non-profit basis and with the inclusion of this * * notice. * * * *********************************************************************** */ /* * Module Name: GloBldLab * * Author: R L Aurbach CR&DS MIS Group 18-Aug-1986 * * Function: * Build the list of labels seen in the input file. Also, if a file * entry is seen, add it to the filelist. * * Modification History: * * Version Initials Date Description * ------------------------------------------------------------------------ * 1-001 RLA 18-Aug-1986 Original Code * 1-002 RLA 26-Aug-1986 Fix problem with duplicate label * detection. * 2-001 F.H. 17-May-1991 converted to portable C */ /* * Module GloBldLab - Module-Wide Data Description Section * * Include Files: */ #ifdef MSDOS #include #include #define F_OK 0 /* access(): File exists */ #else #include extern char *sprintf(); #endif #include #include #include #include "GloDef.h" /* * Module Definitions: */ /* * Global Declarations: */ #ifdef MSDOS int Glo_Build_LabLst(void); #else int Glo_Build_LabLst(); #endif /* * Static Declarations: */ /* * External References: */ extern char infile[256]; extern STRING_PTR labels; extern STRING_PTR filelist; /* * Functions Called: */ #ifdef MSDOS static void glo_get_token(char *buffer, char *token); static int glo_get_next_file(char *token, int *ptr, char *spec); #else static void glo_get_token(); static int glo_get_next_file(); #endif /* * Function Glo_Build_LabLst - Documentation Section * * Discussion: * Read the input file and use its contents to build a list of labels for * which glossary entries are needed. If a file specification is seen * during this operation, add the file to the filelist. * * Calling Synopsis: * status = Glo_Build_LabLst () * * Inputs: * none * * Outputs: * none * * Return Value: * status -> is a status code for the operation. It is a boolean * integer, passed by value. If TRUE, the routine * completed normally. If FALSE, an error occurred. * * Global Data: * labels -> the list of labels is created by this routine. * * filelist -> if one or more files are seen by the routine, they are * added to the file list. * * Files Used: * The input file is read. * * Assumed Entry State: * none * * Normal Exit State: * status = TRUE normal successful completion. * * Error Conditions: * status = FALSE an error occurred. The reason for the error is written * to SYS$OUTPUT. * * Algorithm: * A. Open the input file. * B. For each record in the file, * 1. If it is an \indexentry, * or If it is a \glossaryentry, (TeX 3.0) * a. Parse out the label. * b. If the label does not already appear in the label list, * 1. Build a STRING to contain the label. * 2. Chain it into the label list. * 2. If it is a \glofile, * a. For each file in the list, * 1. Parse out the file specification. * 2. Build a STRING to contain the file specification. * 3. Chain it into the file list. * 3. Else, * a. Ignore the record. * C. Close the input file. * * Special Notes: * none */ /* * Function Glo_Build_LabLst - Code Section */ int Glo_Build_LabLst () { /* * Local Declarations */ int status; FILE *file; char linebf[linesz]; char label[linesz]; int found; STRING_PTR new; STRING_PTR old; char spec[linesz]; int ptr; char fname[256]; /* * Module Body */ /* Open the input file */ (void)sprintf(fname,"%s.glo",infile); if ((file = fopen(fname, "r")) == NULL) { (void)printf("Could not open the input file\n"); return (FALSE); } /* For each record in the file, */ status = TRUE; while (fgets(linebf, linesz, file) != 0) { /* * If the record begins with \indexentry (or \glossaryentry), then it is * a record containing a label. Process the label by parsing it out, * checking for duplicates, and if unique, building a label list entry for it. */ if ((strncmp(linebf, "\\indexentry{", 12)) == 0) { glo_get_token(&linebf[12], label); if (strlen(label) == 0) continue; old = labels; found = FALSE; while (old != 0) { if (strcmp(label,old->desc) == 0) found = TRUE; if (old->next == 0) break; old = old->next; } if (!found) { new = (STRING_PTR) malloc(sizeof(STRING)); if (new == 0) continue; new->next = 0; new->desc=strdup(label); if (old == 0) labels = new; else old->next = new; } } else if ((strncmp(linebf, "\\glossaryentry{", 15)) == 0) { glo_get_token(&linebf[15], label); if (strlen(label) == 0) continue; old = labels; found = FALSE; while (old != 0) { if (strcmp(label,old->desc) == 0) found = TRUE; if (old->next == 0) break; old = old->next; } if (!found) { new = (STRING_PTR) malloc(sizeof(STRING)); if (new == 0) continue; new->next = 0; new->desc=strdup(label); if (old == 0) labels = new; else old->next = new; } } /* * If the record begins with \glofile, then it is a record containing one or * more glossary definition file specifications. For each specification, parse * it out and build a file list entry for it. */ else if ((strncmp(linebf, "\\glofile{", 9)) == 0) { glo_get_token(&linebf[9], label); if (strlen(label) == 0) continue; ptr = 0; while (glo_get_next_file(label, &ptr, spec) != 0) { new = (STRING_PTR) malloc(sizeof(STRING)); if (new == 0) continue; new->next = 0; new->desc=strdup(spec); old = filelist; if (old == 0) filelist = new; else { while (old->next != 0) old = old->next; /*@@@ old->next = file;*/ } } } /* * If the record begins with anything else, ignore it. */ else continue; } (void)fclose(file); return (status); } /* * Function Glo_Get_Token - Documentation Section * * Discussion: * Parse a token from the command line. The token begins at the first * character position in the buffer and ends with a "}". * * Calling Synopsis: * Call Glo_Get_Token (buffer, token) * * Inputs: * buffer -> is an ASCIZ string containing the token to be found. * * Outputs: * token -> is an ASCIZ string into which the token is copied. * * Return Value: * none * * Global Data: * none * * Files Used: * none * * Assumed Entry State: * none * * Normal Exit State: * The token is returned. * * Error Conditions: * none * * Algorithm: * A. Locate the trailing "}" or end of string. * B. Copy the substring starting at the beginning of the buffer to the * end found to the token. * C. Null terminate the string. * * Special Notes: * none */ /* * Function Glo_Get_Token - Code Section */ static void glo_get_token (buffer, token) char *buffer; char *token; { /* * Local Declarations */ int len; /* Length of the substring */ /* * Module Body */ len = strcspn(buffer, "}"); (void)strncpy(token, buffer, len); token[len] = '\0'; } /* * Function Glo_Get_Next_File - Documentation Section * * Discussion: * Parse the next file specification out of the token list. Files are * separated by commas. Return the length of the specification. * * Calling Synopsis: * length = Glo_Get_Next_File (token, ptr, spec) * * Inputs: * token -> is an ASCIZ string containing the list of files. * * ptr -> is an integer (passed by reference) which is the * starting index in the token string for the search. * * Outputs: * spec -> is an ASCIZ string containing the next file spec. * * Return Value: * length -> is the length of the spec string. A value of 0 * indicates that there is no file spec. * * Global Data: * none * * Files Used: * none * * Assumed Entry State: * none * * Normal Exit State: * length != 0 spec contains a file spec. ptr is updated to point * to the starting place for the next search. * length == 0 no spec was found. * * Error Conditions: * none * * Algorithm: * A. Find the next "," in the string. * B. Copy the substring into the output variable. * C. Adjust the pointer. * D. Return the length of the string. * * Special Notes: * none */ /* * Function Glo_Get_Next_File - Code Section */ static int glo_get_next_file (token, ptr, spec) char *token; int *ptr; char *spec; { /* * Local Declarations */ int length; /* * Module Body */ length = strcspn (&token[*ptr], ","); if (length != 0) { (void)strncpy (spec, &token[*ptr], length); spec[length] = 0; (*ptr) += length; if (token[*ptr] == ',') (*ptr)++; } return (length); }