]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/global/lib/conf.c
This commit was generated by cvs2svn to compensate for changes in r55099,
[FreeBSD/FreeBSD.git] / contrib / global / lib / conf.c
1 /*
2  * Copyright (c) 1996, 1997, 1998 Shigio Yamaguchi. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  * 3. All advertising materials mentioning features or use of this software
13  *    must display the following acknowledgement:
14  *      This product includes software developed by Shigio Yamaguchi.
15  * 4. Neither the name of the author nor the names of any co-contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *      conf.c                                  30-Jun-98
32  *
33  */
34 #include <sys/param.h>
35 #include <assert.h>
36 #include <ctype.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "conf.h"
41 #include "die.h"
42 #include "gparam.h"
43 #include "locatestring.h"
44 #include "makepath.h"
45 #include "mgets.h"
46 #include "strbuf.h"
47 #include "strmake.h"
48 #include "test.h"
49 /*
50  * Access library for gtags.conf (.gtagsrc).
51  * File format is a subset of XXXcap (termcap, printcap) file.
52  */
53 #define GTAGSCONF       "/etc/global.conf"
54 #define GTAGSRC         ".globalrc"
55 #define DEFAULTLABEL    "default"
56 static FILE     *fp;
57 static char     *line;
58 static int      allowed_nest_level = 8;
59 static int      opened;
60
61 static void     trim __P((char *));
62 static char     *readrecord __P((const char *));
63 static void     includelabel __P((STRBUF *, const char *, int));
64
65 static void
66 trim(l)
67 char    *l;
68 {
69         char    *f, *b;
70         int     colon = 0;
71
72         for (f = b = l; *f; f++) {
73                 if (colon && isspace(*f))
74                         continue;
75                 colon = 0;
76                 if ((*b++ = *f) == ':')
77                         colon = 1;
78         }
79         *b = 0;
80 }
81 static char     *
82 readrecord(label)
83 const char *label;
84 {
85         char    *p, *q;
86
87         rewind(fp);
88         while ((p = mgets(fp, NULL, MGETS_CONT|MGETS_SKIPCOM)) != NULL) {
89                 trim(p);
90                 for (;;) {
91                         if ((q = strmake(p, "|:")) == NULL)
92                                 die1("illegal configuration file format (%s).", p);
93                         if (!strcmp(label, q)) {
94                                 if (!(p = locatestring(p, ":", MATCH_FIRST)))
95                                         die("illegal configuration file format.");
96                                 p = strdup(p);
97                                 if (!p)
98                                         die("short of memory.");
99                                 return p;
100                         }
101                         p += strlen(q);
102                         if (*p == ':')
103                                 break;
104                         else if (*p == '|')
105                                 p++;
106                         else
107                                 assert(0);
108                 }
109         }
110         return NULL;
111 }
112 static  void
113 includelabel(sb, label, level)
114 STRBUF  *sb;
115 const char *label;
116 int     level;
117 {
118         char    *savep, *p, *q;
119
120         if (++level > allowed_nest_level)
121                 die("nested include= (or tc=) over flow.");
122         if (!(savep = p = readrecord(label)))
123                 die1("label '%s' not found.", label);
124         while ((q = locatestring(p, ":include=", MATCH_FIRST)) || (q = locatestring(p, ":tc=", MATCH_FIRST))) {
125                 char    inclabel[MAXPROPLEN+1], *c = inclabel;
126
127                 strnputs(sb, p, q - p);
128                 q = locatestring(q, "=", MATCH_FIRST) + 1;
129                 while (*q && *q != ':')
130                         *c++ = *q++;
131                 *c = 0;
132                 includelabel(sb, inclabel, level);
133                 p = q;
134         }
135         strputs(sb, p);
136         free(savep);
137 }
138 /*
139  * configpath: get path of configuration file.
140  */
141 char *
142 configpath() {
143         static char config[MAXPATHLEN+1];
144         char *p;
145
146         if ((p = getenv("GTAGSCONF")) != NULL) {
147                 if (!test("r", p))
148                         config[0] = 0;
149                 else
150                         strcpy(config, p);
151         } else if ((p = getenv("HOME")) && test("r", makepath(p, GTAGSRC)))
152                 strcpy(config, makepath(p, GTAGSRC));
153         else if (test("r", GTAGSCONF))
154                 strcpy(config, GTAGSCONF);
155         else
156                 config[0] = 0;
157         return config;
158 }
159 /*
160  * openconf: load configuration file.
161  *
162  *      go)     line    specified entry
163  */
164 void
165 openconf()
166 {
167         const char *label, *config;
168         STRBUF  *sb;
169
170         assert(opened == 0);
171
172         config = configpath();
173         /*
174          * if configuration file is not found, default values are set
175          * for upper compatibility.
176          */
177         if (*config == 0) {
178                 sb = stropen();
179                 strputs(sb, "suffixes=c,h,y,s,S,java:");
180                 strputs(sb, "skip=y.tab.c,y.tab.h,SCCS/,RCS/,CVS/:");
181                 strputs(sb, "format=standard:");
182                 strputs(sb, "extractmethod:");
183                 strputs(sb, "GTAGS=gctags %s:");
184                 strputs(sb, "GRTAGS=gctags -r %s:");
185                 strputs(sb, "GSYMS=gctags -s %s:");
186                 line = strdup(strvalue(sb));
187                 if (!line)
188                         die("short of memory.");
189                 strclose(sb);
190                 opened = 1;
191                 return;
192         }
193         if ((label = getenv("GTAGSLABEL")) == NULL)
194                 label = "default";
195         if (!(fp = fopen(config, "r")))
196                 die1("cannot open '%s'.", config);
197         sb = stropen();
198         includelabel(sb, label, 0);
199         line = strdup(strvalue(sb));
200         strclose(sb);
201         fclose(fp);
202         opened = 1;
203         return;
204 }
205 /*
206  * getconfn: get property number
207  *
208  *      i)      name    property name
209  *      o)      num     value (if not NULL)
210  *      r)              1: found, 0: not found
211  */
212 int
213 getconfn(name, num)
214 const char *name;
215 int     *num;
216 {
217         char    *p;
218         char    buf[MAXPROPLEN+1];
219
220         if (!opened)
221                 openconf();
222         sprintf(buf, ":%s#", name);
223         if ((p = locatestring(line, buf, MATCH_FIRST)) != NULL) {
224                 p += strlen(buf);
225                 if (num != NULL)
226                         *num = atoi(p);
227                 return 1;
228         }
229         return 0;
230 }
231 /*
232  * getconfs: get property string
233  *
234  *      i)      name    property name
235  *      o)      sb      string buffer (if not NULL)
236  *      r)              1: found, 0: not found
237  */
238 int
239 getconfs(name, sb)
240 const char *name;
241 STRBUF  *sb;
242 {
243         char    *p;
244         char    buf[MAXPROPLEN+1];
245         int     all = 0;
246         int     exist = 0;
247
248         if (!opened)
249                 openconf();
250         if (!strcmp(name, "suffixes") || !strcmp(name, "skip") || !strcmp(name, "reserved_words"))
251                 all = 1;
252         sprintf(buf, ":%s=", name);
253         p = line;
254         while ((p = locatestring(p, buf, MATCH_FIRST)) != NULL) {
255                 if (exist && sb)
256                         strputc(sb, ',');               
257                 exist = 1;
258                 for (p += strlen(buf); *p && *p != ':'; p++)
259                         if (sb)
260                                 strputc(sb, *p);
261                 if (!all)
262                         break;
263         }
264         /*
265          * It may be that these code should be moved to applications.
266          * But nothing cannot start without them.
267          */
268         if (!exist) {
269                 exist = 1;
270                 if (!strcmp(name, "suffixes")) {
271                         if (sb)
272                                 strputs(sb, "c,h,y,s,S,java");
273                 } else if (!strcmp(name, "skip")) {
274                         if (sb)
275                                 strputs(sb, "y.tab.c,y.tab.h,SCCS/,RCS/,CVS/");
276                 } else
277                         exist = 0;
278         }
279         return exist;
280 }
281 /*
282  * getconfb: get property bool value
283  *
284  *      i)      name    property name
285  *      r)              1: TRUE, 0: FALSE
286  */
287 int
288 getconfb(name)
289 const char *name;
290 {
291         char    *p;
292         char    buf[MAXPROPLEN+1];
293
294         if (!opened)
295                 openconf();
296         sprintf(buf, ":%s:", name);
297         if ((p = locatestring(line, buf, MATCH_FIRST)) != NULL)
298                 return 1;
299         return 0;
300 }
301 void
302 closeconf()
303 {
304         if (!opened)
305                 return;
306         free(line);
307         opened = 0;
308 }