diff options
Diffstat (limited to 'indexing/glo+idxtex/gloscan.c')
-rw-r--r-- | indexing/glo+idxtex/gloscan.c | 618 |
1 files changed, 618 insertions, 0 deletions
diff --git a/indexing/glo+idxtex/gloscan.c b/indexing/glo+idxtex/gloscan.c new file mode 100644 index 0000000000..3ecde63e60 --- /dev/null +++ b/indexing/glo+idxtex/gloscan.c @@ -0,0 +1,618 @@ +/* #module GloScan "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: GloScan + * + * Author: R L Aurbach CR&DS MIS Group 20-Aug-1986 + * + * Function: + * Scan a file for glossary definitions and build the internal data + * structure for the data. + * + * Modification History: + * + * Version Initials Date Description + * ------------------------------------------------------------------------ + * 1-001 RLA 20-Aug-1986 Original Code + * 1-002 RLA 25-Aug-1986 Make Glo_Parse_Item more sophisticated. + * 2-001 F.H. 17-May-1991 converted to portable C + */ +/* + * Module GloScan - Module-Wide Data Description Section + * + * Include Files: + */ +#ifdef MSDOS +#include <stdlib.h> +#include <io.h> +#define F_OK 0 /* access(): File exists */ +#else +#include <sys/file.h> +extern char *sprintf(); +#endif +#include <string.h> +#include <ctype.h> +#include <malloc.h> +#include <stdio.h> +#include "GloDef.h" +/* + * Module Definitions: + */ +/* + * Global Declarations: + */ +#ifdef MSDOS +int Glo_Scan_File(STRING_PTR file); +#else +int Glo_Scan_File(); +#endif +/* + * Static Declarations: + */ +#ifdef MSDOS +static int glo_copy_text(char *line, NODE_PTR node); +static int glo_match_label(char *token); +static int glo_link_node(NODE_PTR node); +static int glo_parse_item(char *line, char *label, char *item, int *ptr); +#else +static int glo_copy_text(); +static int glo_match_label(); +static int glo_link_node(); +static int glo_parse_item(); +#endif +/* + * External References: + */ +#ifdef MSDOS +extern void idx_build_spell_string(char *desc); +#else +extern void idx_build_spell_string(); +#endif +extern NODE_PTR root; +extern STRING_PTR labels; +/* + * Functions Called: + */ +/* + * Function Glo_Scan_File - Documentation Section + * + * Discussion: + * Scan the specified glossary file for definitions which have labels which + * match the labels in the label list. If a match is found, copy the + * information to a NODE in the data structure and delete the label from + * the label list. Entries are placed in the data structure in alphabetic + * order. + * + * Calling Synopsis: + * status = Glo_Scan_File (file) + * + * Inputs: + * file -> is a STRING_PTR, passed by value. It contains the + * descriptor for the file specification string to be + * used to open the file. + * + * Outputs: + * none + * + * Return Value: + * status -> is a boolean flag which indicates the result of the + * operation. It will have a value of TRUE unless an + * error occurs which is fatal to the execution of the + * program. + * + * Global Data: + * root -> additions may be made to the internal data structure. + * + * labels -> if a definition is found, its entry in the label list is + * removed. + * + * Files Used: + * The specified definition file is opened for read access. + * + * Assumed Entry State: + * none + * + * Normal Exit State: + * status == TRUE The operation succeeded. This means that no error which + * is fatal to the operation of the program occurred, not + * that the program proceeded without error. + * + * Error Conditions: + * status == FALSE A fatal error occurred. The reason for the error should + * be described in a message to the user + * + * Algorithm: + * A. If the labels list is empty, return immediately. + * B. Convert the file spec to an ASCIZ string and open the file. + * C. For each entry in the file, + * 1. Locate the label. + * 2. If the label list contains that label, + * a. Delete the label from the label list. + * b. Allocate a NODE. + * c. Fill in the NODE with the item and spell string. + * d. Fill in the NODE with definition lines. + * e. Chain the NODE into the data structure, using the spell + * string to position it correctly. + * D. Close the file. + * + * Special Notes: + * none + */ +/* + * Function Glo_Scan_File - Code Section + */ +int Glo_Scan_File (file) +STRING_PTR file; +{ +/* + * Local Declarations + */ + char dna[256]; + FILE *f; + int counter = 0; + char line[linesz]; + char token[linesz]; + char item[linesz]; + int ptr; + int status; + NODE_PTR node; + int mode = FALSE; +/* + * Module Body + */ + if (labels == 0) return (TRUE); +/* Open the glossary definition file */ + (void)sprintf(dna, "%s.gdf", file->desc); + if ((f = fopen(dna, "r")) == NULL) { + (void)printf ("Could not find the glossary definition file %s\n", + file->desc); + return (TRUE); + } + while (fgets(line, linesz, f) != 0) { +/* + * If mode = FALSE, we are in discard mode. In this mode, we throw away any + * line which does not begin with "@entry". If mode = TRUE, we are in copy + * mode. In this mode, we copy any text to the current node. In either case, + * if the line begins with "@entry", we must process it. + */ + status = strncmp(line, "@entry{", 7); + if (status != 0) { + if (mode) (void)glo_copy_text(line, node); + continue; + } +/* + * We've found a new entry in the file. Begin processing it. + * Search for the first line of a definition entry and parse out the label. + */ + status = glo_parse_item(line, token, item, &ptr); + if (!status) { + mode = FALSE; + continue; + } +/* Search the label list for a label with the same name as the token. */ + status = glo_match_label (token); + if (!status) { + mode = FALSE; + continue; + } + counter++; +/* Allocate and build the NODE structure */ + node = (NODE_PTR) malloc(sizeof(NODE)); + if (node == 0) { + (void)printf("Could not allocate space for a new definition\n"); + return(FALSE); + } + node->next = 0; + node->hdr = 0; + node->spell = strdup(item); + idx_build_spell_string(node->spell); + node->item=strdup(item); +/* Link the NODE into the data structure in alphabetical order */ + status = glo_link_node(node); + if (!(status & TRUE)) { + (void)printf("Duplicate glossary entry \'%s\' ignored\n", item); + mode = FALSE; + continue; + } +/* If there is text on the @entry line, use it. */ + if (line[ptr] != '\0') (void)glo_copy_text (&line[ptr], node); + mode = TRUE; + } +/* End of file seen. */ + (void)fclose(f); + if (counter == 0) { + (void)printf("No definitions found in file %s.gdf\n", file->desc); + } + else + (void)printf("%d definitions extracted from file %s.gdf\n", + counter, file->desc); + return (TRUE); +} + +/* + * Function Glo_Link_Node - Documentation Section + * + * Discussion: + * Link a node into the node list in alphabetical order. + * + * Calling Synopsis: + * status = Glo_Link_Node (node) + * + * Inputs: + * node -> is a NODE_PTR, passed by reference. + * + * Outputs: + * none + * + * Return Value: + * status -> is a boolean integer. TRUE means a successful link. + * FALSE means a duplicate entry was found. + * + * Global Data: + * root -> the node is linked into the root list. + * + * Files Used: + * none + * + * Assumed Entry State: + * none + * + * Normal Exit State: + * status == TRUE node was linked in. + * + * Error Conditions: + * status == FALSE a node with this spell string was already linked into + * the list. This node is NOT linked in. + * + * Algorithm: + * A. If the list is empty, link the node in at the root. + * B. Else, + * 1. Beginning at the first node in the list, + * a. If spell-string < node-spell-string, + * 1. Get next node. + * b. If spell-string = node-spell-string, + * 1. Return FALSE. + * c. If spell-string > node-spell-string, + * 1. Link it in. + * + * Special Notes: + * none + */ +/* + * Function Glo_Link_Node - Code Section + */ +static int glo_link_node (node) +NODE_PTR node; +{ +/* + * Local Declarations + */ + NODE_PTR old_node; + NODE_PTR new_node; + int status; +/* + * Module Body + */ + old_node = 0; + new_node = root; + while (new_node != 0) { + status = strcmp(new_node->spell, node->spell); + if (status < 0) { + old_node = new_node; + new_node = new_node->next; + continue; + } + if (status == 0) return (FALSE); + if (status > 0) { + if (old_node == 0) root = node; + else old_node->next = node; + node->next = new_node; + return(TRUE); + } + } +/* If the list is exhausted, link the node in at the end. */ + if (old_node == 0) root = node; + else old_node->next = node; + return(TRUE); +} + +/* + * Function Glo_Match_Label - Documentation Section + * + * Discussion: + * See if a label in the label list matches the current file entry. + * If it does, then deallocate the label entry and return TRUE. + * Otherwise, return FALSE. + * + * Calling Synopsis: + * status = Glo_Match_Label (token) + * + * Inputs: + * token -> is the file token string to be matched against the label + * list. It is an ASCIZ string. + * + * Outputs: + * none + * + * Return Value: + * status -> is a boolean integer. TRUE indicates that this entry + * corresponds to a valid label in the label list. The + * label list entry is removed. FALSE indicates that + * this entry does not match a label in the label list. + * + * Global Data: + * labels -> if the entry matches a label, that STRING in the label + * list is removed. + * + * Files Used: + * none + * + * Assumed Entry State: + * none + * + * Normal Exit State: + * status == TRUE We have a match. + * status == FALSE No match. + * + * Error Conditions: + * none + * + * Algorithm: + * A. For each entry in the label list, + * 1. Compare the label with the token. + * 2. If they match, + * a. Unchain and deallocate the STRING. + * b. Return TRUE. + * 3. Else, + * a. Get the next label. + * B. If no match, + * 1. Return FALSE. + * + * Special Notes: + * none + */ +/* + * Function Glo_Match_Label - Code Section + */ +static int glo_match_label (token) +char *token; +{ +/* + * Local Declarations + */ + int length = strlen(token); + STRING_PTR old; + STRING_PTR new; +/* + * Module Body + */ + if (labels == 0) return (FALSE); + old = labels; + new = labels; + while (new != 0) { +/* Search the label list for a matching token */ + if ((strlen(new->desc)) != length) + if (TRUE) { + old = new; + new = new->next; + continue; + } + if (strncmp(token, new->desc, length) != 0) + if (TRUE) { + old = new; + new = new->next; + continue; + } +/* Found the matching token. Delete the entry in the labels list. */ + if (new == labels) labels = new->next; + else old->next = new->next; + (void)free((char *)new->desc); + (void)free((char *)new); + return (TRUE); + } + return (FALSE); +} + +/* + * Function Glo_Parse_Item - Documentation Section + * + * Discussion: + * Parse the label and item strings from a line with the format + * @entry{label,item}[text] + * leaving the pointer pointing to the optional text string. + * + * Calling Synopsis: + * status = Glo_Parse_Item (line, label, item, ptr) + * + * Inputs: + * line -> is the text line to parse. It is an ASCIZ text string. + * + * + * Outputs: + * label -> is the label text string. It is an ASCIZ text string. + * + * item -> is the item text string. It is an ASCIZ text string. + * + * ptr -> is an integer index value, passed by reference. It is + * the array index of the next character of the line + * string, after the closing "}". + * + * Return Value: + * status -> is a result indicator. If TRUE, the label and item + * elements were found. If FALSE, there was a problem + * with the parse operation. + * + * Global Data: + * none + * + * Files Used: + * none + * + * Assumed Entry State: + * none + * + * Normal Exit State: + * status == TRUE Operation succeeded. All output variables were + * returned. + * + * Error Conditions: + * status == FALSE Operation failed due to a missing syntax element. + * None of the output variables is trustworthy. + * + * Algorithm: + * A. Parse out the label. It begins with the first character after the + * leading "{" and is terminated by a ",". + * B. Find the beginning of the item. It is starts at the first + * non-whitespace character after the ",". + * C. Parse out the item. Internally, braces are allowed as long as they + * properly match. + * + * Special Notes: + * none + */ +/* + * Function Glo_Parse_Item - Code Section + */ +static int glo_parse_item (line, label, item, ptr) +char *line; +char *label; +char *item; +int *ptr; +{ +/* + * Local Declarations + */ + int i; + int brace; + char x; +/* + * Module Body + */ +/* Copy the label to the output string. */ + i = 0; + brace = 1; + *ptr = 7; + while(TRUE) { + x = line[(*ptr)++]; + if (x == '\0') return(FALSE); + if (x == '{') if (line[*ptr - 2] != '\\') brace++; + if (x == '}') { + if (line[*ptr - 2] != '\\') brace--; + if (brace <= 0) break; + } + if (x == ',') break; + label[i++] = x; + } + label[i] = '\0'; +/* Find the beginning of the item string. */ + while (isspace(line[*ptr]) != 0) (*ptr)++; +/* Copy the item to the output string. */ + i = 0; + while (brace > 0) { + x = line[(*ptr)++]; + if (x == '\0') return(FALSE); + if (x == '{') if (line[*ptr - 2] != '\\') brace++; + if (x == '}') { + if (line[*ptr - 2] != '\\') brace--; + if (brace <= 0) break; + } + item[i++] = x; + } + item[i] = '\0'; +/* Check to see if the item is missing. If it is, default to the label. */ + if (i == 0) (void)strcpy(item, label); + return (TRUE); +} + +/* + * Function Glo_Copy_Text - Documentation Section + * + * Discussion: + * Create a STRING containing the current line of text and chain it in + * to the current node's definition list. + * + * Calling Synopsis: + * status = Glo_Copy_Text (line, node) + * + * Inputs: + * line -> is the current line of text. It is an ASCIZ string. + * + * node -> is the NODE_PTR for the current glossary entry. + * + * Outputs: + * none + * + * Return Value: + * status -> is a boolean integer which reflects success or + * failure. TRUE will be returned unless there is a + * failure to allocate the string. + * + * Global Data: + * none + * + * Files Used: + * none + * + * Assumed Entry State: + * none + * + * Normal Exit State: + * status == TRUE success. + * + * Error Conditions: + * status == FALSE virtual memory allocation failure. + * + * Algorithm: + * A. Allocate a STRING data structure. + * B. If the input string has a non-zero length, + * 1. Copy the string to the STRING data structure. + * C. Chain the structure in to the end of the hdr structure. + * + * Special Notes: + * none + */ +/* + * Function Glo_Copy_Text - Code Section + */ +static int glo_copy_text (line, node) +char *line; +NODE_PTR node; +{ +/* + * Local Declarations + */ + int length; + STRING_PTR old; + STRING_PTR text; +/* + * Module Body + */ + length = strlen(line); + if (line[length-1] == '\n') length--; + if (length > 0) { + text = (STRING_PTR) malloc(sizeof(STRING)); + if (text == 0) return (FALSE); + text->next = 0; + text->desc = strdup(line); + if (node->hdr == 0) node->hdr = text; + else { + old = node->hdr; + while (old->next != 0) old = old->next; + old->next = text; + } + } + return (TRUE); +} |