Annotation of src/usr.bin/less/optfunc.c, Revision 1.2
1.2 ! niklas 1: /* $OpenBSD$ */
! 2:
1.1 etheisen 3: /*
4: * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice in the documentation and/or other materials provided with
14: * the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
17: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
20: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
22: * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23: * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27: */
28:
29:
30: /*
31: * Handling functions for command line options.
32: *
33: * Most options are handled by the generic code in option.c.
34: * But all string options, and a few non-string options, require
35: * special handling specific to the particular option.
36: * This special processing is done by the "handling functions" in this file.
37: *
38: * Each handling function is passed a "type" and, if it is a string
39: * option, the string which should be "assigned" to the option.
40: * The type may be one of:
41: * INIT The option is being initialized from the command line.
42: * TOGGLE The option is being changed from within the program.
43: * QUERY The setting of the option is merely being queried.
44: */
45:
46: #include "less.h"
47: #include "option.h"
48:
49: extern int nbufs;
50: extern int cbufs;
51: extern int pr_type;
52: extern int nohelp;
53: extern int plusoption;
54: extern int swindow;
55: extern int sc_height;
56: extern int any_display;
57: extern char *prproto[];
58: extern char *eqproto;
59: extern IFILE curr_ifile;
60: #if LOGFILE
61: extern char *namelogfile;
62: extern int force_logfile;
63: extern int logfile;
64: #endif
65: #if TAGS
66: public char *tagoption = NULL;
67: extern char *tagfile;
68: extern char *tags;
69: extern int jump_sline;
70: #endif
71: #if MSOFTC
72: extern int nm_fg_color, nm_bg_color;
73: extern int bo_fg_color, bo_bg_color;
74: extern int ul_fg_color, ul_bg_color;
75: extern int so_fg_color, so_bg_color;
76: extern int bl_fg_color, bl_bg_color;
77: #endif
78:
79:
80: #if LOGFILE
81: /*
82: * Handler for -o option.
83: */
84: public void
85: opt_o(type, s)
86: int type;
87: char *s;
88: {
89: PARG parg;
90:
91: switch (type)
92: {
93: case INIT:
94: namelogfile = s;
95: break;
96: case TOGGLE:
97: if (ch_getflags() & CH_CANSEEK)
98: {
99: error("Input is not a pipe", NULL_PARG);
100: return;
101: }
102: if (logfile >= 0)
103: {
104: error("Log file is already in use", NULL_PARG);
105: return;
106: }
107: s = skipsp(s);
108: namelogfile = glob(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
116: {
117: parg.p_string = namelogfile;
118: error("Log file \"%s\"", &parg);
119: }
120: break;
121: }
122: }
123:
124: /*
125: * Handler for -O option.
126: */
127: public void
128: opt__O(type, s)
129: int type;
130: char *s;
131: {
132: force_logfile = TRUE;
133: opt_o(type, s);
134: }
135: #endif
136:
137: /*
138: * Handlers for -l option.
139: */
140: public void
141: opt_l(type, s)
142: int type;
143: char *s;
144: {
145: int err;
146: int n;
147: char *t;
148:
149: switch (type)
150: {
151: case INIT:
152: t = s;
153: n = getnum(&t, 'l', &err);
154: if (err || n <= 0)
155: {
156: error("Line number is required after -l", NULL_PARG);
157: return;
158: }
159: plusoption = TRUE;
160: ungetsc(s);
161: break;
162: }
163: }
164:
165: #if USERFILE
166: public void
167: opt_k(type, s)
168: int type;
169: char *s;
170: {
171: PARG parg;
172:
173: switch (type)
174: {
175: case INIT:
176: if (lesskey(s))
177: {
178: parg.p_string = s;
179: error("Cannot use lesskey file \"%s\"", &parg);
180: }
181: break;
182: }
183: }
184: #endif
185:
186: #if TAGS
187: /*
188: * Handler for -t option.
189: */
190: public void
191: opt_t(type, s)
192: int type;
193: char *s;
194: {
195: IFILE save_ifile;
196: POSITION pos;
197:
198: switch (type)
199: {
200: case INIT:
201: tagoption = s;
202: /* Do the rest in main() */
203: break;
204: case TOGGLE:
205: findtag(skipsp(s));
206: if (tagfile == NULL)
207: break;
208: save_ifile = curr_ifile;
209: if (edit(tagfile))
210: break;
211: if ((pos = tagsearch()) == NULL_POSITION)
212: {
213: if (edit_ifile(save_ifile))
214: quit(QUIT_ERROR);
215: break;
216: }
217: jump_loc(pos, jump_sline);
218: break;
219: }
220: }
221:
222: /*
223: * Handler for -T option.
224: */
225: public void
226: opt__T(type, s)
227: int type;
228: char *s;
229: {
230: PARG parg;
231:
232: switch (type)
233: {
234: case INIT:
235: tags = s;
236: break;
237: case TOGGLE:
238: s = skipsp(s);
239: tags = glob(s);
240: break;
241: case QUERY:
242: parg.p_string = tags;
243: error("Tags file \"%s\"", &parg);
244: break;
245: }
246: }
247: #endif
248:
249: /*
250: * Handler for -p option.
251: */
252: public void
253: opt_p(type, s)
254: int type;
255: register char *s;
256: {
257: switch (type)
258: {
259: case INIT:
260: /*
261: * Unget a search command for the specified string.
262: * {{ This won't work if the "/" command is
263: * changed or invalidated by a .lesskey file. }}
264: */
265: plusoption = TRUE;
266: ungetsc(s);
267: ungetsc("/");
268: break;
269: }
270: }
271:
272: /*
273: * Handler for -P option.
274: */
275: public void
276: opt__P(type, s)
277: int type;
278: register char *s;
279: {
280: register char **proto;
281: PARG parg;
282:
283: switch (type)
284: {
285: case INIT:
286: case TOGGLE:
287: /*
288: * Figure out which prototype string should be changed.
289: */
290: switch (*s)
291: {
292: case 'm': proto = &prproto[PR_MEDIUM]; s++; break;
293: case 'M': proto = &prproto[PR_LONG]; s++; break;
294: case '=': proto = &eqproto; s++; break;
295: default: proto = &prproto[PR_SHORT]; break;
296: }
297: free(*proto);
298: *proto = save(s);
299: break;
300: case QUERY:
301: parg.p_string = prproto[pr_type];
302: error("%s", &parg);
303: break;
304: }
305: }
306:
307: /*
308: * Handler for the -b option.
309: */
310: /*ARGSUSED*/
311: public void
312: opt_b(type, s)
313: int type;
314: char *s;
315: {
316: switch (type)
317: {
318: case TOGGLE:
319: case QUERY:
320: /*
321: * Allocate the new number of buffers.
322: */
323: cbufs = ch_nbuf(cbufs);
324: break;
325: case INIT:
326: break;
327: }
328: }
329:
330: /*
331: * Handler for the -i option.
332: */
333: /*ARGSUSED*/
334: public void
335: opt_i(type, s)
336: int type;
337: char *s;
338: {
339: switch (type)
340: {
341: case TOGGLE:
342: chg_caseless();
343: break;
344: case QUERY:
345: case INIT:
346: break;
347: }
348: }
349:
350: /*
351: * Handler for the -V option.
352: */
353: /*ARGSUSED*/
354: public void
355: opt__V(type, s)
356: int type;
357: char *s;
358: {
359: switch (type)
360: {
361: case TOGGLE:
362: case QUERY:
363: case INIT:
364: dispversion();
365: if (type == INIT)
366: quit(QUIT_OK);
367: break;
368: }
369: }
370:
371: #if MSOFTC
372: /*
373: *
374: */
375: static void
376: colordesc(s, fg_color, bg_color)
377: char *s;
378: int *fg_color;
379: int *bg_color;
380: {
381: int fg, bg;
382: int err;
383:
384: fg = getnum(&s, 'D', &err);
385: if (err)
386: {
387: error("Missing fg color in -D", NULL_PARG);
388: return;
389: }
390: if (*s != '.')
391: bg = 0;
392: else
393: {
394: s++;
395: bg = getnum(&s, 'D', &err);
396: if (err)
397: {
398: error("Missing fg color in -D", NULL_PARG);
399: return;
400: }
401: }
402: *fg_color = fg;
403: *bg_color = bg;
404: }
405:
406: /*
407: * Handler for the -D option.
408: */
409: /*ARGSUSED*/
410: public void
411: opt_D(type, s)
412: int type;
413: char *s;
414: {
415: switch (type)
416: {
417: case INIT:
418: case TOGGLE:
419: switch (*s++)
420: {
421: case 'n':
422: colordesc(s, &nm_fg_color, &nm_bg_color);
423: break;
424: case 'd':
425: colordesc(s, &bo_fg_color, &bo_bg_color);
426: break;
427: case 'u':
428: colordesc(s, &ul_fg_color, &ul_bg_color);
429: break;
430: case 'k':
431: colordesc(s, &bl_fg_color, &bl_bg_color);
432: break;
433: case 's':
434: colordesc(s, &so_fg_color, &so_bg_color);
435: break;
436: default:
437: error("-D must be followed by n, d, u, k or s", NULL_PARG);
438: break;
439: }
440: if (type == TOGGLE)
441: {
442: so_enter();
443: so_exit();
444: }
445: break;
446: case QUERY:
447: break;
448: }
449: }
450: #endif
451:
452: /*
453: * "-?" means display a help message.
454: * If from the command line, exit immediately.
455: */
456: /*ARGSUSED*/
457: public void
458: opt_query(type, s)
459: int type;
460: char *s;
461: {
462: if (nohelp)
463: return;
464: switch (type)
465: {
466: case QUERY:
467: case TOGGLE:
468: error("Use \"h\" for help", NULL_PARG);
469: break;
470: case INIT:
471: /*
472: * This is "less -?".
473: * It rather ungracefully grabs control,
474: * does the initializations normally done in main,
475: * shows the help file and exits.
476: */
477: raw_mode(1);
478: get_term();
479: open_getchr();
480: init();
481: any_display = TRUE;
482: help(1);
483: quit(QUIT_OK);
484: /*NOTREACHED*/
485: }
486: }
487:
488: /*
489: * Get the "screen window" size.
490: */
491: public int
492: get_swindow()
493: {
494: if (swindow > 0)
495: return (swindow);
496: return (sc_height + swindow);
497: }
498: