summaryrefslogtreecommitdiff
path: root/indexing/glo+idxtex/gloscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'indexing/glo+idxtex/gloscan.c')
-rw-r--r--indexing/glo+idxtex/gloscan.c618
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);
+}