Annotation of src/usr.bin/less/optfunc.c, Revision 1.1.1.2
1.1 etheisen 1: /*
1.1.1.2 ! millert 2: * Copyright (C) 1984-2002 Mark Nudelman
1.1 etheisen 3: *
1.1.1.2 ! millert 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.
1.1 etheisen 6: *
1.1.1.2 ! millert 7: * For more information about less, or for information on how to
! 8: * contact the author, see the README file.
1.1 etheisen 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;
1.1.1.2 ! millert 32: extern int bufspace;
1.1 etheisen 33: extern int pr_type;
34: extern int plusoption;
35: extern int swindow;
36: extern int sc_height;
1.1.1.2 ! millert 37: extern int secure;
! 38: extern int dohelp;
1.1 etheisen 39: extern int any_display;
1.1.1.2 ! millert 40: extern char openquote;
! 41: extern char closequote;
1.1 etheisen 42: extern char *prproto[];
43: extern char *eqproto;
1.1.1.2 ! millert 44: extern char *hproto;
! 45: extern char *wproto;
1.1 etheisen 46: extern IFILE curr_ifile;
1.1.1.2 ! millert 47: extern char version[];
1.1 etheisen 48: #if LOGFILE
49: extern char *namelogfile;
50: extern int force_logfile;
51: extern int logfile;
52: #endif
53: #if TAGS
54: public char *tagoption = NULL;
55: extern char *tags;
56: extern int jump_sline;
57: #endif
1.1.1.2 ! millert 58: #if MSDOS_COMPILER
1.1 etheisen 59: extern int nm_fg_color, nm_bg_color;
60: extern int bo_fg_color, bo_bg_color;
61: extern int ul_fg_color, ul_bg_color;
62: extern int so_fg_color, so_bg_color;
63: extern int bl_fg_color, bl_bg_color;
64: #endif
65:
66:
67: #if LOGFILE
68: /*
69: * Handler for -o option.
70: */
71: public void
72: opt_o(type, s)
73: int type;
74: char *s;
75: {
76: PARG parg;
77:
1.1.1.2 ! millert 78: if (secure)
! 79: {
! 80: error("log file support is not available", NULL_PARG);
! 81: return;
! 82: }
1.1 etheisen 83: switch (type)
84: {
85: case INIT:
86: namelogfile = s;
87: break;
88: case TOGGLE:
89: if (ch_getflags() & CH_CANSEEK)
90: {
91: error("Input is not a pipe", NULL_PARG);
92: return;
93: }
94: if (logfile >= 0)
95: {
96: error("Log file is already in use", NULL_PARG);
97: return;
98: }
99: s = skipsp(s);
1.1.1.2 ! millert 100: namelogfile = lglob(s);
1.1 etheisen 101: use_logfile(namelogfile);
102: sync_logfile();
103: break;
104: case QUERY:
105: if (logfile < 0)
106: error("No log file", NULL_PARG);
107: else
108: {
109: parg.p_string = namelogfile;
110: error("Log file \"%s\"", &parg);
111: }
112: break;
113: }
114: }
115:
116: /*
117: * Handler for -O option.
118: */
119: public void
120: opt__O(type, s)
121: int type;
122: char *s;
123: {
124: force_logfile = TRUE;
125: opt_o(type, s);
126: }
127: #endif
128:
129: /*
130: * Handlers for -l option.
131: */
132: public void
133: opt_l(type, s)
134: int type;
135: char *s;
136: {
137: int err;
138: int n;
139: char *t;
140:
141: switch (type)
142: {
143: case INIT:
144: t = s;
1.1.1.2 ! millert 145: n = getnum(&t, "l", &err);
1.1 etheisen 146: if (err || n <= 0)
147: {
148: error("Line number is required after -l", NULL_PARG);
149: return;
150: }
151: plusoption = TRUE;
152: ungetsc(s);
153: break;
154: }
155: }
156:
157: #if USERFILE
158: public void
159: opt_k(type, s)
160: int type;
161: char *s;
162: {
163: PARG parg;
164:
165: switch (type)
166: {
167: case INIT:
1.1.1.2 ! millert 168: if (lesskey(s, 0))
1.1 etheisen 169: {
170: parg.p_string = s;
171: error("Cannot use lesskey file \"%s\"", &parg);
172: }
173: break;
174: }
175: }
176: #endif
177:
178: #if TAGS
179: /*
180: * Handler for -t option.
181: */
182: public void
183: opt_t(type, s)
184: int type;
185: char *s;
186: {
187: IFILE save_ifile;
188: POSITION pos;
189:
190: switch (type)
191: {
192: case INIT:
193: tagoption = s;
194: /* Do the rest in main() */
195: break;
196: case TOGGLE:
1.1.1.2 ! millert 197: if (secure)
! 198: {
! 199: error("tags support is not available", NULL_PARG);
1.1 etheisen 200: break;
1.1.1.2 ! millert 201: }
! 202: findtag(skipsp(s));
! 203: save_ifile = save_curr_ifile();
! 204: if (edit_tagfile())
1.1 etheisen 205: break;
206: if ((pos = tagsearch()) == NULL_POSITION)
207: {
1.1.1.2 ! millert 208: reedit_ifile(save_ifile);
1.1 etheisen 209: break;
210: }
1.1.1.2 ! millert 211: unsave_ifile(save_ifile);
1.1 etheisen 212: jump_loc(pos, jump_sline);
213: break;
214: }
215: }
216:
217: /*
218: * Handler for -T option.
219: */
220: public void
221: opt__T(type, s)
222: int type;
223: char *s;
224: {
225: PARG parg;
226:
227: switch (type)
228: {
229: case INIT:
230: tags = s;
231: break;
232: case TOGGLE:
233: s = skipsp(s);
1.1.1.2 ! millert 234: tags = lglob(s);
1.1 etheisen 235: break;
236: case QUERY:
237: parg.p_string = tags;
238: error("Tags file \"%s\"", &parg);
239: break;
240: }
241: }
242: #endif
243:
244: /*
245: * Handler for -p option.
246: */
247: public void
248: opt_p(type, s)
249: int type;
250: register char *s;
251: {
252: switch (type)
253: {
254: case INIT:
255: /*
256: * Unget a search command for the specified string.
257: * {{ This won't work if the "/" command is
258: * changed or invalidated by a .lesskey file. }}
259: */
260: plusoption = TRUE;
261: ungetsc(s);
262: ungetsc("/");
263: break;
264: }
265: }
266:
267: /*
268: * Handler for -P option.
269: */
270: public void
271: opt__P(type, s)
272: int type;
273: register char *s;
274: {
275: register char **proto;
276: PARG parg;
277:
278: switch (type)
279: {
280: case INIT:
281: case TOGGLE:
282: /*
283: * Figure out which prototype string should be changed.
284: */
285: switch (*s)
286: {
1.1.1.2 ! millert 287: case 's': proto = &prproto[PR_SHORT]; s++; break;
1.1 etheisen 288: case 'm': proto = &prproto[PR_MEDIUM]; s++; break;
289: case 'M': proto = &prproto[PR_LONG]; s++; break;
290: case '=': proto = &eqproto; s++; break;
1.1.1.2 ! millert 291: case 'h': proto = &hproto; s++; break;
! 292: case 'w': proto = &wproto; s++; break;
1.1 etheisen 293: default: proto = &prproto[PR_SHORT]; break;
294: }
295: free(*proto);
296: *proto = save(s);
297: break;
298: case QUERY:
299: parg.p_string = prproto[pr_type];
300: error("%s", &parg);
301: break;
302: }
303: }
304:
305: /*
306: * Handler for the -b option.
307: */
308: /*ARGSUSED*/
309: public void
310: opt_b(type, s)
311: int type;
312: char *s;
313: {
314: switch (type)
315: {
1.1.1.2 ! millert 316: case INIT:
1.1 etheisen 317: case TOGGLE:
318: /*
1.1.1.2 ! millert 319: * Set the new number of buffers.
1.1 etheisen 320: */
1.1.1.2 ! millert 321: ch_setbufspace(bufspace);
1.1 etheisen 322: break;
1.1.1.2 ! millert 323: case QUERY:
1.1 etheisen 324: break;
325: }
326: }
327:
328: /*
329: * Handler for the -i option.
330: */
331: /*ARGSUSED*/
332: public void
333: opt_i(type, s)
334: int type;
335: char *s;
336: {
337: switch (type)
338: {
339: case TOGGLE:
340: chg_caseless();
341: break;
342: case QUERY:
343: case INIT:
344: break;
345: }
346: }
347:
348: /*
349: * Handler for the -V option.
350: */
351: /*ARGSUSED*/
352: public void
353: opt__V(type, s)
354: int type;
355: char *s;
356: {
357: switch (type)
358: {
359: case TOGGLE:
360: case QUERY:
361: dispversion();
1.1.1.2 ! millert 362: break;
! 363: case INIT:
! 364: /*
! 365: * Force output to stdout per GNU standard for --version output.
! 366: */
! 367: any_display = 1;
! 368: putstr("less ");
! 369: putstr(version);
! 370: putstr("\nCopyright (C) 2002 Mark Nudelman\n\n");
! 371: putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
! 372: putstr("For information about the terms of redistribution,\n");
! 373: putstr("see the file named README in the less distribution.\n");
! 374: putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
! 375: quit(QUIT_OK);
1.1 etheisen 376: break;
377: }
378: }
379:
1.1.1.2 ! millert 380: #if MSDOS_COMPILER
1.1 etheisen 381: /*
1.1.1.2 ! millert 382: * Parse an MSDOS color descriptor.
1.1 etheisen 383: */
384: static void
385: colordesc(s, fg_color, bg_color)
386: char *s;
387: int *fg_color;
388: int *bg_color;
389: {
390: int fg, bg;
391: int err;
392:
1.1.1.2 ! millert 393: fg = getnum(&s, "D", &err);
1.1 etheisen 394: if (err)
395: {
396: error("Missing fg color in -D", NULL_PARG);
397: return;
398: }
399: if (*s != '.')
400: bg = 0;
401: else
402: {
403: s++;
1.1.1.2 ! millert 404: bg = getnum(&s, "D", &err);
1.1 etheisen 405: if (err)
406: {
407: error("Missing fg color in -D", NULL_PARG);
408: return;
409: }
410: }
1.1.1.2 ! millert 411: if (*s != '\0')
! 412: error("Extra characters at end of -D option", NULL_PARG);
1.1 etheisen 413: *fg_color = fg;
414: *bg_color = bg;
415: }
416:
417: /*
418: * Handler for the -D option.
419: */
420: /*ARGSUSED*/
421: public void
422: opt_D(type, s)
423: int type;
424: char *s;
425: {
426: switch (type)
427: {
428: case INIT:
429: case TOGGLE:
430: switch (*s++)
431: {
432: case 'n':
433: colordesc(s, &nm_fg_color, &nm_bg_color);
434: break;
435: case 'd':
436: colordesc(s, &bo_fg_color, &bo_bg_color);
437: break;
438: case 'u':
439: colordesc(s, &ul_fg_color, &ul_bg_color);
440: break;
441: case 'k':
442: colordesc(s, &bl_fg_color, &bl_bg_color);
443: break;
444: case 's':
445: colordesc(s, &so_fg_color, &so_bg_color);
446: break;
447: default:
448: error("-D must be followed by n, d, u, k or s", NULL_PARG);
449: break;
450: }
451: if (type == TOGGLE)
452: {
453: so_enter();
454: so_exit();
455: }
456: break;
457: case QUERY:
458: break;
459: }
460: }
461: #endif
462:
463: /*
1.1.1.2 ! millert 464: * Handler for the -x option.
! 465: */
! 466: public void
! 467: opt_x(type, s)
! 468: int type;
! 469: register char *s;
! 470: {
! 471: extern int tabstops[];
! 472: extern int ntabstops;
! 473: extern int tabdefault;
! 474: char msg[60+(4*TABSTOP_MAX)];
! 475: int i;
! 476: PARG p;
! 477:
! 478: switch (type)
! 479: {
! 480: case INIT:
! 481: case TOGGLE:
! 482: /* Start at 1 because tabstops[0] is always zero. */
! 483: for (i = 1; i < TABSTOP_MAX; )
! 484: {
! 485: int n = 0;
! 486: s = skipsp(s);
! 487: while (*s >= '0' && *s <= '9')
! 488: n = (10 * n) + (*s++ - '0');
! 489: if (n > tabstops[i-1])
! 490: tabstops[i++] = n;
! 491: s = skipsp(s);
! 492: if (*s++ != ',')
! 493: break;
! 494: }
! 495: if (i < 2)
! 496: return;
! 497: ntabstops = i;
! 498: tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
! 499: break;
! 500: case QUERY:
! 501: strcpy(msg, "Tab stops ");
! 502: if (ntabstops > 2)
! 503: {
! 504: for (i = 1; i < ntabstops; i++)
! 505: {
! 506: if (i > 1)
! 507: strcat(msg, ",");
! 508: sprintf(msg+strlen(msg), "%d", tabstops[i]);
! 509: }
! 510: sprintf(msg+strlen(msg), " and then ");
! 511: }
! 512: sprintf(msg+strlen(msg), "every %d spaces",
! 513: tabdefault);
! 514: p.p_string = msg;
! 515: error("%s", &p);
! 516: break;
! 517: }
! 518: }
! 519:
! 520:
! 521: /*
! 522: * Handler for the -" option.
! 523: */
! 524: public void
! 525: opt_quote(type, s)
! 526: int type;
! 527: register char *s;
! 528: {
! 529: char buf[3];
! 530: PARG parg;
! 531:
! 532: switch (type)
! 533: {
! 534: case INIT:
! 535: case TOGGLE:
! 536: if (s[0] == '\0')
! 537: {
! 538: openquote = closequote = '\0';
! 539: break;
! 540: }
! 541: if (s[1] != '\0' && s[2] != '\0')
! 542: {
! 543: error("-\" must be followed by 1 or 2 chars", NULL_PARG);
! 544: return;
! 545: }
! 546: openquote = s[0];
! 547: if (s[1] == '\0')
! 548: closequote = openquote;
! 549: else
! 550: closequote = s[1];
! 551: break;
! 552: case QUERY:
! 553: buf[0] = openquote;
! 554: buf[1] = closequote;
! 555: buf[2] = '\0';
! 556: parg.p_string = buf;
! 557: error("quotes %s", &parg);
! 558: break;
! 559: }
! 560: }
! 561:
! 562: /*
1.1 etheisen 563: * "-?" means display a help message.
564: * If from the command line, exit immediately.
565: */
566: /*ARGSUSED*/
567: public void
568: opt_query(type, s)
569: int type;
570: char *s;
571: {
572: switch (type)
573: {
574: case QUERY:
575: case TOGGLE:
576: error("Use \"h\" for help", NULL_PARG);
577: break;
578: case INIT:
1.1.1.2 ! millert 579: dohelp = 1;
1.1 etheisen 580: }
581: }
582:
583: /*
584: * Get the "screen window" size.
585: */
586: public int
587: get_swindow()
588: {
589: if (swindow > 0)
590: return (swindow);
591: return (sc_height + swindow);
592: }
593: