"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "less-424/opttbl.c" of archive less-424.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /*
2 * Copyright (C) 1984-2008 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 * The option table.
14 */
15
16 #include "less.h"
17 #include "option.h"
18
19 /*
20 * Variables controlled by command line options.
21 */
22 public int quiet; /* Should we suppress the audible bell? */
23 public int how_search; /* Where should forward searches start? */
24 public int top_scroll; /* Repaint screen from top?
25 (alternative is scroll from bottom) */
26 public int pr_type; /* Type of prompt (short, medium, long) */
27 public int bs_mode; /* How to process backspaces */
28 public int know_dumb; /* Don't complain about dumb terminals */
29 public int quit_at_eof; /* Quit after hitting end of file twice */
30 public int quit_if_one_screen; /* Quit if EOF on first screen */
31 public int squeeze; /* Squeeze multiple blank lines into one */
32 public int tabstop; /* Tab settings */
33 public int back_scroll; /* Repaint screen on backwards movement */
34 public int forw_scroll; /* Repaint screen on forward movement */
35 public int caseless; /* Do "caseless" searches */
36 public int linenums; /* Use line numbers */
37 public int autobuf; /* Automatically allocate buffers as needed */
38 public int bufspace; /* Max buffer space per file (K) */
39 public int ctldisp; /* Send control chars to screen untranslated */
40 public int force_open; /* Open the file even if not regular file */
41 public int swindow; /* Size of scrolling window */
42 public int jump_sline; /* Screen line of "jump target" */
43 public long jump_sline_fraction = -1;
44 public int chopline; /* Truncate displayed lines at screen width */
45 public int no_init; /* Disable sending ti/te termcap strings */
46 public int no_keypad; /* Disable sending ks/ke termcap strings */
47 public int twiddle; /* Show tildes after EOF */
48 public int show_attn; /* Hilite first unread line */
49 public int shift_count; /* Number of positions to shift horizontally */
50 public int status_col; /* Display a status column */
51 public int use_lessopen; /* Use the LESSOPEN filter */
52 public int quit_on_intr; /* Quit on interrupt */
53 public int follow_mode; /* F cmd Follows file desc or file name? */
54 public int oldbot; /* Old bottom of screen behavior {{REMOVE}} */
55 #if HILITE_SEARCH
56 public int hilite_search; /* Highlight matched search patterns? */
57 #endif
58
59 public int less_is_more = 0; /* Make compatible with POSIX more */
60
61 /*
62 * Long option names.
63 */
64 static struct optname a_optname = { "search-skip-screen", NULL };
65 static struct optname b_optname = { "buffers", NULL };
66 static struct optname B__optname = { "auto-buffers", NULL };
67 static struct optname c_optname = { "clear-screen", NULL };
68 static struct optname d_optname = { "dumb", NULL };
69 #if MSDOS_COMPILER
70 static struct optname D__optname = { "color", NULL };
71 #endif
72 static struct optname e_optname = { "quit-at-eof", NULL };
73 static struct optname f_optname = { "force", NULL };
74 static struct optname F__optname = { "quit-if-one-screen", NULL };
75 #if HILITE_SEARCH
76 static struct optname g_optname = { "hilite-search", NULL };
77 #endif
78 static struct optname h_optname = { "max-back-scroll", NULL };
79 static struct optname i_optname = { "ignore-case", NULL };
80 static struct optname j_optname = { "jump-target", NULL };
81 static struct optname J__optname = { "status-column", NULL };
82 #if USERFILE
83 static struct optname k_optname = { "lesskey-file", NULL };
84 #endif
85 static struct optname K__optname = { "quit-on-intr", NULL };
86 static struct optname L__optname = { "no-lessopen", NULL };
87 static struct optname m_optname = { "long-prompt", NULL };
88 static struct optname n_optname = { "line-numbers", NULL };
89 #if LOGFILE
90 static struct optname o_optname = { "log-file", NULL };
91 static struct optname O__optname = { "LOG-FILE", NULL };
92 #endif
93 static struct optname p_optname = { "pattern", NULL };
94 static struct optname P__optname = { "prompt", NULL };
95 static struct optname q2_optname = { "silent", NULL };
96 static struct optname q_optname = { "quiet", &q2_optname };
97 static struct optname r_optname = { "raw-control-chars", NULL };
98 static struct optname s_optname = { "squeeze-blank-lines", NULL };
99 static struct optname S__optname = { "chop-long-lines", NULL };
100 #if TAGS
101 static struct optname t_optname = { "tag", NULL };
102 static struct optname T__optname = { "tag-file", NULL };
103 #endif
104 static struct optname u_optname = { "underline-special", NULL };
105 static struct optname V__optname = { "version", NULL };
106 static struct optname w_optname = { "hilite-unread", NULL };
107 static struct optname x_optname = { "tabs", NULL };
108 static struct optname X__optname = { "no-init", NULL };
109 static struct optname y_optname = { "max-forw-scroll", NULL };
110 static struct optname z_optname = { "window", NULL };
111 static struct optname quote_optname = { "quotes", NULL };
112 static struct optname tilde_optname = { "tilde", NULL };
113 static struct optname query_optname = { "help", NULL };
114 static struct optname pound_optname = { "shift", NULL };
115 static struct optname keypad_optname = { "no-keypad", NULL };
116 static struct optname oldbot_optname = { "old-bot", NULL };
117 static struct optname follow_optname = { "follow-name", NULL };
118
119
120 /*
121 * Table of all options and their semantics.
122 *
123 * For BOOL and TRIPLE options, odesc[0], odesc[1], odesc[2] are
124 * the description of the option when set to 0, 1 or 2, respectively.
125 * For NUMBER options, odesc[0] is the prompt to use when entering
126 * a new value, and odesc[1] is the description, which should contain
127 * one %d which is replaced by the value of the number.
128 * For STRING options, odesc[0] is the prompt to use when entering
129 * a new value, and odesc[1], if not NULL, is the set of characters
130 * that are valid in the string.
131 */
132 static struct loption option[] =
133 {
134 { 'a', &a_optname,
135 BOOL, OPT_OFF, &how_search, NULL,
136 {
137 "Search includes displayed screen",
138 "Search skips displayed screen",
139 NULL
140 }
141 },
142
143 { 'b', &b_optname,
144 NUMBER|INIT_HANDLER, 64, &bufspace, opt_b,
145 {
146 "Max buffer space per file (K): ",
147 "Max buffer space per file: %dK",
148 NULL
149 }
150 },
151 { 'B', &B__optname,
152 BOOL, OPT_ON, &autobuf, NULL,
153 {
154 "Don't automatically allocate buffers",
155 "Automatically allocate buffers when needed",
156 NULL
157 }
158 },
159 { 'c', &c_optname,
160 TRIPLE, OPT_OFF, &top_scroll, NULL,
161 {
162 "Repaint by scrolling from bottom of screen",
163 "Repaint by painting from top of screen",
164 "Repaint by painting from top of screen"
165 }
166 },
167 { 'd', &d_optname,
168 BOOL|NO_TOGGLE, OPT_OFF, &know_dumb, NULL,
169 {
170 "Assume intelligent terminal",
171 "Assume dumb terminal",
172 NULL
173 }
174 },
175 #if MSDOS_COMPILER
176 { 'D', &D__optname,
177 STRING|REPAINT|NO_QUERY, 0, NULL, opt_D,
178 {
179 "color desc: ",
180 "Ddknsu0123456789.",
181 NULL
182 }
183 },
184 #endif
185 { 'e', &e_optname,
186 TRIPLE, OPT_OFF, &quit_at_eof, NULL,
187 {
188 "Don't quit at end-of-file",
189 "Quit at end-of-file",
190 "Quit immediately at end-of-file"
191 }
192 },
193 { 'f', &f_optname,
194 BOOL, OPT_OFF, &force_open, NULL,
195 {
196 "Open only regular files",
197 "Open even non-regular files",
198 NULL
199 }
200 },
201 { 'F', &F__optname,
202 BOOL, OPT_OFF, &quit_if_one_screen, NULL,
203 {
204 "Don't quit if end-of-file on first screen",
205 "Quit if end-of-file on first screen",
206 NULL
207 }
208 },
209 #if HILITE_SEARCH
210 { 'g', &g_optname,
211 TRIPLE|HL_REPAINT, OPT_ONPLUS, &hilite_search, NULL,
212 {
213 "Don't highlight search matches",
214 "Highlight matches for previous search only",
215 "Highlight all matches for previous search pattern",
216 }
217 },
218 #endif
219 { 'h', &h_optname,
220 NUMBER, -1, &back_scroll, NULL,
221 {
222 "Backwards scroll limit: ",
223 "Backwards scroll limit is %d lines",
224 NULL
225 }
226 },
227 { 'i', &i_optname,
228 TRIPLE|HL_REPAINT, OPT_OFF, &caseless, opt_i,
229 {
230 "Case is significant in searches",
231 "Ignore case in searches",
232 "Ignore case in searches and in patterns"
233 }
234 },
235 { 'j', &j_optname,
236 STRING, 0, NULL, opt_j,
237 {
238 "Target line: ",
239 "0123456789.",
240 NULL
241 }
242 },
243 { 'J', &J__optname,
244 BOOL|REPAINT, OPT_OFF, &status_col, NULL,
245 {
246 "Don't display a status column",
247 "Display a status column",
248 NULL
249 }
250 },
251 #if USERFILE
252 { 'k', &k_optname,
253 STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_k,
254 { NULL, NULL, NULL }
255 },
256 #endif
257 { 'K', &K__optname,
258 BOOL, OPT_OFF, &quit_on_intr, NULL,
259 {
260 "Interrupt (ctrl-C) returns to prompt",
261 "Interrupt (ctrl-C) exits less",
262 NULL
263 }
264 },
265 { 'l', NULL,
266 STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_l,
267 { NULL, NULL, NULL }
268 },
269 { 'L', &L__optname,
270 BOOL, OPT_ON, &use_lessopen, NULL,
271 {
272 "Don't use the LESSOPEN filter",
273 "Use the LESSOPEN filter",
274 NULL
275 }
276 },
277 { 'm', &m_optname,
278 TRIPLE, OPT_OFF, &pr_type, NULL,
279 {
280 "Short prompt",
281 "Medium prompt",
282 "Long prompt"
283 }
284 },
285 { 'n', &n_optname,
286 TRIPLE|REPAINT, OPT_ON, &linenums, NULL,
287 {
288 "Don't use line numbers",
289 "Use line numbers",
290 "Constantly display line numbers"
291 }
292 },
293 #if LOGFILE
294 { 'o', &o_optname,
295 STRING, 0, NULL, opt_o,
296 { "log file: ", NULL, NULL }
297 },
298 { 'O', &O__optname,
299 STRING, 0, NULL, opt__O,
300 { "Log file: ", NULL, NULL }
301 },
302 #endif
303 { 'p', &p_optname,
304 STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_p,
305 { NULL, NULL, NULL }
306 },
307 { 'P', &P__optname,
308 STRING, 0, NULL, opt__P,
309 { "prompt: ", NULL, NULL }
310 },
311 { 'q', &q_optname,
312 TRIPLE, OPT_OFF, &quiet, NULL,
313 {
314 "Ring the bell for errors AND at eof/bof",
315 "Ring the bell for errors but not at eof/bof",
316 "Never ring the bell"
317 }
318 },
319 { 'r', &r_optname,
320 TRIPLE|REPAINT, OPT_OFF, &ctldisp, NULL,
321 {
322 "Display control characters as ^X",
323 "Display control characters directly",
324 "Display control characters directly, processing ANSI sequences"
325 }
326 },
327 { 's', &s_optname,
328 BOOL|REPAINT, OPT_OFF, &squeeze, NULL,
329 {
330 "Display all blank lines",
331 "Squeeze multiple blank lines",
332 NULL
333 }
334 },
335 { 'S', &S__optname,
336 BOOL|REPAINT, OPT_OFF, &chopline, NULL,
337 {
338 "Fold long lines",
339 "Chop long lines",
340 NULL
341 }
342 },
343 #if TAGS
344 { 't', &t_optname,
345 STRING|NO_QUERY, 0, NULL, opt_t,
346 { "tag: ", NULL, NULL }
347 },
348 { 'T', &T__optname,
349 STRING, 0, NULL, opt__T,
350 { "tags file: ", NULL, NULL }
351 },
352 #endif
353 { 'u', &u_optname,
354 TRIPLE|REPAINT, OPT_OFF, &bs_mode, NULL,
355 {
356 "Display underlined text in underline mode",
357 "Backspaces cause overstrike",
358 "Print backspace as ^H"
359 }
360 },
361 { 'V', &V__optname,
362 NOVAR, 0, NULL, opt__V,
363 { NULL, NULL, NULL }
364 },
365 { 'w', &w_optname,
366 TRIPLE|REPAINT, OPT_OFF, &show_attn, NULL,
367 {
368 "Don't highlight first unread line",
369 "Highlight first unread line after forward-screen",
370 "Highlight first unread line after any forward movement",
371 }
372 },
373 { 'x', &x_optname,
374 STRING|REPAINT, 0, NULL, opt_x,
375 {
376 "Tab stops: ",
377 "0123456789,",
378 NULL
379 }
380 },
381 { 'X', &X__optname,
382 BOOL|NO_TOGGLE, OPT_OFF, &no_init, NULL,
383 {
384 "Send init/deinit strings to terminal",
385 "Don't use init/deinit strings",
386 NULL
387 }
388 },
389 { 'y', &y_optname,
390 NUMBER, -1, &forw_scroll, NULL,
391 {
392 "Forward scroll limit: ",
393 "Forward scroll limit is %d lines",
394 NULL
395 }
396 },
397 { 'z', &z_optname,
398 NUMBER, -1, &swindow, NULL,
399 {
400 "Scroll window size: ",
401 "Scroll window size is %d lines",
402 NULL
403 }
404 },
405 { '"', "e_optname,
406 STRING, 0, NULL, opt_quote,
407 { "quotes: ", NULL, NULL }
408 },
409 { '~', &tilde_optname,
410 BOOL|REPAINT, OPT_ON, &twiddle, NULL,
411 {
412 "Don't show tildes after end of file",
413 "Show tildes after end of file",
414 NULL
415 }
416 },
417 { '?', &query_optname,
418 NOVAR, 0, NULL, opt_query,
419 { NULL, NULL, NULL }
420 },
421 { '#', £_optname,
422 NUMBER, 0, &shift_count, NULL,
423 {
424 "Horizontal shift: ",
425 "Horizontal shift %d positions",
426 NULL
427 }
428 },
429 { '.', &keypad_optname,
430 BOOL|NO_TOGGLE, OPT_OFF, &no_keypad, NULL,
431 {
432 "Use keypad mode",
433 "Don't use keypad mode",
434 NULL
435 }
436 },
437 { '.', &oldbot_optname,
438 BOOL, OPT_OFF, &oldbot, NULL,
439 {
440 "Use new bottom of screen behavior",
441 "Use old bottom of screen behavior",
442 NULL
443 }
444 },
445 { '.', &follow_optname,
446 BOOL, FOLLOW_DESC, &follow_mode, NULL,
447 {
448 "F command Follows file descriptor",
449 "F command Follows file name",
450 NULL
451 }
452 },
453 { '\0', NULL, NOVAR, 0, NULL, NULL, { NULL, NULL, NULL } }
454 };
455
456
457 /*
458 * Initialize each option to its default value.
459 */
460 public void
461 init_option()
462 {
463 register struct loption *o;
464 char *p;
465
466 p = lgetenv("LESS_IS_MORE");
467 if (p != NULL && *p != '\0')
468 less_is_more = 1;
469
470 for (o = option; o->oletter != '\0'; o++)
471 {
472 /*
473 * Set each variable to its default.
474 */
475 if (o->ovar != NULL)
476 *(o->ovar) = o->odefault;
477 if (o->otype & INIT_HANDLER)
478 (*(o->ofunc))(INIT, (char *) NULL);
479 }
480 }
481
482 /*
483 * Find an option in the option table, given its option letter.
484 */
485 public struct loption *
486 findopt(c)
487 int c;
488 {
489 register struct loption *o;
490
491 for (o = option; o->oletter != '\0'; o++)
492 {
493 if (o->oletter == c)
494 return (o);
495 if ((o->otype & TRIPLE) && ASCII_TO_UPPER(o->oletter) == c)
496 return (o);
497 }
498 return (NULL);
499 }
500
501 /*
502 *
503 */
504 static int
505 is_optchar(c)
506 char c;
507 {
508 if (ASCII_IS_UPPER(c))
509 return 1;
510 if (ASCII_IS_LOWER(c))
511 return 1;
512 if (c == '-')
513 return 1;
514 return 0;
515 }
516
517 /*
518 * Find an option in the option table, given its option name.
519 * p_optname is the (possibly partial) name to look for, and
520 * is updated to point after the matched name.
521 * p_oname if non-NULL is set to point to the full option name.
522 */
523 public struct loption *
524 findopt_name(p_optname, p_oname, p_err)
525 char **p_optname;
526 char **p_oname;
527 int *p_err;
528 {
529 char *optname = *p_optname;
530 register struct loption *o;
531 register struct optname *oname;
532 register int len;
533 int uppercase;
534 struct loption *maxo = NULL;
535 struct optname *maxoname = NULL;
536 int maxlen = 0;
537 int ambig = 0;
538 int exact = 0;
539
540 /*
541 * Check all options.
542 */
543 for (o = option; o->oletter != '\0'; o++)
544 {
545 /*
546 * Check all names for this option.
547 */
548 for (oname = o->onames; oname != NULL; oname = oname->onext)
549 {
550 /*
551 * Try normal match first (uppercase == 0),
552 * then, then if it's a TRIPLE option,
553 * try uppercase match (uppercase == 1).
554 */
555 for (uppercase = 0; uppercase <= 1; uppercase++)
556 {
557 len = sprefix(optname, oname->oname, uppercase);
558 if (len <= 0 || is_optchar(optname[len]))
559 {
560 /*
561 * We didn't use all of the option name.
562 */
563 continue;
564 }
565 if (!exact && len == maxlen)
566 /*
567 * Already had a partial match,
568 * and now there's another one that
569 * matches the same length.
570 */
571 ambig = 1;
572 else if (len > maxlen)
573 {
574 /*
575 * Found a better match than
576 * the one we had.
577 */
578 maxo = o;
579 maxoname = oname;
580 maxlen = len;
581 ambig = 0;
582 exact = (len == (int)strlen(oname->oname));
583 }
584 if (!(o->otype & TRIPLE))
585 break;
586 }
587 }
588 }
589 if (ambig)
590 {
591 /*
592 * Name matched more than one option.
593 */
594 if (p_err != NULL)
595 *p_err = OPT_AMBIG;
596 return (NULL);
597 }
598 *p_optname = optname + maxlen;
599 if (p_oname != NULL)
600 *p_oname = maxoname == NULL ? NULL : maxoname->oname;
601 return (maxo);
602 }