Add APIC_ID to extract apic id from local apic id field
[dragonfly.git] / contrib / less / optfunc.c
1 /*
2  * Copyright (C) 1984-2009  Mark Nudelman
3  *
4  * You may distribute under the terms of either the GNU General Public
5  * License or the Less License, as specified in the README file.
6  *
7  * For more information about less, or for information on how to 
8  * contact the author, see the README file.
9  */
10
11
12 /*
13  * Handling functions for command line options.
14  *
15  * Most options are handled by the generic code in option.c.
16  * But all string options, and a few non-string options, require
17  * special handling specific to the particular option.
18  * This special processing is done by the "handling functions" in this file.
19  *
20  * Each handling function is passed a "type" and, if it is a string
21  * option, the string which should be "assigned" to the option.
22  * The type may be one of:
23  *      INIT    The option is being initialized from the command line.
24  *      TOGGLE  The option is being changed from within the program.
25  *      QUERY   The setting of the option is merely being queried.
26  */
27
28 #include "less.h"
29 #include "option.h"
30
31 extern int nbufs;
32 extern int bufspace;
33 extern int pr_type;
34 extern int plusoption;
35 extern int swindow;
36 extern int sc_width;
37 extern int sc_height;
38 extern int secure;
39 extern int dohelp;
40 extern int any_display;
41 extern char openquote;
42 extern char closequote;
43 extern char *prproto[];
44 extern char *eqproto;
45 extern char *hproto;
46 extern char *wproto;
47 extern IFILE curr_ifile;
48 extern char version[];
49 extern int jump_sline;
50 extern int jump_sline_fraction;
51 extern int shift_count;
52 extern int shift_count_fraction;
53 extern int less_is_more;
54 #if LOGFILE
55 extern char *namelogfile;
56 extern int force_logfile;
57 extern int logfile;
58 #endif
59 #if TAGS
60 public char *tagoption = NULL;
61 extern char *tags;
62 #endif
63 #if MSDOS_COMPILER
64 extern int nm_fg_color, nm_bg_color;
65 extern int bo_fg_color, bo_bg_color;
66 extern int ul_fg_color, ul_bg_color;
67 extern int so_fg_color, so_bg_color;
68 extern int bl_fg_color, bl_bg_color;
69 #endif
70
71
72 #if LOGFILE
73 /*
74  * Handler for -o option.
75  */
76         public void
77 opt_o(type, s)
78         int type;
79         char *s;
80 {
81         PARG parg;
82
83         if (secure)
84         {
85                 error("log file support is not available", NULL_PARG);
86                 return;
87         }
88         switch (type)
89         {
90         case INIT:
91                 namelogfile = s;
92                 break;
93         case TOGGLE:
94                 if (ch_getflags() & CH_CANSEEK)
95                 {
96                         error("Input is not a pipe", NULL_PARG);
97                         return;
98                 }
99                 if (logfile >= 0)
100                 {
101                         error("Log file is already in use", NULL_PARG);
102                         return;
103                 }
104                 s = skipsp(s);
105                 namelogfile = lglob(s);
106                 use_logfile(namelogfile);
107                 sync_logfile();
108                 break;
109         case QUERY:
110                 if (logfile < 0)
111                         error("No log file", NULL_PARG);
112                 else
113                 {
114                         parg.p_string = namelogfile;
115                         error("Log file \"%s\"", &parg);
116                 }
117                 break;
118         }
119 }
120
121 /*
122  * Handler for -O option.
123  */
124         public void
125 opt__O(type, s)
126         int type;
127         char *s;
128 {
129         force_logfile = TRUE;
130         opt_o(type, s);
131 }
132 #endif
133
134 /*
135  * Handlers for -l option.
136  */
137         public void
138 opt_l(type, s)
139         int type;
140         char *s;
141 {
142         int err;
143         int n;
144         char *t;
145         
146         switch (type)
147         {
148         case INIT:
149                 t = s;
150                 n = getnum(&t, "l", &err);
151                 if (err || n <= 0)
152                 {
153                         error("Line number is required after -l", NULL_PARG);
154                         return;
155                 }
156                 plusoption = TRUE;
157                 ungetsc(s);
158                 break;
159         }
160 }
161
162 /*
163  * Handlers for -j option.
164  */
165         public void
166 opt_j(type, s)
167         int type;
168         char *s;
169 {
170         PARG parg;
171         char buf[16];
172         int len;
173         int err;
174
175         switch (type)
176         {
177         case INIT:
178         case TOGGLE:
179                 if (*s == '.')
180                 {
181                         s++;
182                         jump_sline_fraction = getfraction(&s, "j", &err);
183                         if (err)
184                                 error("Invalid line fraction", NULL_PARG);
185                         else
186                                 calc_jump_sline();
187                 } else
188                 {
189                         int sline = getnum(&s, "j", &err);
190                         if (err)
191                                 error("Invalid line number", NULL_PARG);
192                         else
193                         {
194                                 jump_sline = sline;
195                                 jump_sline_fraction = -1;
196                         }
197                 }
198                 break;
199         case QUERY:
200                 if (jump_sline_fraction < 0)
201                 {
202                         parg.p_int =  jump_sline;
203                         error("Position target at screen line %d", &parg);
204                 } else
205                 {
206
207                         sprintf(buf, ".%06d", jump_sline_fraction);
208                         len = strlen(buf);
209                         while (len > 2 && buf[len-1] == '0')
210                                 len--;
211                         buf[len] = '\0';
212                         parg.p_string = buf;
213                         error("Position target at screen position %s", &parg);
214                 }
215                 break;
216         }
217 }
218
219         public void
220 calc_jump_sline()
221 {
222         if (jump_sline_fraction < 0)
223                 return;
224         jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM;
225 }
226
227 /*
228  * Handlers for -# option.
229  */
230         public void
231 opt_shift(type, s)
232         int type;
233         char *s;
234 {
235         PARG parg;
236         char buf[16];
237         int len;
238         int err;
239
240         switch (type)
241         {
242         case INIT:
243         case TOGGLE:
244                 if (*s == '.')
245                 {
246                         s++;
247                         shift_count_fraction = getfraction(&s, "#", &err);
248                         if (err)
249                                 error("Invalid column fraction", NULL_PARG);
250                         else
251                                 calc_shift_count();
252                 } else
253                 {
254                         int hs = getnum(&s, "#", &err);
255                         if (err)
256                                 error("Invalid column number", NULL_PARG);
257                         else
258                         {
259                                 shift_count = hs;
260                                 shift_count_fraction = -1;
261                         }
262                 }
263                 break;
264         case QUERY:
265                 if (shift_count_fraction < 0)
266                 {
267                         parg.p_int = shift_count;
268                         error("Horizontal shift %d columns", &parg);
269                 } else
270                 {
271
272                         sprintf(buf, ".%06d", shift_count_fraction);
273                         len = strlen(buf);
274                         while (len > 2 && buf[len-1] == '0')
275                                 len--;
276                         buf[len] = '\0';
277                         parg.p_string = buf;
278                         error("Horizontal shift %s of screen width", &parg);
279                 }
280                 break;
281         }
282 }
283         public void
284 calc_shift_count()
285 {
286         if (shift_count_fraction < 0)
287                 return;
288         shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM;
289 }
290
291 #if USERFILE
292         public void
293 opt_k(type, s)
294         int type;
295         char *s;
296 {
297         PARG parg;
298
299         switch (type)
300         {
301         case INIT:
302                 if (lesskey(s, 0))
303                 {
304                         parg.p_string = s;
305                         error("Cannot use lesskey file \"%s\"", &parg);
306                 }
307                 break;
308         }
309 }
310 #endif
311
312 #if TAGS
313 /*
314  * Handler for -t option.
315  */
316         public void
317 opt_t(type, s)
318         int type;
319         char *s;
320 {
321         IFILE save_ifile;
322         POSITION pos;
323
324         switch (type)
325         {
326         case INIT:
327                 tagoption = s;
328                 /* Do the rest in main() */
329                 break;
330         case TOGGLE:
331                 if (secure)
332                 {
333                         error("tags support is not available", NULL_PARG);
334                         break;
335                 }
336                 findtag(skipsp(s));
337                 save_ifile = save_curr_ifile();
338                 /*
339                  * Try to open the file containing the tag
340                  * and search for the tag in that file.
341                  */
342                 if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION)
343                 {
344                         /* Failed: reopen the old file. */
345                         reedit_ifile(save_ifile);
346                         break;
347                 }
348                 unsave_ifile(save_ifile);
349                 jump_loc(pos, jump_sline);
350                 break;
351         }
352 }
353
354 /*
355  * Handler for -T option.
356  */
357         public void
358 opt__T(type, s)
359         int type;
360         char *s;
361 {
362         PARG parg;
363
364         switch (type)
365         {
366         case INIT:
367                 tags = s;
368                 break;
369         case TOGGLE:
370                 s = skipsp(s);
371                 tags = lglob(s);
372                 break;
373         case QUERY:
374                 parg.p_string = tags;
375                 error("Tags file \"%s\"", &parg);
376                 break;
377         }
378 }
379 #endif
380
381 /*
382  * Handler for -p option.
383  */
384         public void
385 opt_p(type, s)
386         int type;
387         register char *s;
388 {
389         switch (type)
390         {
391         case INIT:
392                 /*
393                  * Unget a search command for the specified string.
394                  * {{ This won't work if the "/" command is
395                  *    changed or invalidated by a .lesskey file. }}
396                  */
397                 plusoption = TRUE;
398                 ungetsc(s);
399                 /*
400                  * In "more" mode, the -p argument is a command,
401                  * not a search string, so we don't need a slash.
402                  */
403                 if (!less_is_more)
404                         ungetsc("/");
405                 break;
406         }
407 }
408
409 /*
410  * Handler for -P option.
411  */
412         public void
413 opt__P(type, s)
414         int type;
415         register char *s;
416 {
417         register char **proto;
418         PARG parg;
419
420         switch (type)
421         {
422         case INIT:
423         case TOGGLE:
424                 /*
425                  * Figure out which prototype string should be changed.
426                  */
427                 switch (*s)
428                 {
429                 case 's':  proto = &prproto[PR_SHORT];  s++;    break;
430                 case 'm':  proto = &prproto[PR_MEDIUM]; s++;    break;
431                 case 'M':  proto = &prproto[PR_LONG];   s++;    break;
432                 case '=':  proto = &eqproto;            s++;    break;
433                 case 'h':  proto = &hproto;             s++;    break;
434                 case 'w':  proto = &wproto;             s++;    break;
435                 default:   proto = &prproto[PR_SHORT];          break;
436                 }
437                 free(*proto);
438                 *proto = save(s);
439                 break;
440         case QUERY:
441                 parg.p_string = prproto[pr_type];
442                 error("%s", &parg);
443                 break;
444         }
445 }
446
447 /*
448  * Handler for the -b option.
449  */
450         /*ARGSUSED*/
451         public void
452 opt_b(type, s)
453         int type;
454         char *s;
455 {
456         switch (type)
457         {
458         case INIT:
459         case TOGGLE:
460                 /*
461                  * Set the new number of buffers.
462                  */
463                 ch_setbufspace(bufspace);
464                 break;
465         case QUERY:
466                 break;
467         }
468 }
469
470 /*
471  * Handler for the -i option.
472  */
473         /*ARGSUSED*/
474         public void
475 opt_i(type, s)
476         int type;
477         char *s;
478 {
479         switch (type)
480         {
481         case TOGGLE:
482                 chg_caseless();
483                 break;
484         case QUERY:
485         case INIT:
486                 break;
487         }
488 }
489
490 /*
491  * Handler for the -V option.
492  */
493         /*ARGSUSED*/
494         public void
495 opt__V(type, s)
496         int type;
497         char *s;
498 {
499         switch (type)
500         {
501         case TOGGLE:
502         case QUERY:
503                 dispversion();
504                 break;
505         case INIT:
506                 /*
507                  * Force output to stdout per GNU standard for --version output.
508                  */
509                 any_display = 1;
510                 putstr("less ");
511                 putstr(version);
512                 putstr("\nCopyright (C) 1984-2009 Mark Nudelman\n\n");
513                 putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
514                 putstr("For information about the terms of redistribution,\n");
515                 putstr("see the file named README in the less distribution.\n");
516                 putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
517                 quit(QUIT_OK);
518                 break;
519         }
520 }
521
522 #if MSDOS_COMPILER
523 /*
524  * Parse an MSDOS color descriptor.
525  */
526         static void
527 colordesc(s, fg_color, bg_color)
528         char *s;
529         int *fg_color;
530         int *bg_color;
531 {
532         int fg, bg;
533         int err;
534         
535         fg = getnum(&s, "D", &err);
536         if (err)
537         {
538                 error("Missing fg color in -D", NULL_PARG);
539                 return;
540         }
541         if (*s != '.')
542                 bg = nm_bg_color;
543         else
544         {
545                 s++;
546                 bg = getnum(&s, "D", &err);
547                 if (err)
548                 {
549                         error("Missing bg color in -D", NULL_PARG);
550                         return;
551                 }
552         }
553         if (*s != '\0')
554                 error("Extra characters at end of -D option", NULL_PARG);
555         *fg_color = fg;
556         *bg_color = bg;
557 }
558
559 /*
560  * Handler for the -D option.
561  */
562         /*ARGSUSED*/
563         public void
564 opt_D(type, s)
565         int type;
566         char *s;
567 {
568         switch (type)
569         {
570         case INIT:
571         case TOGGLE:
572                 switch (*s++)
573                 {
574                 case 'n':
575                         colordesc(s, &nm_fg_color, &nm_bg_color);
576                         break;
577                 case 'd':
578                         colordesc(s, &bo_fg_color, &bo_bg_color);
579                         break;
580                 case 'u':
581                         colordesc(s, &ul_fg_color, &ul_bg_color);
582                         break;
583                 case 'k':
584                         colordesc(s, &bl_fg_color, &bl_bg_color);
585                         break;
586                 case 's':
587                         colordesc(s, &so_fg_color, &so_bg_color);
588                         break;
589                 default:
590                         error("-D must be followed by n, d, u, k or s", NULL_PARG);
591                         break;
592                 }
593                 if (type == TOGGLE)
594                 {
595                         at_enter(AT_STANDOUT);
596                         at_exit();
597                 }
598                 break;
599         case QUERY:
600                 break;
601         }
602 }
603 #endif
604
605 /*
606  * Handler for the -x option.
607  */
608         public void
609 opt_x(type, s)
610         int type;
611         register char *s;
612 {
613         extern int tabstops[];
614         extern int ntabstops;
615         extern int tabdefault;
616         char msg[60+(4*TABSTOP_MAX)];
617         int i;
618         PARG p;
619
620         switch (type)
621         {
622         case INIT:
623         case TOGGLE:
624                 /* Start at 1 because tabstops[0] is always zero. */
625                 for (i = 1;  i < TABSTOP_MAX;  )
626                 {
627                         int n = 0;
628                         s = skipsp(s);
629                         while (*s >= '0' && *s <= '9')
630                                 n = (10 * n) + (*s++ - '0');
631                         if (n > tabstops[i-1])
632                                 tabstops[i++] = n;
633                         s = skipsp(s);
634                         if (*s++ != ',')
635                                 break;
636                 }
637                 if (i < 2)
638                         return;
639                 ntabstops = i;
640                 tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
641                 break;
642         case QUERY:
643                 strcpy(msg, "Tab stops ");
644                 if (ntabstops > 2)
645                 {
646                         for (i = 1;  i < ntabstops;  i++)
647                         {
648                                 if (i > 1)
649                                         strcat(msg, ",");
650                                 sprintf(msg+strlen(msg), "%d", tabstops[i]);
651                         }
652                         sprintf(msg+strlen(msg), " and then ");
653                 }
654                 sprintf(msg+strlen(msg), "every %d spaces",
655                         tabdefault);
656                 p.p_string = msg;
657                 error("%s", &p);
658                 break;
659         }
660 }
661
662
663 /*
664  * Handler for the -" option.
665  */
666         public void
667 opt_quote(type, s)
668         int type;
669         register char *s;
670 {
671         char buf[3];
672         PARG parg;
673
674         switch (type)
675         {
676         case INIT:
677         case TOGGLE:
678                 if (s[0] == '\0')
679                 {
680                         openquote = closequote = '\0';
681                         break;
682                 }
683                 if (s[1] != '\0' && s[2] != '\0')
684                 {
685                         error("-\" must be followed by 1 or 2 chars", NULL_PARG);
686                         return;
687                 }
688                 openquote = s[0];
689                 if (s[1] == '\0')
690                         closequote = openquote;
691                 else
692                         closequote = s[1];
693                 break;
694         case QUERY:
695                 buf[0] = openquote;
696                 buf[1] = closequote;
697                 buf[2] = '\0';
698                 parg.p_string = buf;
699                 error("quotes %s", &parg);
700                 break;
701         }
702 }
703
704 /*
705  * "-?" means display a help message.
706  * If from the command line, exit immediately.
707  */
708         /*ARGSUSED*/
709         public void
710 opt_query(type, s)
711         int type;
712         char *s;
713 {
714         switch (type)
715         {
716         case QUERY:
717         case TOGGLE:
718                 error("Use \"h\" for help", NULL_PARG);
719                 break;
720         case INIT:
721                 dohelp = 1;
722         }
723 }
724
725 /*
726  * Get the "screen window" size.
727  */
728         public int
729 get_swindow()
730 {
731         if (swindow > 0)
732                 return (swindow);
733         return (sc_height + swindow);
734 }
735