diff options
Diffstat (limited to 'support/glosstex/database.c')
-rw-r--r-- | support/glosstex/database.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/support/glosstex/database.c b/support/glosstex/database.c new file mode 100644 index 0000000000..594aac8219 --- /dev/null +++ b/support/glosstex/database.c @@ -0,0 +1,335 @@ +/* -*- c -*- */ + +/* + GlossTeX, a tool for the automatic preparation of glossaries. + Copyright (C) 1997 Volkan Yavuz + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Volkan Yavuz, yavuzv@rumms.uni-mannheim.de + */ + +/* $Id: database.c,v 1.45 1997/12/13 16:06:54 volkan Exp $ */ + +#include "glosstex.h" +#include "database.h" +#include "error.h" +#include "list.h" +#include "labels.h" +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +enum e_pass { + PASS_1 = 0, PASS_2 = 1 +}; + +static unsigned int lineno = 0; + +static void process_file (enum e_pass pass, FILE * infile, char *inname); +static void process_line (enum e_pass pass, char *inname, char *line); +static void write_line (FILE * outfile, + char* inname, + char *list, char *label, char *item, char *longform, + char *line, char *list_mode, char *pageref_mode, + char *page); +static int glo_parse_item (char *line, char *label, + char *item, char *longform, int *ptr); + +void +read_databases (void) +{ + FILE *dbfile; + enum e_pass pass = PASS_1; + s_node *filename = databases.root; + + for (pass = PASS_1; pass <= PASS_2; pass++) { + while (filename != 0) { + if ((dbfile = fopen (filename->ptr, "r")) == NULL) { + error ("database %s", (char *) filename->ptr); + } else { + printlog (PROGRESS, STDOUT, "(%s ", (char *) filename->ptr); + process_file (pass, dbfile, (char *) filename->ptr); + printlog (PROGRESS, STDOUT, ")"); + } + filename = filename->next; + } + filename = databases.root; + } +} + +static void +process_file (enum e_pass pass, FILE * dbfile, char *inname) +{ + enum e_state { + HEADER, BODY + }; + + int status; + char buf[LINESIZE]; + enum e_state state = HEADER; + char *line = 0; + + while (fgets (buf, LINESIZE, dbfile) != 0) { + if (buf[strlen (buf) - 1] == '\n') + lineno++; + + status = strncmp (buf, "@entry{", 7); + if ((state == HEADER) && (status != 0)) { + ; /* ignore heading garbage */ + } else { + state = BODY; + if (status == 0) { /* begin new entry */ + + /* process current entry before starting new entry */ + if (line != 0) { + process_line (pass, inname, line); + free (line); + } + line = (char *) malloc (strlen (buf) + 1); + assert (line != 0); + strcpy (line, buf); + + if (line[strlen (line) - 1] == '\n') + line[strlen (line) - 1] = ' '; + + } else if (strncmp (buf, "%", 1) == 0) { + ; /* skip comments */ + } else { /* add lines to current entry */ + size_t len = strlen (line); /* LINT: null is ok here */ + line = (char *) realloc (line, len + strlen (buf) + 1); + assert (line != 0); + strcpy (&line[len], buf); + if (line[strlen (line) - 1] == '\n') + line[strlen (line) - 1] = ' '; + } + } + } + + /* process last pending line in file */ + if (line != 0) { + process_line (pass, inname, line); + free (line); + } +} + +static void +process_line (enum e_pass pass, char *inname, char *line) +{ + char label[LINESIZE]; + char item[LINESIZE]; + char longform[LINESIZE]; + size_t index; + int ptr = 0; + s_list_iterator iter; + s_list_iterator iter2; + s_label *node; + s_label *node2; + + iter.root = labels.root; + iter.current = labels.root; + iter2.root = labels.root; + iter2.current = labels.root; + + if (glo_parse_item (line, label, item, longform, &ptr) != 0) { + printlog (PROGRESS, STDOUT, "x"); + printlog (WARNING, LOGFILE, "\n%s:%u parse error: %s", + inname, lineno, line); + count_gdf_parsing++; + return; + } + /* remove all trailing spaces */ + index = strlen (&line[ptr]); + index--; + + while (line[ptr + index] == ' ') { + line[ptr + index] = '\0'; + index--; + } + + switch (pass) { + case PASS_1: + /* is there a reference to <label> in any list? */ + node = find_label (&iter, FIND_FIRST, label, 0); + + if (node != 0) { + /* explicit reference to <label> found + process references to <label> in each <list> */ + while (node != 0) { + switch ((enum e_label_flag) node->flag) { + case UNRESOLVED: + write_line (outfile, inname, + node->list, label, item, longform, &line[ptr], + node->list_mode, node->pageref_mode, node->page); + node->flag = RESOLVED; + break; + + case RESOLVED: + printlog (PROGRESS, STDOUT, "i"); + printlog (INFORMATION, LOGFILE, + "\n%s:%u %s already resolved", + inname, lineno, label); + count_gdf_defined++; + break; + } + node = find_label (&iter, FIND_NEXT, label, 0); + } + } + break; + case PASS_2: + /* now look for wildcard in any list */ + node = find_label (&iter, FIND_FIRST, "*", 0); + + if (node == 0) { + printlog (PROGRESS, STDOUT, "."); + printlog (DEBUG, LOGFILE, "\n%s:%u %s@%s(%s) not needed", + inname, lineno, label, item, longform); + } else { + /* check for wildcard in every list */ + while (node != 0) { + /* wurde <label> in <node->list> schon explicit angefordert? */ + if ((node2 = + find_label (&iter2, FIND_FIRST, label, node->list)) == 0) { + write_line (outfile, inname, + node->list, label, item, longform, &line[ptr], + node->list_mode, node->pageref_mode, node->page); + node->flag = RESOLVED; + } + node = find_label (&iter, FIND_NEXT, "*", 0); + } + } + break; + } +} + +static void +write_line (FILE * outfile, + char* inname, + char *list, char *label, char *item, char *longform, + char *line, char *list_mode, char *pageref_mode, char *page) +{ + fprintf (outfile, + "\\GlossTeXEntry{%s%s@{%s}{%s}{%s}{%s}{%s}{%s}" + "{\\GlossTeXPage{%s}{%s}}|GlossTeXNull}{0}\n", + list, label, label, item, longform, line, + list, list_mode, pageref_mode, page); + printlog (PROGRESS, STDOUT, "o"); + printlog (VERBOSE, LOGFILE, "\n%s:%u %s@%s(%s) used *", + inname, lineno, label, item, longform); + count_gdf_success++; +} + +/* #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. * + * * + *********************************************************************** + */ + +/* this has been slightly modified by volkan yavuz 1996/12/18 */ + +static int +glo_parse_item (char *line, char *label, char *item, char *longform, int *ptr) +{ + int i, brace; + char x; + + /* Copy the label to the output string. */ + i = 0; + brace = 1; + *ptr = 7; + while (1) { + x = line[(*ptr)++]; + if (x == '\0') + return 1; + 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 1; + if (x == '{') + if (line[*ptr - 2] != '\\') + brace++; + if (x == '}') { + if (line[*ptr - 2] != '\\') + brace--; + if (brace <= 0) + break; + } + if (x == ',') + 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); /* FIXME: lint code error */ + + while (isspace (line[*ptr]) != 0) + (*ptr)++; + + /* Copy the long-form to the output string. */ + i = 0; + while (brace > 0) { + x = line[(*ptr)++]; + if (x == '\0') + return 1; + if (x == '{') + if (line[*ptr - 2] != '\\') + brace++; + if (x == '}') { + if (line[*ptr - 2] != '\\') + brace--; + if (brace <= 0) + break; + } + longform[i++] = x; + } + longform[i] = '\0'; + + return 0; /* it's all ok */ +} |