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