w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cfg.c
Go to the documentation of this file.
1 /* cfg.c - Read config files and provide lookup routines
2 
3 Copyright (C) 1995-2002 The Free Software Foundation
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 This file is available from http://sourceforge.net/projects/latex2rtf/
20 
21 Authors:
22  1995-1997 Ralf Schlatterbeck
23  1998-2000 Georg Lehner
24  2001-2002 Scott Prahl
25 
26  * LEG200698 I would have prefered to make the reading of the language file
27  * separate, since the language is known some steps after reading the
28  * configuration files. Since the search functions rely on the index into
29  * configinfo this is not trivial. So I reread the language file to the array
30  * at the moment the name is known.
31 
32 */
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdarg.h>
38 #include <ctype.h>
39 
40 #include "main.h"
41 #include "convert.h"
42 #include "funct1.h"
43 #include "cfg.h"
44 #include "util.h"
45 
46 typedef struct ConfigInfoT {
47  char *filename;
52 
54 {
55  {"direct.cfg", NULL, 0, FALSE},
56  {"fonts.cfg", NULL, 0, FALSE},
57  {"ignore.cfg", NULL, 0, FALSE},
58  {"style.cfg", NULL, 0, FALSE},
59  {"english.cfg", NULL, 0, FALSE},
60 };
61 
62 #define CONFIG_SIZE (sizeof(configinfo) / sizeof(ConfigInfoT))
63 #define BUFFER_INCREMENT 1024
64 
65 char *ReadUptoMatch(FILE * infile, const char *scanchars);
66 
67 static int cfg_compare(ConfigEntryT ** el1, ConfigEntryT ** el2)
68 /****************************************************************************
69  * purpose: compare-function for bsearch
70  * params: el1, el2: Config Entries to be compared
71  ****************************************************************************/
72 {
73  return strcmp((*el1)->TexCommand, (*el2)->TexCommand);
74 }
75 
76 static FILE *
77 try_path(const char *path, const char *file)
78 /****************************************************************************
79  * purpose: append path to .cfg file name and open
80  return NULL upon failure,
81  return filepointer otherwise
82  ****************************************************************************/
83 {
84  char * both;
85  FILE * fp=NULL;
86  size_t lastchar;
87 
88  if (path==NULL || file == NULL) return NULL;
89 
90  diagnostics(4, "trying path=<%s> file=<%s>", path, file);
91 
92  lastchar = strlen(path);
93 
94  both = malloc(strlen(path) + strlen(file) + 2);
95  if (both == NULL)
96  diagnostics(ERROR, "Could not allocate memory for both strings.");
97 
98  strcpy(both, path);
99 
100  /* fix path ending if needed */
101  if (both[lastchar] != PATHSEP) {
102  both[lastchar] = PATHSEP;
103  both[lastchar+1] = '\0';
104  }
105 
106  strcat(both, file);
107  fp = fopen(both, "r");
108  free(both);
109  return fp;
110 }
111 
112 #ifdef KPATHSEA
113 #include <kpathsea/kpathsea.h>
114 #endif
115 
116 void *
117 open_cfg(const char *name, int quit_on_error)
118 /****************************************************************************
119 purpose: open config by trying multiple paths
120  ****************************************************************************/
121 {
122 #ifdef KPATHSEA
123  char *fpath;
124  FILE *f = NULL;
125 
126  diagnostics(3,"Open file in cfg directories <%s>",name);
127  fpath = kpse_find_file(name, kpse_program_text_format, 1);
128  if(fpath) {
129  f = fopen(fpath, "r");
130  free(fpath);
131  }
132  return f;
133 #else
134  char *env_path,*p,*p1;
135  char *lib_path;
136  FILE *fp;
137 
138  diagnostics(3,"Open file in cfg directories <%s>",name);
139 
140 /* try path specified on the line */
142  if (fp) return fp;
143 
144 /* try the environment variable RTFPATH */
145  p = getenv("RTFPATH");
146  if (p) {
147  env_path = strdup(p); /* create a copy to work with */
148  p = env_path;
149  while (p) {
150  p1 = strchr(p, ENVSEP);
151  if (p1) *p1 = '\0';
152 
153  fp=try_path(p, name);
154  if (fp) {free(env_path); return fp;}
155 
156  p= (p1) ? p1+1 : NULL;
157  }
158  free(env_path);
159  }
160 
161 /* last resort. try CFGDIR */
162  lib_path = strdup(CFGDIR);
163  if (lib_path) {
164  p = lib_path;
165  while (p) {
166  p1 = strchr(p, ENVSEP);
167  if (p1) *p1 = '\0';
168 
169  fp=try_path(p, name);
170  if (fp) {free(lib_path); return fp;}
171 
172  p= (p1) ? p1+1 : NULL;
173  }
174  free(lib_path);
175  }
176 
177 /* failed ... give some feedback */
178  if (quit_on_error) {
179  diagnostics(WARNING__, "Cannot open the latex2rtf .cfg files");
180  diagnostics(WARNING__, "Locate the directory containing the .cfg files and");
181  diagnostics(WARNING__, " (1) define the environment variable RTFPATH, *or*");
182  diagnostics(WARNING__, " (2) use command line path option \"-P /path/to/cfg/file\", *or*");
183  diagnostics(WARNING__, " (3) recompile latex2rtf with CFGDIR defined properly");
184  diagnostics(WARNING__, "Current RTFPATH: %s", getenv("RTFPATH"));
185  diagnostics(WARNING__, "Current CFGDIR: %s", CFGDIR);
186  diagnostics(ERROR, " Giving up. Please don't hate me.");
187  }
188  return NULL;
189 #endif
190 }
191 
192 static size_t
193 read_cfg(FILE * cfgfile, ConfigEntryT *** pointer_array, bool do_remove_backslash)
194 /****************************************************************************
195  * purpose: Read config file and provide sorted lookup table
196  ****************************************************************************/
197 {
198  size_t bufindex = 0, bufsize = 0;
199  char *line, *cmdend;
200 
201  if (*pointer_array == NULL) {
202  *pointer_array = malloc(BUFFER_INCREMENT * sizeof(char *));
204  if (*pointer_array == NULL)
205  diagnostics(ERROR,"Cannot allocate memory for pointer list");
206  }
207 
208  while ((line = ReadUptoMatch(cfgfile, "\n")) != NULL) {
209 
210  /* skip newline */
211  getc(cfgfile);
212 
213  /* Skip leading white space */
214  while (isspace((unsigned char) *line))
215  line++;
216 
217  /* Skip comment line */
218  if (*line == '#')
219  continue;
220 
221  /* Skip blank line */
222  if (*line == '\0')
223  continue;
224 
225  /* Find period that terminates command */
226  cmdend = strrchr(line, '.');
227  if (cmdend == NULL)
228  diagnostics(ERROR,"Bad config file, missing final period\nBad line is \"%s\"", line);
229 
230  /* Replace period with NULL */
231  *cmdend = '\0';
232 
233  /* Skip backslash if specified */
234  if (do_remove_backslash) {
235  if (*line != '\\')
236  diagnostics(ERROR,"Bad config file, missing initial'\\'\nBad line is\"%s\"", line);
237  else
238  line++;
239  }
240 
241  /* resize buffer if needed */
242  if (bufindex >= bufsize) {
244  *pointer_array = realloc(*pointer_array, bufsize * sizeof(char *));
245  if (*pointer_array == NULL)
246  diagnostics(ERROR,"Cannot allocate memory for pointer list");
247  }
248 
249  /* find start of definition */
250  line=strdup(line);
251  cmdend = strchr(line, ',');
252  if (cmdend == NULL)
253  diagnostics(ERROR,"Bad config file, missing ',' between elements\nBad line is\"%s\"", line);
254 
255  /* terminate command */
256  *cmdend = '\0';
257 
258  (*pointer_array)[bufindex] = malloc(sizeof(ConfigEntryT));
259 
260  if ((*pointer_array)[bufindex] == NULL)
261  diagnostics(ERROR,"Cannot allocate memory for config entry");
262 
263  (*pointer_array)[bufindex]->TexCommand = line;
264  (*pointer_array)[bufindex]->RtfCommand = cmdend+1;
265  bufindex++;
266  }
267 
268  qsort(*pointer_array
269  ,bufindex
270  ,sizeof(**pointer_array)
271  ,(fptr) cfg_compare
272  );
273 
274  return bufindex;
275 }
276 
277 void
278 ReadCfg(void)
279 /****************************************************************************
280  * purpose: opens config-files & reads them
281  * globals: Direct-, Font- IgnoreArray[Size/Root]
282  ****************************************************************************/
283 {
284  size_t i;
285  FILE *fp;
286  char *fname;
287 
288  for (i = 0; i < CONFIG_SIZE; i++) {
290  fp = (FILE *) open_cfg(fname, TRUE);
291  diagnostics(4,"reading config file %s", fname);
292 
294  = read_cfg(fp
295  ,&(configinfo[i].config_info)
296  ,configinfo[i].remove_leading_backslash
297  );
298  (void) fclose(fp);
299  }
300 }
301 
302 static ConfigEntryT **
303 search_rtf(const char *theTexCommand, int WhichCfg)
304 /****************************************************************************
305  * purpose: search theTexCommand in specified config data and return
306  * pointer to the data
307  ****************************************************************************/
308 {
309  ConfigEntryT compare_item;
310  ConfigEntryT *compare_ptr;
311 
312  compare_item.TexCommand = theTexCommand;
313  compare_item.RtfCommand = "";
314  compare_ptr = &compare_item;
315 
316  assert(WhichCfg >= 0 && (size_t) WhichCfg < CONFIG_SIZE);
317  assert(configinfo[WhichCfg].config_info != NULL);
318 
319  return (ConfigEntryT **) bsearch
320  (&compare_ptr
321  ,configinfo[WhichCfg].config_info
322  ,configinfo[WhichCfg].config_info_size
323  ,sizeof(compare_ptr)
324  ,(fptr) cfg_compare
325  );
326 }
327 
328 int
329 SearchRtfIndex(const char *theTexCommand, int WhichCfg)
330 /****************************************************************************
331  * purpose: search theTexCommand in a specified config data and return
332  * index
333  ****************************************************************************/
334 {
335  ConfigEntryT **help = search_rtf(theTexCommand, WhichCfg);
336  if (help == NULL) {
337  return 0;
338  }
339  /* LEG210698*** subtraction of two ConfigEntryT pointers */
340  return help - configinfo[WhichCfg].config_info;
341 }
342 
343 char *
344 SearchRtfCmd(const char *theTexCommand, int WhichCfg)
345 /****************************************************************************
346  * purpose: search theTexCommand in a specified config data and return
347  * pointer to the data
348  ****************************************************************************/
349 {
350  ConfigEntryT **help;
351 
352  help = search_rtf(theTexCommand, WhichCfg);
353 
354  if (help == NULL)
355  return NULL;
356  else
357  return (char *)(*help)->RtfCommand;
358 }
359 
360 ConfigEntryT **
361 CfgStartIterate(int WhichCfg)
362 /****************************************************************************
363  * purpose: Start iterating of configuration data
364  ****************************************************************************/
365 {
366  return NULL;
367 }
368 
369 ConfigEntryT **
370 CfgNext(int WhichCfg, ConfigEntryT ** last)
371 /****************************************************************************
372  * purpose: Get the next entry from specified configuration data
373  ****************************************************************************/
374 {
375  if (last == NULL) {
376  return (ConfigEntryT **) configinfo[WhichCfg].config_info;
377  }
378  last++;
379  if (last
380  > (ConfigEntryT **) configinfo[WhichCfg].config_info
381  + configinfo[WhichCfg].config_info_size
382  - 1
383  ) {
384  return NULL;
385  }
386  return last;
387 }
388 
389 /****************************************************************************
390  * opens and reads the language configuration file named in lang
391 
392 Opens language file & builds a search tree for the translation of
393 "Hardcoded" latex headings like "Part", "References", ...
394 The file format is:
395 LATEXTOKEN,Translation.
396 
397  ****************************************************************************/
398 void
400 {
401  FILE *fp;
402  char *langfn;
403 
404  langfn = malloc(strlen(lang) + strlen(".cfg") + 1);
405  if (langfn == NULL)
406  diagnostics(ERROR, "Could not allocate memory for language filename.");
407 
408  strcpy(langfn, lang);
409  strcat(langfn, ".cfg");
410 
411  fp = (FILE *) open_cfg(langfn, TRUE);
412  free(langfn);
413 
415  = read_cfg(fp,
416  &(configinfo[LANGUAGE_A].config_info),
417  configinfo[LANGUAGE_A].remove_leading_backslash);
418 
419  (void) fclose(fp);
420 }
421 
422 /****************************************************************************
423  purpose : returns a pointer to the Printout name of a Heading, since
424  this is read from a language file it provides translation
425  capability.
426  params : name, name of heading.
427  ****************************************************************************/
428 void
430 {
431  char *s = SearchRtfCmd(name, LANGUAGE_A);
432  if (s != NULL)
433  ConvertString(s);
434 }
435 
436 static char *buffer = NULL;
437 static size_t bufsize = 0;
438 
439 #define CR (char) 0x0d
440 #define LF (char) 0x0a
441 
442 /*
443  * This function assumes there are no '\0' characters in the input.
444  * if there are any, they are ignored.
445  */
446 char *
447 ReadUptoMatch(FILE * infile, const char *scanchars)
448 {
449  size_t bufindex = 0;
450  int c;
451 
452  if (feof(infile) != 0)
453  return NULL;
454 
455  if (buffer == NULL) {
456  buffer = malloc(BUFFER_INCREMENT * sizeof(char));
457  if (buffer == NULL)
458  diagnostics(ERROR, "Cannot allocate memory for input buffer");
460  }
461 
462  while ((c = getc(infile)) != EOF ) {
463 
464  if (c == CR || c == LF)
465  c = '\n';
466 
467  if (strchr(scanchars, c))
468  break;
469 
470  if (c == (int) '\0')
471  continue;
472 
473  buffer[bufindex++] = (char) c;
474  if (bufindex >= bufsize) {
477  if (buffer == NULL)
478  diagnostics(ERROR,"Cannot allocate memory for input buffer");
479  }
480  }
481  buffer[bufindex] = '\0';
482  if (c != EOF)
483  ungetc(c, infile);
484 
485  return buffer;
486 }
void *__cdecl bsearch(void const *_Key, void const *_Base, size_t _NumOfElements, size_t _SizeOfElements, _CoreCrtNonSecureSearchSortCompareFunction _CompareFunction)
#define strdup
Definition: Utility.h:167
#define name
char * p1
Definition: bmpfont.h:62
static ConfigInfoT configinfo[]
Definition: cfg.c:53
void * open_cfg(const char *name, int quit_on_error)
Definition: cfg.c:117
#define LF
Definition: cfg.c:440
void ReadLanguage(char *lang)
Definition: cfg.c:399
char * SearchRtfCmd(const char *theTexCommand, int WhichCfg)
Definition: cfg.c:344
void ReadCfg(void)
Definition: cfg.c:278
static ConfigEntryT ** search_rtf(const char *theTexCommand, int WhichCfg)
Definition: cfg.c:303
ConfigEntryT ** CfgStartIterate(int WhichCfg)
Definition: cfg.c:361
char * ReadUptoMatch(FILE *infile, const char *scanchars)
Definition: cfg.c:447
#define CR
Definition: cfg.c:439
static FILE * try_path(const char *path, const char *file)
Definition: cfg.c:77
static size_t read_cfg(FILE *cfgfile, ConfigEntryT ***pointer_array, bool do_remove_backslash)
Definition: cfg.c:193
int SearchRtfIndex(const char *theTexCommand, int WhichCfg)
Definition: cfg.c:329
static size_t bufsize
Definition: cfg.c:437
#define CONFIG_SIZE
Definition: cfg.c:62
static int cfg_compare(ConfigEntryT **el1, ConfigEntryT **el2)
Definition: cfg.c:67
void ConvertBabelName(char *name)
Definition: cfg.c:429
ConfigEntryT ** CfgNext(int WhichCfg, ConfigEntryT **last)
Definition: cfg.c:370
struct ConfigInfoT ConfigInfoT
#define BUFFER_INCREMENT
Definition: cfg.c:63
static char * buffer
Definition: cfg.c:436
#define CFGDIR
Definition: cfg.h:8
#define LANGUAGE_A
Definition: cfg.h:5
int(* fptr)(const void *, const void *)
Definition: cfg.h:16
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
#define free(a)
Definition: decNumber.cpp:310
#define strrchr
Definition: detex.c:67
#define fopen
Definition: xxstdio.h:21
int strcmp()
Definition: coll.cpp:143
char * strcpy()
#define PATHSEP
Definition: dvidvi.c:105
const FcChar8 lang[6]
Definition: fcfreetype.c:56
static void
Definition: fpif.c:118
mpz_t * f
Definition: gen-fib.c:34
#define s
Definition: afcover.h:80
#define c(n)
Definition: gpos-common.c:150
#define strchr
Definition: gsftopk.c:59
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
static FILE * infile
Definition: rdjpgcom.c:61
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
#define EOF
Definition: afmparse.c:59
char * getenv()
#define ERROR(string)
Definition: error.h:36
#define fclose
Definition: debug.h:100
#define getc
Definition: line.c:39
@ kpse_program_text_format
Definition: types.h:142
void ConvertString(char *string)
Definition: convert.c:103
void diagnostics(int level, char *format,...)
Definition: main.c:469
char * g_config_path
Definition: main.c:101
#define WARNING__
Definition: main.h:32
#define malloc
Definition: alloca.c:91
#define qsort
Definition: includes.h:72
#define realloc
Definition: glob.c:206
#define fp
char * fname
Definition: plain2.c:121
logical lastchar
Definition: pmxab.c:132
static int32_t last
Definition: ppagelist.c:29
char line[1024]
Definition: process_score.c:29
#define isspace(ch)
Definition: utype.h:87
const char * TexCommand
Definition: cfg.h:20
const char * RtfCommand
Definition: cfg.h:21
ConfigEntryT ** config_info
Definition: cfg.c:48
size_t config_info_size
Definition: cfg.c:49
char * filename
Definition: cfg.c:47
bool remove_leading_backslash
Definition: cfg.c:50
Definition: utils.c:300
Definition: filedef.h:30
Definition: bdf.c:133
Definition: tpic.c:45
#define FILE
Definition: t1stdio.h:34
#define ungetc(c, f)
Definition: t1stdio.h:106
#define feof(f)
Definition: t1stdio.h:109
*job_name strlen((char *) job_name) - 4)