1 /*
2 * +-------------------------------------------------------+
3 * | |
4 * | videogen |
5 * | |
6 * | a simple XFree86 Modeline calculator |
7 * | (c) 1997-2003, Szabolcs Rumi |
8 * | |
9 * | http://www.dynaweb.hu/opensource/videogen |
10 * | |
11 * | the videogen package is distributed under the |
12 * | GNU General Public License Version 2 (GPLv2) |
13 * | |
14 * +-------------------------------------------------------+
15 */
16
17
18
19
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "config.h"
26 #include "videogen.h"
27
28
29
30
31
32 arg_opt_t opts[] =
33 {
34 { "-h", NULL, 0 },
35 { "-v", NULL, 0 },
36 { "-q", NULL, 0 },
37 { "-fb", NULL, 0 },
38 { "-nfb", NULL, 0 },
39 { "-nv", NULL, 0 },
40 { "-nnv", NULL, 0 },
41 { "-f", NULL, 0 },
42 { "-m", NULL, 0 },
43 { "-mdc", NULL, 0 },
44 { "-mhf", NULL, 0 },
45 { "-mvf", NULL, 0 },
46 { "-dvf", NULL, 0 },
47 { "-hv", NULL, 0 },
48 { "-vv", NULL, 0 },
49 { "-hfp", NULL, 0 },
50 { "-hbp", NULL, 0 },
51 { "-hsp", NULL, 0 },
52 { "-vfp", NULL, 0 },
53 { "-vbp", NULL, 0 },
54 { "-vsp", NULL, 0 },
55 { NULL, NULL, 0 }
56 };
57
58
59
60
61
62 int
arg_action(arg_parse_t * ap)63 arg_action (arg_parse_t *ap)
64 {
65 unsigned int x_uint, y_uint;
66 double x_double;
67
68 char *serr = NULL; /* for using with strtol(), strtod() */
69
70
71
72 /*
73 fprintf (stdout, "argument %u matches option %u: %s == %s\n",
74 ap->aindex, ap->oindex, (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
75 */
76
77 /*
78 * taking appropriate actions for each argument type
79 */
80
81 switch (ap->oindex)
82 {
83 case 0: {
84 banner ();
85 usage ();
86 exit (0); /* either reading help or using the program... */
87 break;
88 }
89
90 case 1: {
91 if (commit_verbose (CFG_PREC_CMDLINE, &verbose, 1) == 0)
92 pmsg (VL_DEBUG, "[cmdline] arg %u: verbose mode on\n", ap->aindex);
93 break;
94 }
95
96 case 2: {
97 if (commit_verbose (CFG_PREC_CMDLINE, &verbose, 0) == 0)
98 pmsg (VL_DEBUG, "[cmdline] arg %u: verbose mode off\n", ap->aindex);
99 break;
100 }
101
102 case 3: {
103 if (commit_fbset (CFG_PREC_CMDLINE, &fbset, 1) == 0)
104 pmsg (VL_DEBUG, "[cmdline] arg %u: fbset mode on\n", ap->aindex);
105 break;
106 }
107
108 case 4: {
109 if (commit_fbset (CFG_PREC_CMDLINE, &fbset, 0) == 0)
110 pmsg (VL_DEBUG, "[cmdline] arg %u: fbset mode off\n", ap->aindex);
111 break;
112 }
113
114 case 5: {
115 if (commit_nvidia (CFG_PREC_CMDLINE, &nvidia, 1) == 0)
116 pmsg (VL_DEBUG, "[cmdline] arg %u: nvidia compatibility mode on\n", ap->aindex);
117 break;
118 }
119
120 case 6: {
121 if (commit_nvidia (CFG_PREC_CMDLINE, &nvidia, 0) == 0)
122 pmsg (VL_DEBUG, "[cmdline] arg %u: nvidia compatibility mode off\n", ap->aindex);
123 break;
124 }
125
126 case 7: {
127 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
128 {
129 cfgfile = (*ap->options)[ap->oindex].ao_parameter;
130 pmsg (VL_DEBUG, "[cmdline] arg %u: config file set to %s\n", ap->aindex, cfgfile);
131 }
132 break;
133 }
134
135 case 8: {
136 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
137 {
138 if (sscanf ((*ap->options)[ap->oindex].ao_parameter, "%ux%u", &x_uint, &y_uint) == 2)
139 {
140 switch (commit_mode (CFG_PREC_CMDLINE, &modes, &num_modes, x_uint, y_uint))
141 {
142 case -1: break;
143
144 case 0: {
145 pmsg (VL_DEBUG, "[cmdline] arg %u: added mode %ux%u\n", ap->aindex, x_uint, y_uint);
146 break;
147 }
148
149 case 5: {
150 pmsg (VL_DEBUG, "[cmdline] arg %u: too many modes, dropping %ux%u\n", ap->aindex, x_uint, y_uint);
151 pmsg (VL_VERBOSE, "no more than 256 modes are allowed, dropping %ux%u\n", x_uint, y_uint);
152 break;
153 }
154
155 default: {
156 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
157 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
158 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
159 return (-1);
160 }
161 }
162 }
163 else
164 return (-1);
165 }
166 else
167 return (-1);
168
169 break;
170 }
171
172 case 9: {
173 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
174 {
175 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
176
177 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
178 {
179 switch (commit_max_dotclk (CFG_PREC_CMDLINE, &max_dotclk, x_double))
180 {
181 case -1: break;
182
183 case 0: {
184 pmsg (VL_DEBUG, "[cmdline] arg %u: max_dotclk = %0.0f MHz\n", ap->aindex, x_double);
185 break;
186 }
187
188 default: {
189 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
190 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
191 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
192 return (-1);
193 }
194 }
195 }
196 else
197 return (-1);
198 }
199 else
200 return (-1);
201
202 break;
203 }
204
205 case 10: {
206 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
207 {
208 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
209
210 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
211 {
212 switch (commit_max_hfreq (CFG_PREC_CMDLINE, &max_hfreq, x_double))
213 {
214 case -1: break;
215
216 case 0: {
217 pmsg (VL_DEBUG, "[cmdline] arg %u: max_hfreq = %0.1f kHz\n", ap->aindex, x_double);
218 break;
219 }
220
221 default: {
222 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
223 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
224 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
225 return (-1);
226 }
227 }
228 }
229 else
230 return (-1);
231 }
232 else
233 return (-1);
234
235 break;
236 }
237
238 case 11: {
239 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
240 {
241 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
242
243 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
244 {
245 switch (commit_max_vfreq (CFG_PREC_CMDLINE, &max_vfreq, x_double))
246 {
247 case -1: break;
248
249 case 0: {
250 pmsg (VL_DEBUG, "[cmdline] arg %u: max_vfreq = %0.1f Hz\n", ap->aindex, x_double);
251 break;
252 }
253
254 default: {
255 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
256 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
257 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
258 return (-1);
259 }
260 }
261 }
262 else
263 return (-1);
264 }
265 else
266 return (-1);
267
268 break;
269 }
270
271 case 12: {
272 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
273 {
274 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
275
276 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
277 {
278 switch (commit_desired_vfreq (CFG_PREC_CMDLINE, &desired_vfreq, x_double))
279 {
280 case -1: break;
281
282 case 0: {
283 pmsg (VL_DEBUG, "[cmdline] arg %u: desired_vfreq = %0.1f Hz\n", ap->aindex, x_double);
284 break;
285 }
286
287 default: {
288 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
289 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
290 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
291 return (-1);
292 }
293 }
294 }
295 else
296 return (-1);
297 }
298 else
299 return (-1);
300
301 break;
302 }
303
304 case 13: {
305 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
306 {
307 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
308
309 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
310 {
311 switch (commit_hvisible (CFG_PREC_CMDLINE, &hvisible, x_double))
312 {
313 case -1: break;
314
315 case 0: {
316 pmsg (VL_DEBUG, "[cmdline] arg %u: hvisible = %0.0f %\n", ap->aindex, x_double);
317 break;
318 }
319
320 default: {
321 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
322 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
323 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
324 return (-1);
325 }
326 }
327 }
328 else
329 return (-1);
330 }
331 else
332 return (-1);
333
334 break;
335 }
336
337 case 14: {
338 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
339 {
340 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
341
342 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
343 {
344 switch (commit_vvisible (CFG_PREC_CMDLINE, &vvisible, x_double))
345 {
346 case -1: break;
347
348 case 0: {
349 pmsg (VL_DEBUG, "[cmdline] arg %u: vvisible = %0.0f %\n", ap->aindex, x_double);
350 break;
351 }
352
353 default: {
354 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
355 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
356 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
357 return (-1);
358 }
359 }
360 }
361 else
362 return (-1);
363 }
364 else
365 return (-1);
366
367 break;
368 }
369
370 case 15: {
371 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
372 {
373 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
374
375 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
376 {
377 switch (commit_hfporch (CFG_PREC_CMDLINE, &hfporch, x_double))
378 {
379 case -1: break;
380
381 case 0: {
382 pmsg (VL_DEBUG, "[cmdline] arg %u: hfporch = %0.0f ticks\n", ap->aindex, x_double);
383 break;
384 }
385
386 default: {
387 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
388 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
389 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
390 return (-1);
391 }
392 }
393 }
394 else
395 return (-1);
396 }
397 else
398 return (-1);
399
400 break;
401 }
402
403 case 16: {
404 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
405 {
406 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
407
408 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
409 {
410 switch (commit_hbporch (CFG_PREC_CMDLINE, &hbporch, x_double))
411 {
412 case -1: break;
413
414 case 0: {
415 pmsg (VL_DEBUG, "[cmdline] arg %u: hbporch = %0.0f ticks\n", ap->aindex, x_double);
416 break;
417 }
418
419 default: {
420 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
421 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
422 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
423 return (-1);
424 }
425 }
426 }
427 else
428 return (-1);
429 }
430 else
431 return (-1);
432
433 break;
434 }
435
436 case 17: {
437 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
438 {
439 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
440
441 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
442 {
443 switch (commit_hsync (CFG_PREC_CMDLINE, &hsync, x_double))
444 {
445 case -1: break;
446
447 case 0: {
448 pmsg (VL_DEBUG, "[cmdline] arg %u: hsync = %0.1f usec\n", ap->aindex, x_double);
449 break;
450 }
451
452 default: {
453 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
454 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
455 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
456 return (-1);
457 }
458 }
459 }
460 else
461 return (-1);
462 }
463 else
464 return (-1);
465
466 break;
467 }
468
469 case 18: {
470 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
471 {
472 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
473
474 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
475 {
476 switch (commit_vfporch (CFG_PREC_CMDLINE, &vfporch, x_double))
477 {
478 case -1: break;
479
480 case 0: {
481 pmsg (VL_DEBUG, "[cmdline] arg %u: vfporch = %0.0f ticks\n", ap->aindex, x_double);
482 break;
483 }
484
485 default: {
486 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
487 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
488 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
489 return (-1);
490 }
491 }
492 }
493 else
494 return (-1);
495 }
496 else
497 return (-1);
498
499 break;
500 }
501
502 case 19: {
503 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
504 {
505 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
506
507 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
508 {
509 switch (commit_vbporch (CFG_PREC_CMDLINE, &vbporch, x_double))
510 {
511 case -1: break;
512
513 case 0: {
514 pmsg (VL_DEBUG, "[cmdline] arg %u: vbporch = %0.0f ticks\n", ap->aindex, x_double);
515 break;
516 }
517
518 default: {
519 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
520 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
521 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
522 return (-1);
523 }
524 }
525 }
526 else
527 return (-1);
528 }
529 else
530 return (-1);
531
532 break;
533 }
534
535 case 20: {
536 if ((*ap->options)[ap->oindex].ao_flags & ARG_FOUND_PARM)
537 {
538 x_double = strtod ((*ap->options)[ap->oindex].ao_parameter, &serr);
539
540 if ((*(*ap->options)[ap->oindex].ao_parameter != '\0') && (*serr == '\0'))
541 {
542 switch (commit_vsync (CFG_PREC_CMDLINE, &vsync, x_double))
543 {
544 case -1: break;
545
546 case 0: {
547 pmsg (VL_DEBUG, "[cmdline] arg %u: vsync = %0.0f usec\n", ap->aindex, x_double);
548 break;
549 }
550
551 default: {
552 pmsg (VL_DEBUG, "[cmdline] arg %u: %s has an invalid parameter \"%s\"\n", ap->aindex,
553 (*ap->options)[ap->oindex].ao_option, (*ap->options)[ap->oindex].ao_parameter);
554 pmsg (VL_VERBOSE, "argument %u (%s) has an invalid parameter\n", ap->aindex, ap->argv[ap->aindex]);
555 return (-1);
556 }
557 }
558 }
559 else
560 return (-1);
561 }
562 else
563 return (-1);
564
565 break;
566 }
567
568 default: {
569 pmsg (VL_DEBUG, "[cmdline] arg %u: unrecognized argument \"%s\"\n", ap->aindex, ap->argv[ap->aindex]);
570 pmsg (VL_VERBOSE, "invalid argument %u (%s)\n", ap->aindex, ap->argv[ap->aindex]);
571 return (-1);
572 }
573 }
574
575 return (0);
576 }
577
578
579
580
581
582 int
arg_parse(arg_parse_t * ap,int (* arg_action)(arg_parse_t *))583 arg_parse (arg_parse_t *ap, int (*arg_action) (arg_parse_t *))
584 {
585 char *eq;
586 int match;
587
588
589
590 /*
591 * parse all arguments present on the command line
592 */
593
594 ap->aindex = 1;
595 while (ap->aindex < ap->argc)
596 {
597 ap->oindex = 0;
598 match = 0;
599
600 while ((*ap->options)[ap->oindex].ao_option != NULL)
601 {
602 if ((eq = strchr (ap->argv[ap->aindex], '=')) == NULL)
603 {
604 /*
605 * argument does not have a parameter
606 */
607
608 if (strcmp ((*ap->options)[ap->oindex].ao_option, ap->argv[ap->aindex]) == 0)
609 {
610 match++;
611 (*ap->options)[ap->oindex].ao_flags |= ARG_FOUND;
612
613 if ((*arg_action) (ap) < 0)
614 return (-1);
615 }
616 }
617 else
618 {
619 /*
620 * argument does have a parameter
621 */
622
623 *eq = '\0'; /* temporarily split string at the equal sign */
624
625 if (strcmp ((*ap->options)[ap->oindex].ao_option, ap->argv[ap->aindex]) == 0)
626 {
627 match++;
628 (*ap->options)[ap->oindex].ao_flags |= ARG_FOUND;
629 (*ap->options)[ap->oindex].ao_flags |= ARG_FOUND_PARM;
630 (*ap->options)[ap->oindex].ao_parameter = eq + 1;
631
632 *eq = '='; /* restore equal sign */
633 if ((*arg_action) (ap) < 0)
634 return (-1);
635 }
636 else
637 *eq = '='; /* restore equal sign */
638 }
639
640 ap->oindex++;
641 }
642
643 if (((*ap->options)[ap->oindex].ao_option != NULL) && (match == 0))
644 {
645 ap->oindex = -1; /* signal unmatched argument */
646 if ((*arg_action) (ap) < 0)
647 return (-1);
648 }
649
650 ap->aindex++;
651 }
652
653 return (0);
654 }
655
656
657
658
659
660 /* EOF */
661