summaryrefslogtreecommitdiff
path: root/support/glosstex/database.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/glosstex/database.c
Initial commit
Diffstat (limited to 'support/glosstex/database.c')
-rw-r--r--support/glosstex/database.c335
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 */
+}