1268
|
1 /* cnf.c: read config files. |
|
2 |
|
3 Copyright (C) 1994 Karl Berry. |
|
4 |
|
5 This program is free software; you can redistribute it and/or modify |
|
6 it under the terms of the GNU General Public License as published by |
|
7 the Free Software Foundation; either version 2, or (at your option) |
|
8 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 |
1315
|
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
1268
|
18 |
|
19 #include <kpathsea/config.h> |
|
20 |
|
21 #include <kpathsea/c-fopen.h> |
|
22 #include <kpathsea/c-ctype.h> |
|
23 #include <kpathsea/cnf.h> |
|
24 #include <kpathsea/db.h> |
|
25 #include <kpathsea/hash.h> |
|
26 #include <kpathsea/line.h> |
|
27 #include <kpathsea/paths.h> |
|
28 #include <kpathsea/pathsearch.h> |
|
29 #include <kpathsea/tex-file.h> |
|
30 #include <kpathsea/variable.h> |
|
31 |
|
32 |
|
33 /* By using our own hash table, instead of the environment, we |
|
34 complicate variable expansion (because now we have to look in two |
|
35 places), but we don't bang so heavily on the system. DOS and System |
|
36 V have very limited environment space. Also, this way |
|
37 `kpse_init_format' can distinguish between values originating from |
|
38 the cnf file and ones from environment variables, which can be useful |
|
39 for users trying to figure out what's going on. */ |
|
40 #ifndef CNF_HASH_SIZE |
|
41 #define CNF_HASH_SIZE 751 |
|
42 #endif |
|
43 static hash_table_type cnf_hash; |
|
44 |
|
45 /* Do a single line in a cnf file: if it's blank or a comment, skip it. |
|
46 Otherwise, parse <variable>[.<program>] [=] <value>. Do |
|
47 this even if the <variable> is already set in the environment, since |
|
48 the envvalue might contain a trailing :, in which case we'll be |
|
49 looking for the cnf value. */ |
|
50 |
|
51 static void |
|
52 do_line P1C(string, line) |
|
53 { |
|
54 unsigned len; |
|
55 string start; |
|
56 string value, var; |
|
57 |
|
58 /* Skip leading whitespace. */ |
|
59 while (ISSPACE (*line)) |
|
60 line++; |
|
61 |
|
62 /* More to do only if we have non-comment material left. */ |
|
63 if (*line == 0 || *line == '%' || *line == '#') |
|
64 return; |
|
65 |
|
66 /* The variable name is everything up to the next space or = or `.'. */ |
|
67 start = line; |
|
68 while (!ISSPACE (*line) && *line != '=' && *line != '.') |
|
69 line++; |
|
70 |
|
71 /* `line' is now one character past the end of the variable name. */ |
|
72 len = line - start; |
|
73 var = xmalloc (len + 1); |
|
74 strncpy (var, start, len); |
|
75 var[len] = 0; |
|
76 |
|
77 /* If the variable is qualified with a program name, we might be |
|
78 ignoring it. */ |
|
79 while (ISSPACE (*line)) |
|
80 line++; |
|
81 if (*line == '.') |
|
82 { /* Skip spaces, then everything up to the next space or =. */ |
|
83 string prog; |
|
84 extern string program_invocation_short_name; /* must be set by main */ |
|
85 |
|
86 line++; |
|
87 while (ISSPACE (*line)) |
|
88 line++; |
|
89 start = line; |
|
90 while (!ISSPACE (*line) && *line != '=') |
|
91 line++; |
|
92 |
|
93 /* It's annoying to repeat all this, but making a tokenizing |
|
94 subroutine would be just as long and annoying. */ |
|
95 len = line - start; |
|
96 prog = xmalloc (len + 1); |
|
97 strncpy (prog, start, len); |
|
98 prog[len] = 0; |
|
99 |
|
100 /* If we are running `prog', fine; otherwise, we're done. */ |
|
101 assert (program_invocation_short_name); |
|
102 if (!STREQ (prog, program_invocation_short_name)) |
|
103 { |
|
104 free (var); |
|
105 free (prog); |
|
106 return; |
|
107 } |
|
108 } |
|
109 |
|
110 /* Skip whitespace, an optional =, more whitespace. */ |
|
111 while (ISSPACE (*line)) |
|
112 line++; |
|
113 if (*line == '=') |
|
114 { |
|
115 line++; |
|
116 while (ISSPACE (*line)) |
|
117 line++; |
|
118 } |
|
119 |
|
120 /* Everything up to the next whitespace or eol is the value. */ |
|
121 start = line; |
|
122 while (*line && !ISSPACE (*line)) |
|
123 line++; |
|
124 len = line - start; |
|
125 |
|
126 value = xmalloc (len + 1); |
|
127 strncpy (value, start, len); |
|
128 value[len] = 0; |
|
129 |
|
130 /* For cnf files, multiple values for a single variable make no sense, |
|
131 but instead of removing them, we'll just take the most recent in |
|
132 `kpse_cnf_get'. Thus, we are assuming here that `hash_insert' puts |
|
133 the most recent entries in first. */ |
|
134 hash_insert (&cnf_hash, var, value); |
|
135 |
|
136 /* We could check that anything remaining is preceded by a comment |
|
137 character, but let's not bother. */ |
|
138 } |
|
139 |
|
140 /* Read all the configuration files in the path. */ |
|
141 |
|
142 static void |
|
143 read_files P1H(void) |
|
144 { |
|
145 string *cnf_files; |
|
146 const_string cnf_path = kpse_init_format (kpse_cnf_format); |
|
147 |
|
148 cnf_hash = hash_create (CNF_HASH_SIZE); |
|
149 |
|
150 for (cnf_files = kpse_all_path_search (cnf_path, |
|
151 kpse_format_info[kpse_cnf_format].program); |
|
152 cnf_files && *cnf_files; cnf_files++) |
|
153 { |
|
154 string line; |
|
155 string cnf_filename = *cnf_files; |
|
156 FILE *cnf_file = xfopen (cnf_filename, FOPEN_R_MODE); |
|
157 |
|
158 while ((line = read_line (cnf_file)) != NULL) |
|
159 { |
|
160 do_line (line); |
|
161 free (line); |
|
162 } |
|
163 |
|
164 xfclose (cnf_file, cnf_filename); |
|
165 } |
|
166 |
|
167 /* After (*after*) reading the cnf files, expand the db directory, for |
|
168 use by `elt_in_db' in pathsearch.c. The default value of $TEXMF |
|
169 has to be able to get TEXMF from a cnf file, therefore in the |
|
170 `kpse_all_path_search' call above, we do not have DB_DIR. */ |
|
171 kpse_db_dir = kpse_var_expand (KPSE_DB_DIR); |
|
172 if (! *kpse_db_dir) |
|
173 kpse_db_dir = kpse_var_expand (DEFAULT_TEXMF); |
|
174 } |
|
175 |
|
176 /* Read the cnf files on the first call. Return the first value in the |
|
177 returned list -- this will be from the last-read cnf file. */ |
|
178 |
|
179 string |
|
180 kpse_cnf_get P1C(const_string, name) |
|
181 { |
|
182 string *ret_list; |
|
183 |
|
184 if (cnf_hash.size == 0) |
|
185 read_files (); |
|
186 |
|
187 ret_list = hash_lookup (cnf_hash, name); |
|
188 |
|
189 return ret_list ? *ret_list : NULL; |
|
190 } |