kernel - support dummy reallocblks in devfs
[dragonfly.git] / contrib / less / optfunc.c
blobc3bb6b2d9eb1ee67cdd96c1f701ef620278ec870
1 /*
2 * Copyright (C) 1984-2015 Mark Nudelman
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.
7 * For more information, see the README file.
8 */
12 * Handling functions for command line options.
14 * Most options are handled by the generic code in option.c.
15 * But all string options, and a few non-string options, require
16 * special handling specific to the particular option.
17 * This special processing is done by the "handling functions" in this file.
19 * Each handling function is passed a "type" and, if it is a string
20 * option, the string which should be "assigned" to the option.
21 * The type may be one of:
22 * INIT The option is being initialized from the command line.
23 * TOGGLE The option is being changed from within the program.
24 * QUERY The setting of the option is merely being queried.
27 #include "less.h"
28 #include "option.h"
30 extern int nbufs;
31 extern int bufspace;
32 extern int pr_type;
33 extern int plusoption;
34 extern int swindow;
35 extern int sc_width;
36 extern int sc_height;
37 extern int secure;
38 extern int dohelp;
39 extern int any_display;
40 extern char openquote;
41 extern char closequote;
42 extern char *prproto[];
43 extern char *eqproto;
44 extern char *hproto;
45 extern char *wproto;
46 extern char *every_first_cmd;
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 extern char ztags[];
63 #endif
64 #if MSDOS_COMPILER
65 extern int nm_fg_color, nm_bg_color;
66 extern int bo_fg_color, bo_bg_color;
67 extern int ul_fg_color, ul_bg_color;
68 extern int so_fg_color, so_bg_color;
69 extern int bl_fg_color, bl_bg_color;
70 #endif
73 #if LOGFILE
75 * Handler for -o option.
77 public void
78 opt_o(type, s)
79 int type;
80 char *s;
82 PARG parg;
84 if (secure)
86 error("log file support is not available", NULL_PARG);
87 return;
89 switch (type)
91 case INIT:
92 namelogfile = save(s);
93 break;
94 case TOGGLE:
95 if (ch_getflags() & CH_CANSEEK)
97 error("Input is not a pipe", NULL_PARG);
98 return;
100 if (logfile >= 0)
102 error("Log file is already in use", NULL_PARG);
103 return;
105 s = skipsp(s);
106 if (namelogfile != NULL)
107 free(namelogfile);
108 namelogfile = lglob(s);
109 use_logfile(namelogfile);
110 sync_logfile();
111 break;
112 case QUERY:
113 if (logfile < 0)
114 error("No log file", NULL_PARG);
115 else
117 parg.p_string = namelogfile;
118 error("Log file \"%s\"", &parg);
120 break;
125 * Handler for -O option.
127 public void
128 opt__O(type, s)
129 int type;
130 char *s;
132 force_logfile = TRUE;
133 opt_o(type, s);
135 #endif
138 * Handlers for -j option.
140 public void
141 opt_j(type, s)
142 int type;
143 char *s;
145 PARG parg;
146 char buf[16];
147 int len;
148 int err;
150 switch (type)
152 case INIT:
153 case TOGGLE:
154 if (*s == '.')
156 s++;
157 jump_sline_fraction = getfraction(&s, "j", &err);
158 if (err)
159 error("Invalid line fraction", NULL_PARG);
160 else
161 calc_jump_sline();
162 } else
164 int sline = getnum(&s, "j", &err);
165 if (err)
166 error("Invalid line number", NULL_PARG);
167 else
169 jump_sline = sline;
170 jump_sline_fraction = -1;
173 break;
174 case QUERY:
175 if (jump_sline_fraction < 0)
177 parg.p_int = jump_sline;
178 error("Position target at screen line %d", &parg);
179 } else
182 sprintf(buf, ".%06d", jump_sline_fraction);
183 len = (int) strlen(buf);
184 while (len > 2 && buf[len-1] == '0')
185 len--;
186 buf[len] = '\0';
187 parg.p_string = buf;
188 error("Position target at screen position %s", &parg);
190 break;
194 public void
195 calc_jump_sline()
197 if (jump_sline_fraction < 0)
198 return;
199 jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM;
203 * Handlers for -# option.
205 public void
206 opt_shift(type, s)
207 int type;
208 char *s;
210 PARG parg;
211 char buf[16];
212 int len;
213 int err;
215 switch (type)
217 case INIT:
218 case TOGGLE:
219 if (*s == '.')
221 s++;
222 shift_count_fraction = getfraction(&s, "#", &err);
223 if (err)
224 error("Invalid column fraction", NULL_PARG);
225 else
226 calc_shift_count();
227 } else
229 int hs = getnum(&s, "#", &err);
230 if (err)
231 error("Invalid column number", NULL_PARG);
232 else
234 shift_count = hs;
235 shift_count_fraction = -1;
238 break;
239 case QUERY:
240 if (shift_count_fraction < 0)
242 parg.p_int = shift_count;
243 error("Horizontal shift %d columns", &parg);
244 } else
247 sprintf(buf, ".%06d", shift_count_fraction);
248 len = (int) strlen(buf);
249 while (len > 2 && buf[len-1] == '0')
250 len--;
251 buf[len] = '\0';
252 parg.p_string = buf;
253 error("Horizontal shift %s of screen width", &parg);
255 break;
258 public void
259 calc_shift_count()
261 if (shift_count_fraction < 0)
262 return;
263 shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM;
266 #if USERFILE
267 public void
268 opt_k(type, s)
269 int type;
270 char *s;
272 PARG parg;
274 switch (type)
276 case INIT:
277 if (lesskey(s, 0))
279 parg.p_string = s;
280 error("Cannot use lesskey file \"%s\"", &parg);
282 break;
285 #endif
287 #if TAGS
289 * Handler for -t option.
291 public void
292 opt_t(type, s)
293 int type;
294 char *s;
296 IFILE save_ifile;
297 POSITION pos;
299 switch (type)
301 case INIT:
302 tagoption = save(s);
303 /* Do the rest in main() */
304 break;
305 case TOGGLE:
306 if (secure)
308 error("tags support is not available", NULL_PARG);
309 break;
311 findtag(skipsp(s));
312 save_ifile = save_curr_ifile();
314 * Try to open the file containing the tag
315 * and search for the tag in that file.
317 if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION)
319 /* Failed: reopen the old file. */
320 reedit_ifile(save_ifile);
321 break;
323 unsave_ifile(save_ifile);
324 jump_loc(pos, jump_sline);
325 break;
330 * Handler for -T option.
332 public void
333 opt__T(type, s)
334 int type;
335 char *s;
337 PARG parg;
339 switch (type)
341 case INIT:
342 tags = save(s);
343 break;
344 case TOGGLE:
345 s = skipsp(s);
346 if (tags != NULL && tags != ztags)
347 free(tags);
348 tags = lglob(s);
349 break;
350 case QUERY:
351 parg.p_string = tags;
352 error("Tags file \"%s\"", &parg);
353 break;
356 #endif
359 * Handler for -p option.
361 public void
362 opt_p(type, s)
363 int type;
364 register char *s;
366 switch (type)
368 case INIT:
370 * Unget a command for the specified string.
372 if (less_is_more)
375 * In "more" mode, the -p argument is a command,
376 * not a search string, so we don't need a slash.
378 every_first_cmd = save(s);
379 } else
381 plusoption = TRUE;
382 ungetcc(CHAR_END_COMMAND);
383 ungetsc(s);
385 * {{ This won't work if the "/" command is
386 * changed or invalidated by a .lesskey file. }}
388 ungetsc("/");
390 break;
395 * Handler for -P option.
397 public void
398 opt__P(type, s)
399 int type;
400 register char *s;
402 register char **proto;
403 PARG parg;
405 switch (type)
407 case INIT:
408 case TOGGLE:
410 * Figure out which prototype string should be changed.
412 switch (*s)
414 case 's': proto = &prproto[PR_SHORT]; s++; break;
415 case 'm': proto = &prproto[PR_MEDIUM]; s++; break;
416 case 'M': proto = &prproto[PR_LONG]; s++; break;
417 case '=': proto = &eqproto; s++; break;
418 case 'h': proto = &hproto; s++; break;
419 case 'w': proto = &wproto; s++; break;
420 default: proto = &prproto[PR_SHORT]; break;
422 free(*proto);
423 *proto = save(s);
424 break;
425 case QUERY:
426 parg.p_string = prproto[pr_type];
427 error("%s", &parg);
428 break;
433 * Handler for the -b option.
435 /*ARGSUSED*/
436 public void
437 opt_b(type, s)
438 int type;
439 char *s;
441 switch (type)
443 case INIT:
444 case TOGGLE:
446 * Set the new number of buffers.
448 ch_setbufspace(bufspace);
449 break;
450 case QUERY:
451 break;
456 * Handler for the -i option.
458 /*ARGSUSED*/
459 public void
460 opt_i(type, s)
461 int type;
462 char *s;
464 switch (type)
466 case TOGGLE:
467 chg_caseless();
468 break;
469 case QUERY:
470 case INIT:
471 break;
476 * Handler for the -V option.
478 /*ARGSUSED*/
479 public void
480 opt__V(type, s)
481 int type;
482 char *s;
484 switch (type)
486 case TOGGLE:
487 case QUERY:
488 dispversion();
489 break;
490 case INIT:
492 * Force output to stdout per GNU standard for --version output.
494 any_display = 1;
495 putstr("less ");
496 putstr(version);
497 putstr(" (");
498 #if HAVE_GNU_REGEX
499 putstr("GNU ");
500 #endif
501 #if HAVE_POSIX_REGCOMP
502 putstr("POSIX ");
503 #endif
504 #if HAVE_PCRE
505 putstr("PCRE ");
506 #endif
507 #if HAVE_RE_COMP
508 putstr("BSD ");
509 #endif
510 #if HAVE_REGCMP
511 putstr("V8 ");
512 #endif
513 #if HAVE_V8_REGCOMP
514 putstr("Spencer V8 ");
515 #endif
516 #if !HAVE_GNU_REGEX && !HAVE_POSIX_REGCOMP && !HAVE_PCRE && !HAVE_RE_COMP && !HAVE_REGCMP && !HAVE_V8_REGCOMP
517 putstr("no ");
518 #endif
519 putstr("regular expressions)\n");
520 putstr("Copyright (C) 1984-2015 Mark Nudelman\n\n");
521 putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
522 putstr("For information about the terms of redistribution,\n");
523 putstr("see the file named README in the less distribution.\n");
524 putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
525 quit(QUIT_OK);
526 break;
530 #if MSDOS_COMPILER
532 * Parse an MSDOS color descriptor.
534 static void
535 colordesc(s, fg_color, bg_color)
536 char *s;
537 int *fg_color;
538 int *bg_color;
540 int fg, bg;
541 int err;
543 fg = getnum(&s, "D", &err);
544 if (err)
546 error("Missing fg color in -D", NULL_PARG);
547 return;
549 if (*s != '.')
550 bg = nm_bg_color;
551 else
553 s++;
554 bg = getnum(&s, "D", &err);
555 if (err)
557 error("Missing bg color in -D", NULL_PARG);
558 return;
561 if (*s != '\0')
562 error("Extra characters at end of -D option", NULL_PARG);
563 *fg_color = fg;
564 *bg_color = bg;
568 * Handler for the -D option.
570 /*ARGSUSED*/
571 public void
572 opt_D(type, s)
573 int type;
574 char *s;
576 switch (type)
578 case INIT:
579 case TOGGLE:
580 switch (*s++)
582 case 'n':
583 colordesc(s, &nm_fg_color, &nm_bg_color);
584 break;
585 case 'd':
586 colordesc(s, &bo_fg_color, &bo_bg_color);
587 break;
588 case 'u':
589 colordesc(s, &ul_fg_color, &ul_bg_color);
590 break;
591 case 'k':
592 colordesc(s, &bl_fg_color, &bl_bg_color);
593 break;
594 case 's':
595 colordesc(s, &so_fg_color, &so_bg_color);
596 break;
597 default:
598 error("-D must be followed by n, d, u, k or s", NULL_PARG);
599 break;
601 if (type == TOGGLE)
603 at_enter(AT_STANDOUT);
604 at_exit();
606 break;
607 case QUERY:
608 break;
611 #endif
614 * Handler for the -x option.
616 public void
617 opt_x(type, s)
618 int type;
619 register char *s;
621 extern int tabstops[];
622 extern int ntabstops;
623 extern int tabdefault;
624 char msg[60+(4*TABSTOP_MAX)];
625 int i;
626 PARG p;
628 switch (type)
630 case INIT:
631 case TOGGLE:
632 /* Start at 1 because tabstops[0] is always zero. */
633 for (i = 1; i < TABSTOP_MAX; )
635 int n = 0;
636 s = skipsp(s);
637 while (*s >= '0' && *s <= '9')
638 n = (10 * n) + (*s++ - '0');
639 if (n > tabstops[i-1])
640 tabstops[i++] = n;
641 s = skipsp(s);
642 if (*s++ != ',')
643 break;
645 if (i < 2)
646 return;
647 ntabstops = i;
648 tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
649 break;
650 case QUERY:
651 strcpy(msg, "Tab stops ");
652 if (ntabstops > 2)
654 for (i = 1; i < ntabstops; i++)
656 if (i > 1)
657 strcat(msg, ",");
658 sprintf(msg+strlen(msg), "%d", tabstops[i]);
660 sprintf(msg+strlen(msg), " and then ");
662 sprintf(msg+strlen(msg), "every %d spaces",
663 tabdefault);
664 p.p_string = msg;
665 error("%s", &p);
666 break;
672 * Handler for the -" option.
674 public void
675 opt_quote(type, s)
676 int type;
677 register char *s;
679 char buf[3];
680 PARG parg;
682 switch (type)
684 case INIT:
685 case TOGGLE:
686 if (s[0] == '\0')
688 openquote = closequote = '\0';
689 break;
691 if (s[1] != '\0' && s[2] != '\0')
693 error("-\" must be followed by 1 or 2 chars", NULL_PARG);
694 return;
696 openquote = s[0];
697 if (s[1] == '\0')
698 closequote = openquote;
699 else
700 closequote = s[1];
701 break;
702 case QUERY:
703 buf[0] = openquote;
704 buf[1] = closequote;
705 buf[2] = '\0';
706 parg.p_string = buf;
707 error("quotes %s", &parg);
708 break;
713 * "-?" means display a help message.
714 * If from the command line, exit immediately.
716 /*ARGSUSED*/
717 public void
718 opt_query(type, s)
719 int type;
720 char *s;
722 switch (type)
724 case QUERY:
725 case TOGGLE:
726 error("Use \"h\" for help", NULL_PARG);
727 break;
728 case INIT:
729 dohelp = 1;
734 * Get the "screen window" size.
736 public int
737 get_swindow()
739 if (swindow > 0)
740 return (swindow);
741 return (sc_height + swindow);