CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/clargs.c
Go to the documentation of this file.
1/*
2 * Command-line arg handling
3 */
4
5#include "ctwm.h"
6
7#include <getopt.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "clargs.h"
13#include "ctopts.h"
14#include "deftwmrc.h"
15#include "screen.h"
16#include "version.h"
17
18static void usage(void) __attribute__((noreturn));
19static void print_version(void);
20static void DisplayInfo(void);
21static void dump_default_config(void);
22
23
24/*
25 * Command-line args. Initialize with useful default values.
26 */
28 .MultiScreen = true,
29 .Monochrome = false,
30 .cfgchk = false,
31 .InitFile = NULL,
32 .display_name = NULL,
33 .PrintErrorMessages = false,
34#ifdef DEBUG
35 .ShowWelcomeWindow = false,
36#else
37 .ShowWelcomeWindow = true,
38#endif
39#ifdef CAPTIVE
40 .is_captive = false,
41 .capwin = (Window) 0,
43#endif
45 .KeepTmpFile = false,
47 .GoThroughM4 = true,
48#endif
50 .ewmh_replace = false,
51#endif
52 .client_id = NULL,
53 .restore_filename = NULL,
54};
55
56
57
58/*
59 * Parse them out and setup CLargs.
60 */
61void
62clargs_parse(int argc, char *argv[])
63{
64 int ch, optidx;
65
66 /*
67 * Setup long options for arg parsing
68 */
69 static struct option long_options[] = {
70 /* Simple flags */
71 { "single", no_argument, NULL, 0 },
72 { "mono", no_argument, NULL, 0 },
73 { "verbose", no_argument, NULL, 'v' },
74 { "quiet", no_argument, NULL, 'q' },
75 { "nowelcome", no_argument, NULL, 'W' },
76
77 /* Config/file related */
78 { "file", required_argument, NULL, 'f' },
79 { "cfgchk", no_argument, NULL, 0 },
80
81 /* Show something and exit right away */
82 { "help", no_argument, NULL, 'h' },
83 { "version", no_argument, NULL, 0 },
84 { "info", no_argument, NULL, 0 },
85 { "dumpcfg", no_argument, NULL, 0 },
86
87 /* Misc control bits */
88 { "display", required_argument, NULL, 'd' },
89 { "xrm", required_argument, NULL, 0 },
90#ifdef CAPTIVE
91 { "window", optional_argument, NULL, 'w' },
92 { "name", required_argument, NULL, 0 },
93#endif
94
95#ifdef EWMH
96 { "replace", no_argument, NULL, 0 },
97#endif
98
99 /* M4 control params */
100#ifdef USEM4
101 { "keep-defs", no_argument, NULL, 'k' },
102 { "keep", required_argument, NULL, 'K' },
103 { "nom4", no_argument, NULL, 'n' },
104#endif
105
106 /* Random session-related bits */
107 { "clientId", required_argument, NULL, 0 },
108 { "restore", required_argument, NULL, 0 },
109
110 { NULL, 0, NULL, 0 },
111 };
112
113
114 /*
115 * Short aliases for some
116 *
117 * I assume '::' for optional args is portable; getopt_long(3)
118 * doesn't describe it, but it's a GNU extension for getopt(3).
119 */
120 const char *short_options = "vqWf:hd:"
121#ifdef CAPTIVE
122 "w::"
123#endif
124#ifdef USEM4
125 "kK:n"
126#endif
127 ;
128
129
130 /*
131 * Backward-compat cheat: accept a few old-style long args if they
132 * came first. Of course, this assumed argv[x] is editable, which on
133 * most systems it is, and C99 requires it.
134 */
135 if(argc > 1) {
136#define CHK(x) else if(strcmp(argv[1], (x)) == 0)
137 if(0) {
138 /* nada */
139 }
140 CHK("-version") {
142 exit(0);
143 }
144 CHK("-info") {
145 DisplayInfo();
146 exit(0);
147 }
148 CHK("-cfgchk") {
149 CLarg.cfgchk = true;
150 *argv[1] = '\0';
151 }
152 CHK("-display") {
153 if(argc <= 2 || strlen(argv[2]) < 1) {
154 usage();
155 }
157
158 *argv[1] = '\0';
159 *argv[2] = '\0';
160 }
161#undef CHK
162 }
163
164
165 /*
166 * Parse out the args
167 */
168 optidx = 0;
170 &optidx)) != -1) {
171 switch(ch) {
172 /* First handle the simple cases that have short args */
173 case 'v':
175 break;
176 case 'q':
178 break;
179 case 'W':
180 CLarg.ShowWelcomeWindow = false;
181 break;
182 case 'f':
184 break;
185 case 'h':
186 usage();
187 case 'd':
189 break;
190#ifdef CAPTIVE
191 case 'w':
192 CLarg.is_captive = true;
193 CLarg.MultiScreen = false;
194 if(optarg != NULL) {
195 sscanf(optarg, "%x", (unsigned int *)&CLarg.capwin);
196 /* Failure will just leave capwin as initialized */
197 }
198 break;
199#endif
200
201#ifdef USEM4
202 /* Args that only mean anything if we're built with m4 */
203 case 'k':
204 CLarg.KeepTmpFile = true;
205 break;
206 case 'K':
207 CLarg.keepM4_filename = optarg;
208 break;
209 case 'n':
210 CLarg.GoThroughM4 = false;
211 break;
212#endif
213
214
215 /*
216 * Now the stuff that doesn't have short variants.
217 */
218 case 0:
219
220#define IFIS(x) if(strcmp(long_options[optidx].name, (x)) == 0)
221 /* Simple flag-setting */
222 IFIS("single") {
223 CLarg.MultiScreen = false;
224 break;
225 }
226 IFIS("mono") {
227 CLarg.Monochrome = true;
228 break;
229 }
230 IFIS("cfgchk") {
231 CLarg.cfgchk = true;
232 break;
233 }
234#ifdef EWMH
235 IFIS("replace") {
236 CLarg.ewmh_replace = true;
237 break;
238 }
239#endif
240
241 /* Simple value-setting */
242#ifdef CAPTIVE
243 IFIS("name") {
244 CLarg.captivename = optarg;
245 break;
246 }
247#endif
248 IFIS("clientId") {
250 break;
251 }
252 IFIS("restore") {
254 break;
255 }
256
257 /* Some immediate actions */
258 IFIS("version") {
260 exit(0);
261 }
262 IFIS("info") {
263 DisplayInfo();
264 exit(0);
265 }
266 IFIS("dumpcfg") {
268 exit(0);
269 }
270
271 /* Misc */
272 IFIS("xrm") {
273 /*
274 * Quietly ignored by us; Xlib processes it
275 * internally in XtToolkitInitialize();
276 */
277 break;
278 }
279#undef IFIS
280
281 /*
282 * Some choices may just be internally setting a flag.
283 * We have none right now, but leave this in case we grow
284 * more later.
285 */
286 if(long_options[optidx].flag != NULL) {
287 break;
288 }
289
290 /* Don't think it should be possible to get here... */
291 fprintf(stderr, "Internal error in getopt: '%s' unhandled.\n",
292 long_options[optidx].name);
293 usage();
294
295 /* Something totally unexpected */
296 case '?':
297 /* getopt_long() already printed an error */
298 usage();
299
300 default:
301 /* Uhhh... */
302 fprintf(stderr, "Internal error: getopt confused us.\n");
303 usage();
304 }
305 }
306
307
308 /* Should do it */
309 return;
310}
311
312
313/*
314 * Sanity check CLarg's
315 */
316void
318{
319
320#ifdef USEM4
321 /* If we're not doing m4, don't specify m4 options */
322 if(!CLarg.GoThroughM4) {
323 if(CLarg.KeepTmpFile) {
324 fprintf(stderr, "--keep-defs is incompatible with --nom4.\n");
325 usage();
326 }
327 if(CLarg.keepM4_filename) {
328 fprintf(stderr, "--keep is incompatible with --nom4.\n");
329 usage();
330 }
331 }
332#endif
333
334#ifdef CAPTIVE
335 /* If we're not captive, captivename is meaningless too */
336 if(CLarg.captivename && !CLarg.is_captive) {
337 fprintf(stderr, "--name is meaningless without --window.\n");
338 usage();
339 }
340
341 /*
342 * Being captive and --cfgchk'ing is kinda meaningless. There's no
343 * reason to create a window just to destroy things, and it never
344 * adds anything. And it's one more way we're forcing changes on the
345 * X side before we parse the actual config, so let's just disallow
346 * it.
347 */
348 if(CLarg.is_captive && CLarg.cfgchk) {
349 fprintf(stderr, "--window is incompatible with --cfgchk.\n");
350 usage();
351 }
352#endif
353
354 /* Guess that's it */
355 return;
356}
357
358
359/*
360 * Small utils only currently used in this file. Over time they may need
361 * to be exported, if we start using them from more places.
362 */
363static void
364usage(void)
365{
366 /* How far to indent continuation lines */
367 int llen = 10;
368
369 fprintf(stderr, "usage: %s [(--display | -d) dpy] "
370#ifdef EWMH
371 "[--replace] "
372#endif
373 "[--single]\n", ProgramName);
374
375 fprintf(stderr, "%*s[(--file | -f) initfile] [--cfgchk] [--dumpcfg]\n",
376 llen, "");
377
378#ifdef USEM4
379 fprintf(stderr, "%*s[--nom4 | -n] [--keep-defs | -k] "
380 "[(--keep | -K) m4file]\n", llen, "");
381#endif
382
383 fprintf(stderr, "%*s[--verbose | -v] [--quiet | -q] [--mono] "
384 "[--xrm resource]\n", llen, "");
385
386 fprintf(stderr, "%*s[--version] [--info] [--nowelcome | -W]\n",
387 llen, "");
388
389#ifdef CAPTIVE
390 fprintf(stderr, "%*s[(--window | -w) [win-id]] [--name name]\n", llen, "");
391#endif
392
393 /* Semi-intentionally not documenting --clientId/--restore */
394
395 fprintf(stderr, "%*s[--help]\n", llen, "");
396
397
398 exit(1);
399}
400
401
402static void
404{
405 printf("ctwm %s\n", VersionNumberFull);
406 if(VCSType && VCSRevision) {
407 printf(" (%s:%s)\n", VCSType, VCSRevision);
408 }
409}
410
411
412static void
414{
415 char *ctopts;
416
417 printf("Twm version: %s\n", TwmVersion);
418
419 ctopts = ctopts_string(" ");
420 printf("Compile time options : %s\n", ctopts);
421 free(ctopts);
422}
423
424
425static void
427{
428 int i;
429
430 for(i = 0 ; defTwmrc[i] != NULL ; i++) {
431 printf("%s\n", defTwmrc[i]);
432 }
433}
static int PlaceX
Definition add_window.c:82
static void dump_default_config(void)
Definition clargs.c:426
void clargs_parse(int argc, char *argv[])
Definition clargs.c:62
#define IFIS(x)
static void print_version(void)
Definition clargs.c:403
void clargs_check(void)
Definition clargs.c:317
ctwm_cl_args CLarg
Definition clargs.c:27
static void usage(void)
Definition clargs.c:364
static void DisplayInfo(void)
Definition clargs.c:413
#define CHK(x)
static char * ctopts[]
Definition ctopts.c:17
char * ctopts_string(char *sep)
Definition ctopts.c:48
char * ProgramName
Definition ctwm_main.c:146
#define __attribute__(x)
Definition ctwm.h:50
const char * defTwmrc[]
char * restore_filename
Definition ctwm.h:413
char * InitFile
Definition ctwm.h:390
char * client_id
Definition ctwm.h:412
bool PrintErrorMessages
Definition ctwm.h:393
bool MultiScreen
Definition ctwm.h:387
bool Monochrome
Definition ctwm.h:388
bool cfgchk
Definition ctwm.h:389
char * display_name
Definition ctwm.h:391
bool ShowWelcomeWindow
Definition ctwm.h:394
const char * VCSType
const char * VersionNumberFull
const char * TwmVersion
const char * VCSRevision