1 /*********************************************************************/
2 /*  bibView: Administration of BibTeX-Databases                      */
3 /*           (Verwaltung von BibTeX-Literaturdatenbanken)            */
4 /*                                                                   */
5 /*  Module:  rc_file.c                                               */
6 /*                                                                   */
7 /*             - Handling of Configuration files                     */
8 /*             -                                                     */
9 /*                                                                   */
10 /*  Author:  Holger Martin,  martinh@informatik.tu-muenchen.de       */
11 /*           Peter M. Urban, urban@informatik.tu-muenchen.de         */
12 /*                                                                   */
13 /*  History:                                                         */
14 /*    11.22.91  HM   created                                         */
15 /*    05.26.92       Version 1.0 released                            */
16 /*                                                                   */
17 /*  Copyright 1992 TU MUENCHEN                                       */
18 /*    See ./Copyright for complete rights and liability information. */
19 /*                                                                   */
20 /*********************************************************************/
21 
22 #include <stdio.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <ctype.h>
26 #include <X11/Intrinsic.h>
27 #include <X11/StringDefs.h>
28 #include <sys/param.h>
29 #include <sys/stat.h>
30 
31 #include "bibview.h"
32 
33 /* imported global variables */
34 /* ------------------------- */
35 
36 
37 /* macros and definitions */
38 /* ---------------------- */
39 #define STR_TRUE 		"TRUE"
40 #define STR_BEEP_ON_ERROR_OPT	"BeepOnError"
41 #define STR_ICON_ON_DESK_OPT	"IconsOnDesk"
42 #define STR_MAKE_BACKUPS_OPT	"MakeBackups"
43 #define STR_AUTO_CHECK_BIB_OPT	"AutoCheckBib"
44 #define STR_REQUIRED_FIELDS_OPT "RequiredFields"
45 #define STR_IGNORE_CASE         "IgnoreCase"
46 #define STR_PRINT_AS_BIB        "PrintAsBib"
47 #define STR_DISPLAY_ERRWIN      "DisplayErrWin"
48 #define STR_FOCUS               "Focus"
49 #define STR_ORIG                "Orig"
50 
51 #define STR_FLDINDENT           "fldindent"
52 #define STR_CONTINDENT          "contindent"
53 #define STR_NEWLINEINDENT       "newlineindent"
54 #define STR_MAXLINELEN          "maxlinelen"
55 
56 #define MAX_TAGLEN		80
57 #define MAX_CFGLINELEN		255
58 
59 typedef enum {
60    findTag,         /* Modus: Suche nach Tag in Konfigdatei        */
61    illegalTag,      /*        Tag gefunden, aber ungueltig         */
62    optionTags,      /*        Optionen-Tag, jetzt folgen Optionen  */
63    userFldTags,     /*        Benutzerdefinierte Felder folgen     */
64    predefTags,      /*        Vordefinierte Feldinhalte  folgen    */
65    latexHeadTags,   /*        Kopfzeilen der LaTeX-Druckdatei      */
66    latexFootTags,   /*        Fusszeilen der LaTeX-Druckdatei      */
67    indentTags,      /*        indentation in BibTeX Format         */
68    sortedByTags,    /*        default how List is Sorted           */
69    sortFieldTags,   /*        fields by which files can be sorted  */
70    searchFieldTags, /*        fields considered in a search        */
71    annoteFieldTags, /*        name of annote field                 */
72    styleFileTags,   /*        default Style File                   */
73    listFieldTags,   /*        layout of list entry                 */
74    typeTags,        /*        define new types                     */
75    defaultDirTags   /*        default Directory                    */
76 } CfgMode;
77 
78 typedef struct {
79    char *tagStr;
80    CfgMode mode;
81 } TagType;
82 
83 
84 /* local function prototypes */
85 /* ------------------------- */
86 static CfgMode  getCfgFileTag        (char *str);
87 static int      procOptionLine       (char *str);
88 static int      procPredefLine       (char *str);
89 static int      procUserFldLine      (char *str);
90 static int      procLatexHeadLine    (char *str);
91 static int      procLatexFootLine    (char *str);
92 static int      procIndentLine       (char *str);
93 static int      procTypeLine         (char *str);
94 static int      procSortFieldLine    (char *str);
95 static int      procSortedByLine     (char *str);
96 static int      procStyleFileLine    (char *str);
97 static int      procSearchFieldLine  (char *str);
98 static int      procListFieldLine    (char *str);
99 static int      procAnnoteFieldLine  (char *str);
100 static int      build_path 	     (char *str1, char *str2);
101 
102 
103 /* exported variables */
104 /* ------------------ */
105 UserDefFld userDefFlds[MAX_BIBTEX_TYPES+1];
106 
107 PredefLists predefLst;
108 
109 char *latexHeader = NULL;
110 int latexHeaderLen = 0;
111 char *latexFooter = NULL;
112 int latexFooterLen = 0;
113 int fld_indent, cont_indent, newline_indent, max_linelen;
114 
115 char *actual_path;
116 extern char *style_file;
117 extern int sortedby;
118 extern listEntry *list_layout;
119 extern OptionsRec options;
120 
121 extern char requiredfields[MAX_BIBTEX_TYPES+1][MAX_FIELDS];
122 extern char standardfields[MAX_BIBTEX_TYPES+1][MAX_FIELDS];
123 extern String cardNames[];
124 extern String fieldNames[];
125 extern int max_fields;
126 extern int max_bibtex_types;
127 extern char sort_field[];
128 extern char is_search_field[];
129 
130 
131 /* local global variables */
132 /* ---------------------- */
133 
134 TagType tagTypes[] = {
135    { "Options",       optionTags },
136    { "UserFields",    userFldTags },
137    { "Predefines",    predefTags },
138    { "LatexHeader",   latexHeadTags },
139    { "LatexFooter",   latexFootTags },
140    { "Indent",        indentTags },
141    { "BibDir", 	      defaultDirTags},
142    { "SortedBy",      sortedByTags},
143    { "SortFields",    sortFieldTags},
144    { "SearchFields",  searchFieldTags},
145    { "AnnoteField",   annoteFieldTags},
146    { "StyleFile",     styleFileTags},
147    { "ListFields",    listFieldTags},
148    { "Types",         typeTags},
149    { NULL,            illegalTag }
150 };
151 
152 static Boolean processOptions = TRUE,
153                prtToStd = TRUE;
154 
155 static int akttype;
156 
157 
158 
159 /*********************************************************************/
160 /* rcfReadCfgFile:                                                   */
161 /*    Reads and processes .bibrc configuration file                  */
162 /*********************************************************************/
163 int
rcfReadCfgFile(char * cfgFname)164 rcfReadCfgFile (char *cfgFname)
165 {
166 FILE *cfgFP;
167 CfgMode curMode;
168 char cfgLine[MAX_CFGLINELEN+1];
169 char *cfgp;
170 int  i;
171 char processLine;
172 
173    /* throw away old values */
174    if (latexHeader) {
175       XtFree(latexHeader);
176       latexHeader = NULL;
177       latexHeaderLen = 0;
178    }
179    if (latexFooter) {
180       XtFree(latexFooter);
181       latexFooter = NULL;
182       latexFooterLen = 0;
183    }
184 
185    if (glbContIllegalChar(cfgFname) != 0) {
186       return(ERR_NO_CFGFILE);
187    }
188 
189 
190    if ((cfgFP = fopen(cfgFname, "r")) == NULL) {
191       return(ERR_NO_CFGFILE);
192    }
193 
194    curMode = findTag;
195    while (TRUE) {
196       /* Zeile in Zeilenpuffer lesen */
197       /* for (i=0; (i <= MAX_CFGLINELEN) && (cfgLine[i-1] != '\n'); i++) { */
198        for (i=0; (i <= MAX_CFGLINELEN) && ((i==0) || (cfgLine[i-1] != '\n')); i++) {
199          if (fread(&cfgLine[i], 1, 1, cfgFP) == 0)
200             break;
201       }
202       if (feof(cfgFP))  /* Ende der Konfigdatei */
203          break;
204       if (cfgLine[0] == '\n')  /* Leerzeilen ueberspringen */
205          continue;
206       cfgLine[i-1] = '\0';  /* Stringende setzen */
207 
208       /* gelesene Zeile bearbeiten */
209       cfgp = cfgLine;
210       while (isspace(*cfgp)) cfgp++;
211 
212 /*      switch (cfgLine[0]) { */
213       switch (*cfgp) {
214          case '#':  /* Kommentarzeile */
215                     processLine = FALSE;
216                     break;
217          case '[':  /* Neuer Abschnitt in Konfigdatei */
218               /*      curMode = getCfgFileTag(cfgLine); */
219                     curMode = getCfgFileTag(cfgp);
220 		    if (curMode == listFieldTags)
221                        list_layout->number = 0;
222                     if (curMode != illegalTag)
223                        continue;
224                     processLine = TRUE;
225 		    break;
226          default:   /* Zeile je nach aktuellem Modus bearbeiten */
227                     processLine = TRUE;
228       } /* endswitch */
229 
230       if (processLine) {
231          switch (curMode) {
232             case optionTags:  /* Optionszeilen bearbeiten */
233                               procOptionLine(cfgLine);
234                               break;
235             case predefTags:  /* Vordef.zeilen bearbeiten */
236                               procPredefLine(cfgLine);
237                               break;
238             case userFldTags: /* Ersetzungsdef bearbeiten */
239                               procUserFldLine(cfgLine);
240                               break;
241             case latexHeadTags: /* Kopfzeilen bearbeiten */
242                               procLatexHeadLine(cfgLine);
243                               break;
244             case latexFootTags: /* Fusszeilen bearbeiten */
245                               procLatexFootLine(cfgLine);
246                               break;
247             case indentTags:  /* bearbeiten */
248                               procIndentLine(cfgLine);
249                               break;
250             case defaultDirTags: /* Default Directory */
251                               procDefaultDirLine(cfgLine);
252                               break;
253             case sortedByTags: /* Style File */
254                               procSortedByLine(cfgLine);
255                               break;
256             case sortFieldTags: /* fields considered for sorting */
257                               procSortFieldLine(cfgLine);
258                               break;
259             case searchFieldTags: /* fields considered in search */
260                               procSearchFieldLine(cfgLine);
261                               break;
262             case annoteFieldTags: /* Style File */
263                               procAnnoteFieldLine(cfgLine);
264                               break;
265             case styleFileTags: /* Style File */
266                               procStyleFileLine(cfgLine);
267                               break;
268             case listFieldTags: /* layout for list */
269                               procListFieldLine(cfgLine);
270                               break;
271             case typeTags: /* Style File */
272                               procTypeLine(cfgLine);
273                               break;
274             case illegalTag:  /* Fehler im Tag aufgetreten */
275                               if (prtToStd)
276 				 fprintf(stderr, "bibview: illegal tag %s in %s\n", cfgLine, cfgFname);
277                               curMode = findTag;
278                               break;
279             case findTag:     ;
280             default:          ;
281          } /* endswitch */
282       } /* endif */
283    } /* endwhile */
284 
285    fclose(cfgFP);
286    return(OK);
287 }
288 
289 
290 /*********************************************************************/
291 /* rcfSetPrintMode:                                                  */
292 /*    Sets whether messages go to stderr or not                      */
293 /*********************************************************************/
294 Errcode
rcfSetPrintMode(Boolean bool)295 rcfSetPrintMode (Boolean bool)
296 {
297    prtToStd = bool;
298    return(OK);
299 }
300 
301 
302 /*********************************************************************/
303 /* rcfReadOptions:                                                   */
304 /*    Sets flag whether options in rc file should be processed       */
305 /*********************************************************************/
306 Errcode
rcfReadOptions(Boolean bool)307 rcfReadOptions (Boolean bool)
308 {
309    processOptions = bool;
310    return(OK);
311 }
312 
313 
314 
315 /*********************************************************************/
316 /* LOCAL FUNCTIONS                                                   */
317 /*********************************************************************/
318 
319 /*********************************************************************/
320 /* getCfgFileTag:                                                    */
321 /*    Finds next paragraph of config file                            */
322 /*********************************************************************/
323 static CfgMode
getCfgFileTag(char * str)324 getCfgFileTag (char *str)
325 {
326 char token[MAX_TAGLEN+1] = "";
327 TagType *tptr;
328 
329    sscanf(str, "[%[^]]s", token);
330 
331    for (tptr = &tagTypes[0];
332 	tptr->tagStr != NULL && strcmp(token, tptr->tagStr);
333 	tptr++) ;
334 
335    return( (tptr->tagStr != NULL) ? tptr->mode : illegalTag);
336 }
337 
338 
339 /*********************************************************************/
340 /* procOptionLine:                                                   */
341 /*    Process line containing option defs                            */
342 /*********************************************************************/
343 static int
procOptionLine(char * str)344 procOptionLine (char *str)
345 {
346 char token[MAX_TAGLEN+1] = "",
347      value[MAX_CFGLINELEN+1] = "";
348 char *p;
349 int width, fieldnr;
350 
351    if ((p = strchr(str, ':')) == NULL) {
352       if (prtToStd)
353 	 fprintf(stderr, "bibview: illegal [Options] format: %s\n", str);
354       return(OK);
355    }
356 
357    *p = '\0';
358    strcpy(token, str);
359    glbTrimString(token);
360    strcpy(value, p+1);
361    glbTrimString(value);
362 
363    if (!processOptions)
364       return(OK);
365 
366    if (strcmp(token, STR_BEEP_ON_ERROR_OPT) == 0) {
367       optionsStatus[OPT_BEEP_ON_ERROR] =
368 			       (strcmp(strupr(value), STR_TRUE) == 0);
369       options.quiet = !optionsStatus[OPT_BEEP_ON_ERROR];
370 
371    }
372    else if (strcmp(token, STR_ICON_ON_DESK_OPT) == 0) {
373       optionsStatus[OPT_ICON_ON_DESKTOP] = options.iconsOnDesk =
374 			       (strcmp(strupr(value), STR_TRUE) == 0);
375    }
376    else if (strcmp(token, STR_MAKE_BACKUPS_OPT) == 0) {
377       optionsStatus[OPT_BACKUP_ON_SAVE] = options.makeBackup =
378 			       (strcmp(strupr(value), STR_TRUE) == 0);
379    }
380    else if (strcmp(token, STR_AUTO_CHECK_BIB_OPT) == 0) {
381       optionsStatus[OPT_AUTO_CHECK_BIB] = options.autoCheck =
382 			       (strcmp(strupr(value), STR_TRUE) == 0);
383    }
384    else if (strcmp(token, STR_REQUIRED_FIELDS_OPT) == 0) {
385       optionsStatus[OPT_REQUIRED_FIELDS] = options.reqFields =
386 			       (strcmp(strupr(value), STR_TRUE) == 0);
387    }
388    else if (strcmp(token, STR_IGNORE_CASE) == 0) {
389       optionsStatus[OPT_IGNORE_CASE] = options.ignoreCase =
390 			       (strcmp(strupr(value), STR_TRUE) == 0);
391    }
392    else if (strcmp(token, STR_PRINT_AS_BIB) == 0) {
393       optionsStatus[OPT_PRINT_AS_BIB] = options.printAsBib =
394 			       (strcmp(strupr(value), STR_TRUE) == 0);
395    }
396    else if (strcmp(token, STR_DISPLAY_ERRWIN) == 0) {
397       optionsStatus[OPT_DISPLAY_ERRWIN] = options.displayErrWin =
398 			       (strcmp(strupr(value), STR_TRUE) == 0);
399    }
400    else if (strcmp(token, STR_FOCUS) == 0) {
401       optionsStatus[OPT_FOCUS] =  options.focus =
402 			       (strcmp(strupr(value), STR_TRUE) == 0);
403    }
404    else if (strcmp(token, STR_ORIG) == 0) {
405       optionsStatus[OPT_ORIG] =  options.orig =
406 			       (strcmp(strupr(value), STR_TRUE) == 0);
407    }
408    else {
409       if (prtToStd)
410 	 fprintf(stderr, "bibview: Illegal option %s in config file.\n", str);
411    }
412    return(OK);
413 }
414 
415 
416 /*********************************************************************/
417 /* procIndentLine:                                                   */
418 /*    Process line containing indentation information                */
419 /*********************************************************************/
420 static int
procIndentLine(char * str)421 procIndentLine (char *str)
422 {
423 char token[MAX_TAGLEN+1] = "",
424      value[MAX_CFGLINELEN+1] = "";
425 char *p;
426 int width, fieldnr;
427 
428    if ((p = strchr(str, ':')) == NULL) {
429       if (prtToStd)
430 	 fprintf(stderr, "bibview: illegal [Indent] format: %s\n", str);
431       return(OK);
432    }
433 
434    *p = '\0';
435    strcpy(token, str);
436    glbTrimString(token);
437    strcpy(value, p+1);
438    glbTrimString(value);
439    strlower(token);
440    if (strcmp(token, STR_FLDINDENT) == 0)
441       fld_indent = atoi(value);
442    else if (strcmp(token, STR_CONTINDENT) == 0)
443       cont_indent = atoi(value);
444    else if (strcmp(token, STR_NEWLINEINDENT) == 0)
445       newline_indent = atoi(value);
446    else if (strcmp(token, STR_MAXLINELEN) == 0)
447       max_linelen = atoi(value);
448    else {
449       if (prtToStd)
450 	 fprintf(stderr,
451 	 "bibview: Illegal indentation information %s in config file.\n", str);
452    }
453    if (fld_indent < 0)
454       fld_indent = 0;
455    if (newline_indent < 0)
456       newline_indent = 0;
457    if (max_linelen < 20)
458       max_linelen = 20;
459    return(OK);
460 }
461 
462 
463 /*********************************************************************/
464 /* procPredefLine:                                                   */
465 /*    Process line containing predefined data for a field            */
466 /*********************************************************************/
467 static int
procPredefLine(char * str)468 procPredefLine (char *str)
469 {
470 char field[MAX_TAGLEN+1] = "",
471      data[MAX_CFGLINELEN+1] = "";
472 ListNode **lnp;
473 char *p;
474 int found, i;
475 
476    found = 0;
477    if ((p = strchr(str, ':')) == NULL) {
478       if (prtToStd)
479 	 fprintf(stderr, "bibview: illegal [Predef] format: %s\n", str);
480       return(OK);
481    }
482 
483    *p = '\0';
484    strcpy(field, str);
485    glbTrimString(field);
486    strcpy(data, p+1);
487    glbTrimString(data);
488    if (strcmp(strlower(field), "allfields") == 0) {
489       found = 1;
490       lnp = &predefLst.allfields;
491       }
492    else if (strcmp(strlower(field), "cardtype") == 0) {
493       found = 1;
494       lnp = &predefLst.bibtype;
495       }
496    else if (strcmp(strlower(field), "mainkey") == 0) {
497       found = 1;
498       lnp = &predefLst.mainkey;
499       }
500    else
501      for (i=0; i<max_fields; i++)
502        if ((!found) && strcmp(field, glbFldToName(i)) == 0){
503 	  found = 1;
504 	  lnp = &predefLst.field[i];
505 	  }
506    if (!found) {
507       if (prtToStd)
508 	 fprintf(stderr, "bibview: illegal field %s in config file.\n", field);
509       return(OK);
510    }
511 
512    dbtListAppend(lnp, data);
513    return(OK);
514 }
515 
516 
517 /*********************************************************************/
518 /* procUserFldLine:                                                  */
519 /*    Process line containing user defined field for a card type     */
520 /*********************************************************************/
521 static int
procUserFldLine(char * str)522 procUserFldLine (char *str)
523 {
524 char type[MAX_TAGLEN+1] = "",
525      data[MAX_CFGLINELEN+1] = "";
526 CardType cardtype;
527 char *p;
528 int i;
529 
530    if ((p = strchr(str, ':')) == NULL) {
531       if (prtToStd)
532 	 fprintf(stderr, "bibview: illegal [UserFields] format: %s\n", str);
533       return(OK);
534    }
535 
536    *p = '\0';
537    strcpy(type, str);
538    glbTrimString(type);
539    strcpy(data, p+1);
540    glbTrimString(data);
541    strlower(type);
542    strlower(data);
543    i=0;
544    while ((data[i] != '\0') && (!isspace(data[i])))
545       i++;
546    if (isspace(data[i]))
547       data[i] = '\0';
548    if (strcmp(type, "all") == 0) {
549       for (i = 0; i < MAX_BIBTEX_TYPES+1; i++)
550 	 dbtListAppend(&userDefFlds[i], data);
551    }
552    else if ((cardtype = glbNameToType(type)) != -1)
553       dbtListAppend(&userDefFlds[cardtype], data);
554    else {
555       if (prtToStd)
556 	 fprintf(stderr, "bibview: illegal type %s in config file.\n",
557 			 type);
558    }
559 
560    return(OK);
561 }
562 
563 
564 /*********************************************************************/
565 /* procLatexHeadLine:                                                */
566 /*    Process line containing a line of LaTeX-Header                 */
567 /*********************************************************************/
568 static int
procLatexHeadLine(char * str)569 procLatexHeadLine (char *str)
570 {
571 int linelen;
572 
573    linelen = strlen(str);
574    if (latexHeader) {
575       latexHeaderLen += linelen + 1;
576       latexHeader = (char *)XtRealloc(latexHeader, latexHeaderLen);
577       strcat(latexHeader, str);
578       strcat(latexHeader, "\n");
579    }
580    else {
581       latexHeaderLen = linelen + 2;
582       latexHeader = (char *)XtMalloc(latexHeaderLen);
583       strcpy(latexHeader, str);
584       strcat(latexHeader, "\n");
585    }
586 
587    return(OK);
588 }
589 
590 
591 /*********************************************************************/
592 /* procLatexFootLine:                                                */
593 /*    Process line containing a line of LaTeX-Footer                 */
594 /*********************************************************************/
595 static int
procLatexFootLine(char * str)596 procLatexFootLine (char *str)
597 {
598 int linelen;
599 
600    linelen = strlen(str);
601    if (latexFooter) {
602       latexFooterLen += linelen + 1;
603       latexFooter = (char *)XtRealloc(latexFooter, latexFooterLen);
604       strcat(latexFooter, str);
605       strcat(latexFooter, "\n");
606    }
607    else {
608       latexFooterLen = linelen + 2;
609       latexFooter = (char *)XtMalloc(latexFooterLen);
610       strcpy(latexFooter, str);
611       strcat(latexFooter, "\n");
612    }
613 
614    return(OK);
615 }
616 
617 
618 /*********************************************************************/
619 /* procDefaultDirLine:                                               */
620 /*    Process line containing the Default Directory                  */
621 /*********************************************************************/
622 Errcode
procDefaultDirLine(char * str)623 procDefaultDirLine (char *str)
624 
625 {
626 struct stat fstats;
627 int status;
628 char defdir[MAX_TAGLEN+1] = "";
629 
630    strcpy(defdir, str);
631    glbTrimString(defdir);
632 
633    status = stat(defdir, &fstats);
634 
635    if (status != -1 && fstats.st_mode & S_IFDIR)
636       if  (access(defdir, R_OK) == 0)
637         strcpy(actual_path, defdir);
638 
639    return(OK);
640 }
641 
642 /*********************************************************************/
643 /* procStyleFileLine:                                                */
644 /*    Process line containing the Default Style File                 */
645 /*********************************************************************/
646 static int
procStyleFileLine(char * str)647 procStyleFileLine (char *str)
648 
649 {
650 char stfile[MAX_TAGLEN+1] = "";
651 
652    strcpy(stfile, str);
653    glbTrimString(stfile);
654 
655    strcpy(style_file, stfile);
656 
657    return(OK);
658 }
659 
660 /*********************************************************************/
661 /* procSortedByTags:                                                 */
662 /*    Process line containing Default how list is sorted	     */
663 /*********************************************************************/
664 static int
procSortedByLine(char * str)665 procSortedByLine (char *str)
666 
667 {
668 char sortfield[MAX_TAGLEN+1] = "";
669 FieldName i;
670 
671    strcpy(sortfield,str);
672    glbTrimString(sortfield);
673 
674    if (!strncmp(strlower(sortfield), "type", 4))
675       sortedby = SORT_TYPE;
676    else if (!strncmp(strlower(sortfield), "mainkey", 7))
677       sortedby = SORT_MAINKEY;
678    else if ((i=glbNameToField(strlower(sortfield))) != -1)
679       sortedby = i;
680    else {
681       if (max_fields == MAX_FIELDS){
682          fprintf(stderr,
683 	      "bibview: too many new fields in config file.\n");
684          return(OK);
685 	 }
686       fieldNames[max_fields] = XtCalloc(strlen(sortfield)+1, sizeof(char));
687       strcpy(fieldNames[max_fields], sortfield);
688       sortedby = max_fields;
689       max_fields++;
690       }
691    return(OK);
692 }
693 
694 /*********************************************************************/
695 /* procTypeLine:                                                     */
696 /*    Process line type definition                                   */
697 /*********************************************************************/
698 static int
procTypeLine(char * str)699 procTypeLine (char *str)
700 {
701 char field[MAX_TAGLEN+1] = "",
702      data[MAX_CFGLINELEN+1] = "";
703 char *p;
704 int found, i, type, fieldnr;
705 
706    found = 0;
707    if ((p = strchr(str, ':')) == NULL) {
708       if (prtToStd)
709 	 fprintf(stderr, "bibview: illegal [Types] format: %s\n", str);
710       return(OK);
711    }
712 
713    *p = '\0';
714    strcpy(field, str);
715    glbTrimString(field);
716    strcpy(data, p+1);
717    glbTrimString(data);
718    strlower(field);
719    strlower(data);
720    i=0;
721    while ((data[i] != '\0') && (!isspace(data[i])))
722       i++;
723    if (isspace(data[i]))
724       data[i] = '\0';
725    if (field[0] == 't'){
726       found = 1;
727       if (strcmp(data, "all") == 0)
728 	 akttype = -1;
729       else if ((type = glbNameToType(data)) != -1){
730 	 if (field[1] == 'c'){
731 	    for (i=0; i<MAX_FIELDS; i++){
732 	       standardfields[type][i] = '0';
733 	       requiredfields[type][i] = '0';
734 	       }
735 	    standardfields[type][nannote] = '1';
736 	    }
737          akttype = type;
738 	 }
739       else {
740 	 if (max_bibtex_types == MAX_BIBTEX_TYPES){
741 	    fprintf(stderr,
742 	      "bibview: too many type definitions in config file.\n");
743             return(OK);
744 	    }
745 	 if (field[1] == 'c'){
746 	    for (i=0; i<MAX_FIELDS; i++){
747 	       standardfields[max_bibtex_types][i] = '0';
748 	       requiredfields[max_bibtex_types][i] = '0';
749 	       }
750 	    }
751 	 standardfields[max_bibtex_types][nannote] = '1';
752 	 cardNames[max_bibtex_types] = XtCalloc(strlen(data)+1, sizeof(char));
753 	 strcpy(cardNames[max_bibtex_types], data);
754          akttype = max_bibtex_types;
755 	 max_bibtex_types++;
756 	 }
757       }
758    else if (strcmp(field, "f") == 0) {
759       found = 1;
760       if ((fieldnr = glbNameToField(data)) != -1){
761 	 if (akttype == -1){
762 	    for (i=0; i<max_bibtex_types; i++)
763 	       standardfields[i][fieldnr] = '1';
764             }
765          else
766 	    standardfields[akttype][fieldnr] = '1';
767 	 }
768       else {
769 	 if (max_fields == MAX_FIELDS){
770 	    fprintf(stderr,
771 	      "bibview: too many new fields in config file.\n");
772             return(OK);
773 	    }
774 	 fieldNames[max_fields] = XtCalloc(strlen(data)+1, sizeof(char));
775 	 strcpy(fieldNames[max_fields], data);
776 	 is_search_field[max_fields] = '1';
777 	 if (akttype == -1){
778 	    for (i=0; i<max_bibtex_types; i++)
779 	       standardfields[i][max_fields] = '1';
780             }
781          else
782 	    standardfields[akttype][max_fields] = '1';
783 	 max_fields++;
784 	 }
785       }
786    else if (strcmp(strlower(field), "rf") == 0) {
787       found = 1;
788       if ((fieldnr = glbNameToField(data)) != -1){
789 	 if (akttype == -1){
790 	    for (i=0; i<max_bibtex_types; i++){
791 	       standardfields[i][fieldnr] = '1';
792 	       requiredfields[i][fieldnr] = '1';
793 	       }
794             }
795          else {
796 	    standardfields[akttype][fieldnr] = '1';
797 	    requiredfields[akttype][fieldnr] = '1';
798 	    }
799 	 }
800       else {
801 	 if (max_fields == MAX_FIELDS){
802 	    fprintf(stderr,
803 	      "bibview: too many new fields in config file.\n");
804             return(OK);
805 	    }
806 	 fieldNames[max_fields] = XtCalloc(strlen(data)+1, sizeof(char));
807 	 strcpy(fieldNames[max_fields], data);
808 	 if (akttype == -1){
809 	    for (i=0; i<max_bibtex_types; i++){
810 	       standardfields[i][max_fields] = '1';
811 	       requiredfields[i][max_fields] = '1';
812 	       }
813             }
814          else {
815 	    standardfields[akttype][max_fields] = '1';
816 	    requiredfields[akttype][max_fields] = '1';
817 	    }
818 	 max_fields++;
819 	 }
820       }
821 
822    if (!found) {
823       if (prtToStd)
824 	 fprintf(stderr, "bibview: illegal type %s in config file.\n", field);
825       return(OK);
826    }
827 
828    return(OK);
829 }
830 
831 
832 /*********************************************************************/
833 /* procSortFieldLine:                                                */
834 /*    Process fields for sorting                                     */
835 /*********************************************************************/
836 static int
procSortFieldLine(char * str)837 procSortFieldLine (char *str)
838 {
839 char field[MAX_TAGLEN+1] = "",
840      data[MAX_CFGLINELEN+1] = "";
841 char *p;
842 int i, type, fieldnr;
843 
844    p = strchr(str, ':');
845    if (p!=NULL){
846       *p = '\0';
847       strcpy(field, str);
848       glbTrimString(field);
849       strcpy(data, p+1);
850       glbTrimString(data);
851       strlower(field);
852       strlower(data);
853       }
854    else{
855       strcpy(field, strlower(str));
856       strcpy(data, "");
857       glbTrimString(field);
858       }
859    if (strcmp(field, "$clear$")==0)
860       for (i=0; i<MAX_FIELDS; i++)
861          sort_field[i] = '0';
862    else if ((fieldnr = glbNameToField(field)) != -1){
863       if (data[0] == 'n')
864          sort_field[fieldnr] = 'n';
865       else if (data[0] == 'd')
866          sort_field[fieldnr] = 'd';
867       else
868          sort_field[fieldnr] = '1';
869       }
870    else {
871       if (max_fields == MAX_FIELDS){
872 	    fprintf(stderr,
873 	      "bibview: too many new fields in [SortField] part.\n");
874             return(OK);
875 	    }
876       fieldNames[max_fields] = XtCalloc(strlen(field)+1, sizeof(char));
877       strcpy(fieldNames[max_fields], strlower(field));
878       if (data[0] == 'n')
879          sort_field[max_fields] = 'n';
880       else if (data[0] == 'd')
881          sort_field[max_fields] = 'd';
882       else
883          sort_field[max_fields] = '1';
884       max_fields++;
885    }
886 
887    return(OK);
888 }
889 
890 
891 /*********************************************************************/
892 /* procSearchFieldLine:                                              */
893 /*    Process fields for sorting                                     */
894 /*********************************************************************/
895 static int
procSearchFieldLine(char * str)896 procSearchFieldLine (char *str)
897 {
898 char field[MAX_TAGLEN+1] = "";
899 int i, fieldnr;
900 
901    strcpy(field, strlower(str));
902    glbTrimString(field);
903    i=0;
904    while ((field[i] != '\0') && (!isspace(field[i])))
905       i++;
906    if (isspace(field[i]))
907       field[i] = '\0';
908    if (strcmp(field, "$clear$")==0)
909       for (i=0; i<MAX_FIELDS; i++)
910          is_search_field[i] = '0';
911    else if ((fieldnr = glbNameToField(field)) != -1)
912       is_search_field[fieldnr] = '1';
913    else {
914       if (max_fields == MAX_FIELDS){
915 	    fprintf(stderr,
916 	      "bibview: too many new fields in [SearchField] part.\n");
917             return(OK);
918 	    }
919       fieldNames[max_fields] = XtCalloc(strlen(field)+1, sizeof(char));
920       strcpy(fieldNames[max_fields], strlower(field));
921       is_search_field[max_fields] = '1';
922       max_fields++;
923    }
924 
925    return(OK);
926 }
927 
928 
929 /*********************************************************************/
930 /* procAnnoteFieldLine:                                              */
931 /*    Process line for name of annote field                          */
932 /*********************************************************************/
933 static int
procAnnoteFieldLine(char * str)934 procAnnoteFieldLine (char *str)
935 {
936 char field[MAX_TAGLEN+1] = "";
937 int fieldnr;
938 
939    strcpy(field, strlower(str));
940    glbTrimString(field);
941    if (fieldNames[nannote] != NULL){
942       XtFree((char *) fieldNames[nannote]);
943       }
944    fieldNames[nannote] = XtCalloc(strlen(field)+1, sizeof(char));
945    strcpy(fieldNames[nannote], field);
946 
947    return(OK);
948 }
949 
950 
951 /*********************************************************************/
952 /* procListFieldLine:                                                */
953 /*    Process fields for sorting                                     */
954 /*********************************************************************/
955 static int
procListFieldLine(char * str)956 procListFieldLine (char *str)
957 {
958 char field[MAX_TAGLEN+1] = "",
959      data[MAX_CFGLINELEN+1] = "";
960 char *p;
961 int width, fieldnr;
962 
963    if ((p = strchr(str, ':')) == NULL) {
964       if (prtToStd)
965 	 fprintf(stderr, "bibview: illegal [ListFields] format: %s\n", str);
966       return(OK);
967    }
968 
969    *p = '\0';
970    strcpy(field, str);
971    glbTrimString(field);
972    strcpy(data, p+1);
973    glbTrimString(data);
974    strlower(field);
975    strlower(data);
976 
977    if ((width = atoi(data)) <= 0){
978       fprintf(stderr,
979         "bibview: illegal width in field %s of [ListFields] part.\n", field);
980       return(OK);
981       }
982    if (strcmp(field, "mainkey") == 0)
983       list_layout->field[list_layout->number] = -1;
984    else if (strcmp(field, "cardtype") == 0)
985       list_layout->field[list_layout->number] = -2;
986    else if ((fieldnr = glbNameToField(field)) != -1)
987       list_layout->field[list_layout->number] = fieldnr;
988    else {
989       if (max_fields == MAX_FIELDS){
990 	    fprintf(stderr,
991 	      "bibview: too many new fields in [ListFields] part.\n");
992             return(OK);
993 	    }
994       fieldNames[max_fields] = XtCalloc(strlen(field)+1, sizeof(char));
995       strcpy(fieldNames[max_fields], strlower(field));
996       list_layout->field[list_layout->number] = max_fields;
997       max_fields++;
998    }
999    list_layout->width[list_layout->number] = width;
1000    list_layout->number++;
1001 
1002    return(OK);
1003 }
1004 
1005