1 /*
2 * conf.c
3 *
4 * All rights reserved. Copyright (C) 1998 by NARITA Tomio.
5 * $Id: conf.c,v 1.16 2004/01/05 07:23:29 nrt Exp $
6 */
7 /*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <import.h>
28 #include <itable.h>
29 #include <unimap.h>
30 #include <find.h>
31 #include <display.h>
32 #include <guess.h>
33 #include <console.h>
34 #include <file.h>
35 #include <kana.h>
36 #include <decode.h>
37 #include <command.h>
38 #include <conv.h>
39 #include <uty.h>
40 #include <version.h>
41 #ifdef HAVE_SETLOCALE
42 #include <locale.h>
43 #include <guesslocale.h>
44 #endif
45 #include <begin.h>
46 #include <conf.h>
47
48 #define DEFAULT_INPUT_CODING_SYSTEM AUTOSELECT
49
50 #ifdef UNIX
51 #define DEFAULT_OUTPUT_CODING_SYSTEM EUC_JAPAN /* ja specific */
52 #define DEFAULT_KEYBOARD_CODING_SYSTEM EUC_JAPAN
53 #define DEFAULT_PATHNAME_CODING_SYSTEM EUC_JAPAN
54 #define DEFAULT_DEFAULT_CODING_SYSTEM EUC_JAPAN
55
56 #define LV_CONF ".lv"
57 #endif /* UNIX */
58
59 #ifdef MSDOS
60 #define DEFAULT_OUTPUT_CODING_SYSTEM SHIFT_JIS
61 #define DEFAULT_KEYBOARD_CODING_SYSTEM SHIFT_JIS
62 #define DEFAULT_PATHNAME_CODING_SYSTEM SHIFT_JIS
63 #define DEFAULT_DEFAULT_CODING_SYSTEM EUC_JAPAN
64
65 #define LV_CONF "_lv"
66 #endif /* MSDOS */
67
68 #define BUF_SIZE 128
69
70 #define LV_HELP "lv.hlp"
71 /*#define LV_HELP_PATH "/usr/local/lib/lv/"*/ /* now defined through make */
72
73 private byte *lvHelpFile[ 2 ];
74
ConfInitArgs(conf_t * conf)75 private void ConfInitArgs( conf_t *conf )
76 {
77 #ifdef HAVE_SETLOCALE
78 byte localeCodingSystem;
79 char dummy[6];
80 char *nl;
81 int use_locale = 1;
82
83 nl = setlocale( LC_CTYPE, "" );
84 if (NULL == nl || !strcmp("C", nl))
85 use_locale = 0;
86 else
87 localeCodingSystem = LocaleCodingSystem(dummy);
88 #endif
89
90 conf->file = NULL;
91 conf->st = NULL;
92 conf->width = -1;
93 conf->height = -1;
94 conf->options = TRUE;
95 conf->inputCodingSystem = DEFAULT_INPUT_CODING_SYSTEM;
96 #ifdef HAVE_SETLOCALE
97 if (use_locale) {
98 conf->keyboardCodingSystem = localeCodingSystem;
99 conf->outputCodingSystem = localeCodingSystem;
100 conf->pathnameCodingSystem = localeCodingSystem;
101 conf->defaultCodingSystem = localeCodingSystem;
102 } else
103 #endif
104 {
105 conf->keyboardCodingSystem = DEFAULT_KEYBOARD_CODING_SYSTEM;
106 conf->outputCodingSystem = DEFAULT_OUTPUT_CODING_SYSTEM;
107 conf->pathnameCodingSystem = DEFAULT_PATHNAME_CODING_SYSTEM;
108 conf->defaultCodingSystem = DEFAULT_DEFAULT_CODING_SYSTEM;
109 }
110 conf->keyCodingSystemVirgin = TRUE;
111
112 #ifndef MSDOS /* IF NOT DEFINED */
113 unicode_width_threshold = 0x3000; /* itable_t.h */
114 unimap_iso8859 = FALSE; /* unimap.h */
115 #endif /* MSDOS */
116
117 casefold_search = TRUE; /* find.h */
118 regexp_search = TRUE; /* find.h */
119 carefully_divide = TRUE; /* display.h */
120 adjust_charset = TRUE; /* guess.h */
121 no_scroll = TRUE; /* console.h */
122
123 allow_unify = FALSE; /* itable_t.h */
124 allow_ansi_esc = FALSE; /* console.h */
125 line_number = FALSE; /* conv.h */
126 grep_inverted = FALSE; /* conv.h */
127 kana_conv = FALSE; /* kana.h */
128 smooth_paging = FALSE; /* display.h */
129 hz_detection = FALSE; /* decode.h */
130
131 ConsoleResetAnsiSequence();
132 }
133
UnknownOption(byte * s,byte * location)134 private void UnknownOption( byte *s, byte *location )
135 {
136 fprintf( stderr, "lv: unknown option %s in %s\n", s, location );
137 exit( -1 );
138 }
139
SetCodingSystem(byte * s,byte * codingSystem,byte * location)140 private void SetCodingSystem( byte *s, byte *codingSystem, byte *location )
141 {
142 switch( *( s + 1 ) ){
143 case 'e':
144 /*
145 * extended unix code
146 */
147 switch( *( s + 2 ) ){
148 case 'c': *codingSystem = EUC_CHINA; break;
149 case 'j': *codingSystem = EUC_JAPAN; break;
150 case 'k': *codingSystem = EUC_KOREA; break;
151 case 't': *codingSystem = EUC_TAIWAN; break;
152 default:
153 *codingSystem = EUC_JAPAN;
154 }
155 break;
156 case 'l':
157 /*
158 * iso-8859
159 */
160 switch( *( s + 2 ) ){
161 case '1': *codingSystem = ISO_8859_1; break;
162 case '2': *codingSystem = ISO_8859_2; break;
163 case '3': *codingSystem = ISO_8859_3; break;
164 case '4': *codingSystem = ISO_8859_4; break;
165 case '5': *codingSystem = ISO_8859_5; break;
166 case '6': *codingSystem = ISO_8859_6; break;
167 case '7': *codingSystem = ISO_8859_7; break;
168 case '8': *codingSystem = ISO_8859_8; break;
169 case '9': *codingSystem = ISO_8859_9; break;
170 case '0': *codingSystem = ISO_8859_10; break;
171 case 'b': *codingSystem = ISO_8859_11; break;
172 case 'd': *codingSystem = ISO_8859_13; break;
173 case 'e': *codingSystem = ISO_8859_14; break;
174 case 'f': *codingSystem = ISO_8859_15; break;
175 case 'g': *codingSystem = ISO_8859_16; break;
176 default:
177 *codingSystem = ISO_8859_1;
178 }
179 break;
180 case 'c': *codingSystem = ISO_2022_CN; break;
181 case 'j': *codingSystem = ISO_2022_JP; break;
182 case 'k': *codingSystem = ISO_2022_KR; break;
183 case 'm':
184 case 's': *codingSystem = SHIFT_JIS; break;
185 case 'b': *codingSystem = BIG_FIVE; break;
186 case 'h':
187 case 'z':
188 hz_detection = TRUE;
189 *codingSystem = HZ_GB; break;
190 #ifndef MSDOS /* IF NOT DEFINED */
191 case 'u':
192 switch( *( s + 2 ) ){
193 case '7': *codingSystem = UTF_7; break;
194 case '8': *codingSystem = UTF_8; break;
195 default:
196 *codingSystem = UTF_8;
197 }
198 break;
199 #endif /* MSDOS */
200 case 'r': *codingSystem = RAW; break;
201 default:
202 UnknownOption( s, location );
203 }
204 }
205
SetAnsiSequence(byte * s,byte * location)206 private void SetAnsiSequence( byte *s, byte *location )
207 {
208 switch( *( s + 1 ) ){
209 case 's': ansi_standout = TokenAlloc( s + 2 ); break;
210 case 'r': ansi_reverse = TokenAlloc( s + 2 ); break;
211 case 'b': ansi_blink = TokenAlloc( s + 2 ); break;
212 case 'u': ansi_underline = TokenAlloc( s + 2 ); break;
213 case 'h': ansi_hilight = TokenAlloc( s + 2 ); break;
214 default:
215 UnknownOption( s, location );
216 }
217 }
218
ConfArg(conf_t * conf,byte ** argv,byte * location)219 private void ConfArg( conf_t *conf, byte **argv, byte *location )
220 {
221 byte *s, quotationChar;
222 #ifdef HAVE_SETLOCALE
223 char dummy[6];
224 #endif
225
226 if( TRUE == conf->options && '-' == **argv ){
227 s = *argv + 1;
228 if( 0x00 == *s )
229 conf->options = FALSE;
230 while( *s ){
231 switch( *s ){
232 case 'A':
233 SetCodingSystem( s, &conf->inputCodingSystem, location );
234 conf->keyboardCodingSystem = conf->outputCodingSystem =
235 conf->pathnameCodingSystem = conf->defaultCodingSystem =
236 conf->inputCodingSystem;
237 break;
238 case 'I':
239 if( 'a' == *( s + 1 ) )
240 conf->inputCodingSystem = AUTOSELECT;
241 else
242 SetCodingSystem( s, &conf->inputCodingSystem, location );
243 break;
244 case 'O':
245 #ifdef HAVE_SETLOCALE
246 if( 'a' == *( s + 1 ) )
247 conf->outputCodingSystem = LocaleCodingSystem(dummy);
248 else
249 SetCodingSystem( s, &conf->outputCodingSystem, location );
250 #else
251 SetCodingSystem( s, &conf->outputCodingSystem, location );
252 #endif
253 break;
254 case 'K':
255 SetCodingSystem( s, &conf->keyboardCodingSystem, location );
256 conf->keyCodingSystemVirgin = FALSE;
257 break;
258 case 'P':
259 SetCodingSystem( s, &conf->pathnameCodingSystem, location );
260 break;
261 case 'D':
262 SetCodingSystem( s, &conf->defaultCodingSystem, location );
263 break;
264 case 'S': SetAnsiSequence( s, location ); break;
265 case 'W': conf->width = atoi( s + 1 ); break;
266 case 'H': conf->height = atoi( s + 1 ); break;
267 case 'E':
268 if( '\'' == *( s + 1 ) || '"' == *( s + 1 ) ){
269 quotationChar = *( s + 1 );
270 editor_program = TokenAlloc( s + 1 );
271 s += 2;
272 while( 0x00 != *s && quotationChar != *s )
273 s++;
274 } else {
275 editor_program = Malloc( strlen( s + 1 ) + 1 );
276 strcpy( editor_program, s + 1 );
277 }
278 break;
279 #ifndef MSDOS /* IF NOT DEFINED */
280 case 'T': unicode_width_threshold = (ic_t)atoi( s + 1 ); break;
281 case 'm': unimap_iso8859 = TRUE; s++; continue;
282 #endif /* MSDOS */
283 case 'a': adjust_charset = TRUE; s++; continue;
284 case 'c': allow_ansi_esc = TRUE; s++; continue;
285 case 'd': casefold_search = TRUE; s++; continue;
286 case 'i': casefold_search = TRUE; s++; continue;
287 case 'f': regexp_search = FALSE; s++; continue;
288 case 'g': grep_mode = TRUE; s++; continue;
289 case 'k': kana_conv = TRUE; s++; continue;
290 case 'l': carefully_divide = FALSE; s++; continue;
291 case 'n': line_number = TRUE; s++; continue;
292 case 'q': no_scroll = FALSE; s++; continue;
293 case 's': smooth_paging = TRUE; s++; continue;
294 case 'u': allow_unify = TRUE; s++; continue;
295 case 'v': grep_inverted = TRUE; s++; continue;
296 case 'z': hz_detection = TRUE; s++; continue;
297 case '+': ConfInitArgs( conf ); s++; continue;
298 case 'h': conf->file = lvHelpFile; break;
299 case 'V': Banner(); exit( 0 );
300 case SP:
301 case HT:
302 break;
303 default:
304 UnknownOption( s, location );
305 }
306 do {
307 s++;
308 if( '-' == *s || '+' == *s ){
309 s++;
310 break;
311 }
312 } while( *s );
313 }
314 } else if( TRUE == conf->options && '+' == **argv ){
315 s = *argv + 1;
316 while( *s ){
317 switch( *s ){
318 #ifndef MSDOS /* IF NOT DEFINED */
319 case 'm': unimap_iso8859 = FALSE; s++; continue;
320 #endif /* MSDOS */
321 case 'a': adjust_charset = FALSE; s++; continue;
322 case 'c': allow_ansi_esc = FALSE; s++; continue;
323 case 'd': casefold_search = FALSE; s++; continue;
324 case 'i': casefold_search = FALSE; s++; continue;
325 case 'f': regexp_search = TRUE; s++; continue;
326 case 'g': grep_mode = FALSE; s++; continue;
327 case 'k': kana_conv = FALSE; s++; continue;
328 case 'l': carefully_divide = TRUE; s++; continue;
329 case 'n': line_number = FALSE; s++; continue;
330 case 'q': no_scroll = TRUE; s++; continue;
331 case 's': smooth_paging = FALSE; s++; continue;
332 case 'u': allow_unify = FALSE; s++; continue;
333 case 'v': grep_inverted = FALSE; s++; continue;
334 case 'z': hz_detection = FALSE; s++; continue;
335 case SP:
336 case HT:
337 break;
338 default:
339 UnknownOption( s, location );
340 }
341 do {
342 s++;
343 if( '-' == *s || '+' == *s ){
344 s++;
345 break;
346 }
347 } while( *s );
348 }
349 } else {
350 if( TRUE == grep_mode && NULL == conf->pattern )
351 conf->pattern = *argv;
352 else if( NULL == conf->file )
353 conf->file = argv;
354 }
355 }
356
ConfFile(conf_t * conf,byte * file)357 private void ConfFile( conf_t *conf, byte *file )
358 {
359 FILE *fp;
360 int i;
361 byte *argv[ 1 ], buf[ BUF_SIZE ];
362
363 if( NULL == (fp = fopen( file, "r" )) )
364 return;
365
366 while( NULL != fgets( buf, BUF_SIZE, fp ) ){
367 if( '#' == *buf )
368 continue;
369 for( i = strlen( buf ) - 1 ; i >= 0 ; i-- ){
370 if( buf[ i ] < SP )
371 buf[ i ] = 0x00;
372 else
373 break;
374 }
375 *argv = buf;
376 ConfArg( conf, argv, file );
377 }
378
379 fclose( fp );
380 }
381
Conf(conf_t * conf,byte ** argv)382 public void Conf( conf_t *conf, byte **argv )
383 {
384 byte *ptr, buf[ BUF_SIZE ];
385
386 ConfInitArgs( conf );
387
388 if( NULL != (ptr = getenv( "HOME" )) ){
389 strcpy( buf, ptr );
390 strcat( buf, "/" LV_CONF );
391 ConfFile( conf, buf );
392 }
393
394 #ifdef MSDOS
395 ConfFile( conf, LV_CONF );
396 #endif
397
398 if( NULL != (*argv = getenv( "LV" )) )
399 ConfArg( conf, argv, "environment" );
400
401 conf->file = NULL;
402 conf->pattern = NULL;
403
404 while( *++argv )
405 ConfArg( conf, argv, "argument" );
406 }
407
ConfInit(byte ** argv)408 public void ConfInit( byte **argv )
409 {
410 #define helpFile (*lvHelpFile)
411 lvHelpFile[ 1 ] = NULL;
412
413 #ifdef MSDOS
414 {
415 int i;
416
417 helpFile = Malloc( strlen( argv[ 0 ] ) + strlen( LV_HELP ) + 1 );
418 strcpy( helpFile, argv[ 0 ] );
419 for( i = strlen( helpFile ) - 1 ; i >= 0 ; i-- ){
420 if( '/' == helpFile[ i ] || '\\' == helpFile[ i ] ){
421 i++;
422 break;
423 }
424 }
425 if( i < 0 ) i = 0;
426 helpFile[ i ] = NULL;
427 strcat( helpFile, LV_HELP );
428 }
429 #else
430 helpFile = Malloc( strlen( LV_HELP_PATH "/" LV_HELP ) + 1 );
431 strcpy( helpFile, LV_HELP_PATH "/" LV_HELP );
432 #endif /* MSDOS */
433 }
434
ConfFilename(conf_t * conf)435 public byte *ConfFilename( conf_t *conf )
436 {
437 byte *env;
438
439 if( NULL == conf->file ){
440 if( NULL != (env = getenv( "MAN_PN" )) )
441 return env;
442 else
443 return (byte *)"(stdin)";
444 } else {
445 return *( conf->file );
446 }
447 }
448