CTWM
Toggle main menu visibility
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/parse.c
Go to the documentation of this file.
1
/*
2
* Copyright 1988 by Evans & Sutherland Computer Corporation,
3
* Salt Lake City, Utah
4
* Portions Copyright 1989 by the Massachusetts Institute of Technology
5
* Cambridge, Massachusetts
6
*
7
* Copyright 1992 Claude Lecommandeur.
8
*/
9
10
/***********************************************************************
11
*
12
* $XConsortium: parse.c,v 1.52 91/07/12 09:59:37 dave Exp $
13
*
14
* parse the .twmrc file
15
*
16
* 17-Nov-87 Thomas E. LaStrange File created
17
* 10-Oct-90 David M. Sternlicht Storing saved colors on root
18
*
19
* Do the necessary modification to be integrated in ctwm.
20
* Can no longer be used for the standard twm.
21
*
22
* 22-April-92 Claude Lecommandeur.
23
*
24
***********************************************************************/
25
26
#include "
ctwm.h
"
27
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
#include <strings.h>
32
#ifdef USEM4
33
# include <sys/types.h>
34
# include <sys/wait.h>
35
#endif
36
37
#include "ctwm_atoms.h"
38
#include "
screen.h
"
39
#include "
parse.h
"
40
#include "
parse_int.h
"
41
#include "
deftwmrc.h
"
42
#ifdef SOUNDS
43
# include "
sound.h
"
44
#endif
45
46
#ifndef SYSTEM_INIT_FILE
47
#error "No SYSTEM_INIT_FILE set"
48
#endif
49
50
static
bool
ParseStringList
(
const
char
**sl);
51
52
/*
53
* With current bison, this is defined in the gram.tab.h, so this causes
54
* a warning for redundant declaration. With older bisons and byacc,
55
* it's not, so taking it out causes a warning for implicit declaration.
56
* A little looking around doesn't show any handy #define's we could use
57
* to be sure of the difference. This should quiet it down on gcc/clang
58
* anyway...
59
*/
60
#ifdef __GNUC__
61
# pragma GCC diagnostic push
62
# pragma GCC diagnostic ignored "-Wredundant-decls"
63
extern
int
yyparse
(
void
);
64
# pragma GCC diagnostic pop
65
#else
66
extern
int
yyparse
(
void
);
67
#endif
68
69
// Because of how this winds up shared with callback funcs in the
70
// parsing, it's difficult to unwind from being global, so just accept
71
// it.
72
static
FILE *
twmrc
;
73
74
static
int
ptr
= 0;
75
static
int
len
= 0;
76
#define BUF_LEN 300
77
static
char
buff
[
BUF_LEN
+ 1];
78
static
const
char
**
stringListSource
, *
currentString
;
79
80
#ifdef NON_FLEX_LEX
81
/*
82
* While these are (were) referenced in a number of places through the
83
* file, overflowlen is initialized to 0, only possibly changed in
84
* twmUnput(), and unless it's non-zero, neither is otherwise touched.
85
* So this is purely a twmUnput()-related var, and with flex, never used
86
* for anything.
87
*/
88
static
char
overflowbuff[20];
/* really only need one */
89
static
int
overflowlen;
90
#endif
91
92
int
ConstrainedMoveTime
= 400;
/* milliseconds, event times */
93
bool
ParseError
;
/* error parsing the .twmrc file */
94
int
RaiseDelay
= 0;
/* msec, for AutoRaise */
95
int (*
twmInputFunc
)(void);
/* used in lexer */
96
97
static
int
twmrc_lineno
;
98
99
100
/* Actual file loader */
101
static
int
ParseTwmrc
(
const
char
*filename);
102
103
/* lex plumbing funcs */
104
static
bool
doparse
(
int
(*ifunc)(
void
),
const
char
*srctypename,
105
const
char
*srcname);
106
107
static
int
twmStringListInput
(
void
);
108
#ifndef USEM4
109
static
int
twmFileInput
(
void
);
110
#else
111
static
int
m4twmFileInput(
void
);
112
#endif
113
114
#if defined(YYDEBUG) && YYDEBUG
115
int
yydebug = 1;
116
#endif
117
118
119
/**
120
* Principal entry point from top-level code to parse the config file.
121
* This tries the various permutations of config files we could load.
122
* For most possible names, we try loading `$NAME.$SCREENNUM` before
123
* trying `$NAME`. If a `-f filename` is given on the command line, it's
124
* passed in here, and the normal `~/.[c]twmrc*` attempts are skipped if
125
* it's not found.
126
*
127
* \param filename A filename given in the -f command-line argument (or
128
* NULL)
129
* \return true/false for whether a valid config was parsed out from
130
* somewhere.
131
*/
132
bool
133
LoadTwmrc
(
const
char
*filename)
134
{
135
int
ret = -1;
136
char
*tryname = NULL;
137
138
/*
139
* Check for the twmrc file in the following order:
140
* 0. -f filename.#
141
* 1. -f filename
142
* (skip to 6 if -f was given)
143
* 2. .ctwmrc.#
144
* 3. .ctwmrc
145
* 4. .twmrc.#
146
* 5. .twmrc
147
* 6. system.ctwmrc
148
*/
149
#define TRY(fn) if((ret = ParseTwmrc(fn)) != -1) { goto DONE_TRYING; } (void)0
150
151
if
(filename) {
152
/* -f filename.# */
153
asprintf(&tryname,
"%s.%d"
, filename,
Scr
->screen);
154
if
(tryname == NULL) {
155
// Oh, we're _screwed_...
156
return
false
;
157
}
158
TRY
(tryname);
159
160
/* -f filename */
161
TRY
(filename);
162
163
/* If we didn't get either from -f, don't try the ~ bits */
164
goto
TRY_FALLBACK;
165
}
166
167
if
(
Home
) {
168
/* ~/.ctwmrc.screennum */
169
free(tryname);
170
asprintf(&tryname,
"%s/.ctwmrc.%d"
,
Home
,
Scr
->screen);
171
if
(tryname == NULL) {
172
return
false
;
173
}
174
TRY
(tryname);
175
176
// All later attempts are guaranteed shorter strings than that,
177
// so we can just keep sprintf'ing over it.
178
179
/* ~/.ctwmrc */
180
sprintf(tryname,
"%s/.ctwmrc"
,
Home
);
181
TRY
(tryname);
182
183
/* ~/.twmrc.screennum */
184
sprintf(tryname,
"%s/.twmrc.%d"
,
Home
,
Scr
->screen);
185
TRY
(tryname);
186
187
/* ~/.twmrc */
188
sprintf(tryname,
"%s/.twmrc"
,
Home
);
189
TRY
(tryname);
190
}
191
192
TRY_FALLBACK:
193
/* system.twmrc */
194
if
((ret =
ParseTwmrc
(SYSTEM_INIT_FILE)) != -1) {
195
if
(ret && filename) {
196
// If we were -f'ing, fell back to the system default, and
197
// that succeeeded, we warn. It's "normal"(ish) to not have
198
// a personal twmrc and fall back...
199
fprintf(stderr,
200
"%s: unable to open twmrc file %s, using %s instead\n"
,
201
ProgramName
, filename, SYSTEM_INIT_FILE);
202
}
203
goto
DONE_TRYING;
204
}
205
206
207
DONE_TRYING:
208
#undef TRY
209
free(tryname);
210
211
/*
212
* If we wound up with -1 all the way, we totally failed to find a
213
* file to work with. Fall back to builtin config.
214
*/
215
if
(ret == -1) {
216
// Only warn if -f.
217
if
(filename) {
218
fprintf(stderr,
219
"%s: unable to open twmrc file %s, using built-in defaults instead\n"
,
220
ProgramName
, filename);
221
}
222
return
ParseStringList
(
defTwmrc
);
223
}
224
225
226
/* Better have a useful value in ret... */
227
return
ret;
228
}
229
230
231
/**
232
* Try parsing a file as a ctwmrc.
233
*
234
* \param filename The filename to try opening and parsing.
235
* \return -1,0,1. 0/1 should be treated as false/true for whether
236
* parsing the file succeeded. -1 means the file couldn't be opened.
237
*/
238
static
int
239
ParseTwmrc
(
const
char
*filename)
240
{
241
bool
status;
242
243
#if 0
244
fprintf(stderr,
"%s(): Trying %s\n"
, __func__, filename);
245
#endif
246
247
/* See if we can open the file */
248
if
(!filename) {
249
return
-1;
250
}
251
twmrc
= fopen(filename,
"r"
);
252
if
(!
twmrc
) {
253
return
-1;
254
}
255
256
257
/* Got it. Kick off the parsing, however we do it. */
258
#ifdef USEM4
259
FILE *raw = NULL;
260
if
(
CLarg
.GoThroughM4) {
261
/*
262
* Hold onto raw filehandle so we can fclose() it below, and
263
* swap twmrc over to the output from m4
264
*/
265
raw =
twmrc
;
266
twmrc
=
start_m4
(raw);
267
}
268
status =
doparse
(m4twmFileInput,
"file"
, filename);
269
fclose(
twmrc
);
270
if
(raw) {
271
fclose(raw);
272
}
273
#else
274
status =
doparse
(
twmFileInput
,
"file"
, filename);
275
fclose(
twmrc
);
276
#endif
277
278
/* And we're done */
279
return
status;
280
281
/* NOTREACHED */
282
}
283
284
static
bool
285
ParseStringList
(
const
char
**sl)
286
{
287
stringListSource
= sl;
288
currentString
= *sl;
289
return
doparse
(
twmStringListInput
,
"string list"
, NULL);
290
}
291
292
293
/*
294
* Util used throughout the code (possibly often wrongly?)
295
*/
296
void
twmrc_error_prefix
(
void
)
297
{
298
fprintf(stderr,
"%s: line %d: "
,
ProgramName
,
twmrc_lineno
);
299
}
300
301
302
303
/*
304
* Everything below here is related to plumbing and firing off lex/yacc
305
*/
306
307
308
/*
309
* Backend func that takes an input-providing func and hooks it up to the
310
* lex/yacc parser to do the work
311
*/
312
static
bool
313
doparse
(
int
(*ifunc)(
void
),
const
char
*srctypename,
314
const
char
*srcname)
315
{
316
ptr
= 0;
317
len
= 0;
318
twmrc_lineno
= 0;
319
ParseError
=
false
;
320
twmInputFunc
= ifunc;
321
#ifdef NON_FLEX_LEX
322
overflowlen = 0;
323
#endif
324
325
yyparse
();
326
327
if
(
ParseError
) {
328
fprintf(stderr,
"%s: errors found in twm %s"
,
329
ProgramName
, srctypename);
330
if
(srcname) {
331
fprintf(stderr,
" \"%s\""
, srcname);
332
}
333
fprintf(stderr,
"\n"
);
334
}
335
return
!(
ParseError
);
336
}
337
338
339
/*
340
* Various input routines for the lexer for the various sources of
341
* config.
342
*/
343
344
#ifndef USEM4
345
#include <ctype.h>
346
347
/* This has Tom's include() funtionality. This is utterly useless if you
348
* can use m4 for the same thing. Chris P. Ross */
349
350
#define MAX_INCLUDES 10
351
352
static
struct
incl
{
353
FILE *
fp
;
354
char
*
name
;
355
int
lineno
;
356
}
rc_includes
[
MAX_INCLUDES
];
357
static
int
include_file
= 0;
358
359
360
static
int
twmFileInput
(
void
)
361
{
362
#ifdef NON_FLEX_LEX
363
if
(overflowlen) {
364
return
(
int
) overflowbuff[--overflowlen];
365
}
366
#endif
367
368
while
(
ptr
==
len
) {
369
while
(
include_file
) {
370
if
(fgets(
buff
,
BUF_LEN
,
rc_includes
[
include_file
].fp) == NULL) {
371
free(
rc_includes
[
include_file
].name);
372
fclose(
rc_includes
[
include_file
].fp);
373
twmrc_lineno
=
rc_includes
[
include_file
--].
lineno
;
374
}
375
else
{
376
break
;
377
}
378
}
379
380
if
(!
include_file
)
381
if
(fgets(
buff
,
BUF_LEN
,
twmrc
) == NULL) {
382
return
0;
383
}
384
twmrc_lineno
++;
385
386
if
(strncmp(
buff
,
"include"
, 7) == 0) {
387
/* Whoops, an include file! */
388
char
*p =
buff
+ 7, *q;
389
FILE *fp;
390
391
while
(isspace(*p)) {
392
p++;
393
}
394
for
(q = p; *q && !isspace(*q); q++) {
395
continue
;
396
}
397
*q = 0;
398
399
if
((fp = fopen(p,
"r"
)) == NULL) {
400
fprintf(stderr,
"%s: Unable to open included init file %s\n"
,
401
ProgramName
, p);
402
continue
;
403
}
404
if
(++
include_file
>=
MAX_INCLUDES
) {
405
fprintf(stderr,
"%s: init file includes nested too deep\n"
,
406
ProgramName
);
407
continue
;
408
}
409
rc_includes
[
include_file
].
fp
= fp;
410
rc_includes
[
include_file
].
lineno
=
twmrc_lineno
;
411
twmrc_lineno
= 0;
412
rc_includes
[
include_file
].
name
= strdup(p);
413
continue
;
414
}
415
ptr
= 0;
416
len
= strlen(
buff
);
417
}
418
return
((
int
)
buff
[
ptr
++]);
419
}
420
#else
/* USEM4 */
421
/* If you're going to use m4, use this version instead. Much simpler.
422
* m4 ism's credit to Josh Osborne (stripes) */
423
424
static
int
m4twmFileInput(
void
)
425
{
426
int
line;
427
static
FILE *cp = NULL;
428
429
if
(cp == NULL &&
CLarg
.keepM4_filename) {
430
cp = fopen(
CLarg
.keepM4_filename,
"w"
);
431
if
(cp == NULL) {
432
fprintf(stderr,
433
"%s: unable to create m4 output %s, ignoring\n"
,
434
ProgramName
,
CLarg
.keepM4_filename);
435
CLarg
.keepM4_filename = NULL;
436
}
437
}
438
439
#ifdef NON_FLEX_LEX
440
if
(overflowlen) {
441
return
((
int
) overflowbuff[--overflowlen]);
442
}
443
#endif
444
445
while
(
ptr
==
len
) {
446
nextline:
447
if
(fgets(
buff
,
BUF_LEN
,
twmrc
) == NULL) {
448
if
(cp) {
449
fclose(cp);
450
}
451
return
(0);
452
}
453
if
(cp) {
454
fputs(
buff
, cp);
455
}
456
457
if
(sscanf(
buff
,
"#line %d"
, &line)) {
458
twmrc_lineno
= line - 1;
459
goto
nextline;
460
}
461
else
{
462
twmrc_lineno
++;
463
}
464
465
ptr
= 0;
466
len
= strlen(
buff
);
467
}
468
return
((
int
)
buff
[
ptr
++]);
469
}
470
#endif
/* USEM4 */
471
472
473
static
int
twmStringListInput
(
void
)
474
{
475
#ifdef NON_FLEX_LEX
476
if
(overflowlen) {
477
return
(
int
) overflowbuff[--overflowlen];
478
}
479
#endif
480
481
/*
482
* return the character currently pointed to
483
*/
484
if
(
currentString
) {
485
unsigned
int
c = (
unsigned
int) *
currentString
++;
486
487
if
(c) {
488
return
c;
/* if non-nul char */
489
}
490
currentString
= *++
stringListSource
;
/* advance to next bol */
491
return
'\n'
;
/* but say that we hit last eol */
492
}
493
return
0;
/* eof */
494
}
495
496
497
498
/*
499
* unput/output funcs for AT&T lex. No longer supported, and expected to
500
* be GC'd in a release or two.
501
*/
502
#ifdef NON_FLEX_LEX
503
504
void
twmUnput(
int
c)
505
{
506
if
(overflowlen <
sizeof
overflowbuff) {
507
overflowbuff[overflowlen++] = (char) c;
508
}
509
else
{
510
twmrc_error_prefix
();
511
fprintf(stderr,
"unable to unput character (%c)\n"
,
512
c);
513
}
514
}
515
516
void
TwmOutput(
int
c)
517
{
518
putchar(c);
519
}
520
521
#endif
/* NON_FLEX_LEX */
CLarg
ctwm_cl_args CLarg
Definition
clargs.c:27
ctwm.h
ProgramName
char * ProgramName
Definition
ctwm_main.c:146
Home
char * Home
Definition
ctwm_main.c:128
Scr
#define Scr
deftwmrc.h
defTwmrc
const char * defTwmrc[]
twmInputFunc
int(*) twmInputFunc(void)
Definition
parse.c:95
buff
static char buff[300+1]
Definition
parse.c:77
ParseStringList
static bool ParseStringList(const char **sl)
Definition
parse.c:285
ptr
static int ptr
Definition
parse.c:74
ParseError
bool ParseError
Definition
parse.c:93
include_file
static int include_file
Definition
parse.c:357
doparse
static bool doparse(int(*ifunc)(void), const char *srctypename, const char *srcname)
Definition
parse.c:313
MAX_INCLUDES
#define MAX_INCLUDES
Definition
parse.c:350
currentString
static const char * currentString
Definition
parse.c:78
yyparse
int yyparse(void)
ConstrainedMoveTime
int ConstrainedMoveTime
Definition
parse.c:92
BUF_LEN
#define BUF_LEN
Definition
parse.c:76
twmStringListInput
static int twmStringListInput(void)
Definition
parse.c:473
TRY
#define TRY(fn)
stringListSource
static const char ** stringListSource
Definition
parse.c:78
RaiseDelay
int RaiseDelay
Definition
parse.c:94
twmrc_lineno
static int twmrc_lineno
Definition
parse.c:97
twmFileInput
static int twmFileInput(void)
Definition
parse.c:360
twmrc
static FILE * twmrc
Definition
parse.c:72
twmrc_error_prefix
void twmrc_error_prefix(void)
Definition
parse.c:296
rc_includes
static struct incl rc_includes[10]
ParseTwmrc
static int ParseTwmrc(const char *filename)
Try parsing a file as a ctwmrc.
Definition
parse.c:239
LoadTwmrc
bool LoadTwmrc(const char *filename)
Principal entry point from top-level code to parse the config file.
Definition
parse.c:133
len
static int len
Definition
parse.c:75
parse.h
parse_int.h
start_m4
FILE * start_m4(FILE *fraw)
Definition
parse_m4.c:28
screen.h
sound.h
incl
Definition
parse.c:352
incl::lineno
int lineno
Definition
parse.c:355
incl::fp
FILE * fp
Definition
parse.c:353
incl::name
char * name
Definition
parse.c:354
parse.c
Generated by
1.18.0