* clear out some warnings by gcc 9.3.1.
[alpine.git] / pico / main.c
blobcfce306479e5567ff871ae3aae1cdd848957b4df
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: main.c 1184 2008-12-16 23:52:15Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006-2008 University of Washington
8 * Copyright 2013-2020 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
20 * Program: Main stand-alone Pine Composer routines
23 * WEEMACS/PICO NOTES:
25 * 08 Jan 92 - removed PINE defines to simplify compiling
27 * 08 Apr 92 - removed PINE stub calls
31 #include "headers.h"
32 #include "../c-client/mail.h"
33 #include "../c-client/rfc822.h"
34 #include "../c-client/utf8.h"
35 #include "../pith/osdep/collate.h"
36 #include "../pith/charconv/filesys.h"
37 #include "../pith/charconv/utf8.h"
38 #include "../pith/conf.h"
41 * Useful internal prototypes
43 #ifdef _WINDOWS
44 int pico_file_drop(int, int, char *);
45 #endif
48 * this isn't defined in the library, because it's a pine global
49 * which we use for GetKey's timeout
51 int timeoutset = 0;
54 int my_timer_period = (300 * 1000);
57 * function key mappings
59 static UCS fkm[12][2] = {
60 { F1, (CTRL|'G')},
61 { F2, (CTRL|'X')},
62 { F3, (CTRL|'O')},
63 { F4, (CTRL|'J')},
64 { F5, (CTRL|'R')},
65 { F6, (CTRL|'W')},
66 { F7, (CTRL|'Y')},
67 { F8, (CTRL|'V')},
68 { F9, (CTRL|'K')},
69 { F10, (CTRL|'U')},
70 { F11, (CTRL|'C')},
71 #ifdef SPELLER
72 { F12, (CTRL|'T')}
73 #else
74 { F12, (CTRL|'D')}
75 #endif
78 char *pico_args(int, char **, int *, int *, int *);
79 void pico_args_help(void);
80 void pico_vers_help(void);
81 void pico_display_args_err(char *, char **, int);
82 #ifndef _WINDOWS
83 PCOLORS *pico_set_global_colors(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
84 void display_color_codes(void);
85 #endif /* ! _WINDOWS */
87 /* TRANSLATORS: An error message about an unknown flag (option)
88 on the command line */
89 char args_pico_missing_flag[] = N_("unknown flag \"%c\"");
90 /* TRANSLATORS: error message about command line */
91 char args_pico_missing_arg[] = N_("missing or empty argument to \"%c\" flag");
92 char args_pico_missing_arg_s[] = N_("missing or empty argument to \"%s\" flag");
93 char args_pico_missing_num[] = N_("non numeric argument for \"%c\" flag");
94 char args_pico_missing_color[] = N_("missing color for \"%s\" flag");
95 char args_pico_missing_charset[] = N_("missing character set for \"%s\" flag");
96 char args_pico_input_charset[] = N_("input character set \"%s\" is unsupported");
97 char args_pico_output_charset[] = N_("output character set \"%s\" is unsupported");
99 char *args_pico_args[] = {
100 /* TRANSLATORS: little help printed out when incorrect arguments
101 are given to pico program. */
102 N_("Possible Starting Arguments for Pico editor:"),
104 N_("\tArgument\t\tMeaning"),
105 N_("\t -e \t\tComplete - allow file name completion"),
106 N_("\t -k \t\tCut - let ^K cut from cursor position to end of line"),
107 N_("\t -a \t\tShowDot - show dot files in file browser"),
108 N_("\t -j \t\tGoto - allow 'Goto' command in file browser"),
109 N_("\t -g \t\tShow - show cursor in file browser"),
110 N_("\t -m \t\tMouse - turn on mouse support"),
111 N_("\t -x \t\tNoKeyhelp - suppress keyhelp"),
112 N_("\t -p \t\tPreserveStartStop - preserve \"start\"(^Q) and \"stop\"(^S) characters"),
113 N_("\t -q \t\tTermdefWins - termcap or terminfo takes precedence over defaults"),
114 N_("\t -Q <quotestr> \tSet quote string (eg. \"> \") esp. for composing email"),
115 N_("\t -d \t\tRebind - let delete key delete current character"),
116 N_("\t -f \t\tKeys - force use of function keys"),
117 N_("\t -b \t\tReplace - allow search and replace"),
118 N_("\t -h \t\tHelp - give this list of options"),
119 N_("\t -r[#cols] \tFill - set fill column to #cols columns, default=72"),
120 N_("\t -n[#s] \tMail - notify about new mail every #s seconds, default=180"),
121 N_("\t -s <speller> \tSpeller - specify alternative speller"),
122 N_("\t -t \t\tShutdown - enable special shutdown mode"),
123 N_("\t -o <dir>\tOperation - specify the operating directory"),
124 N_("\t -z \t\tSuspend - allow use of ^Z suspension"),
125 N_("\t -w \t\tNoWrap - turn off word wrap"),
126 N_("\t -W <wordseps> \tSet word separators other than whitespace"),
127 #ifndef _WINDOWS
128 N_("\t -dcs <display_character_set> \tdefault uses LANG or LC_CTYPE from environment"),
129 N_("\t -kcs <keyboard_character_set> \tdefaults to display_character_set"),
130 N_("\t -syscs\t\tuse system-supplied translation routines"),
131 #endif /* ! _WINDOWS */
132 #ifdef _WINDOWS
133 N_("\t -dict \"dict1,dict2\" a comma separated list of dictionaries, e.g. en_US, de_DE, es_ES, etc."),
134 N_("\t -cnf color \tforeground color"),
135 N_("\t -cnb color \tbackground color"),
136 N_("\t -crf color \treverse foreground color"),
137 N_("\t -crb color \treverse background color"),
138 #endif /* _WINDOWS */
139 #ifndef _WINDOWS
140 N_("\t -color_code \tdisplay number codes for different colors"),
141 N_("\t -ncolors number \tnumber of colors for screen (8, 16, or 256)"),
142 N_("\t -ntfc number \tnumber of color of foreground text"),
143 N_("\t -ntbc number \tnumber of color of the background"),
144 N_("\t -rtfc number \tnumber of color of reverse text"),
145 N_("\t -rtbc number \tnumber of color of reverse background"),
146 N_("\t -tbfc number \tnumber of color of foreground (text) of the title bar"),
147 N_("\t -tbbc number \tnumber of color of background of the title bar"),
148 N_("\t -klfc number \tnumber of color of foreground (text) of the key label"),
149 N_("\t -klbc number \tnumber of color of background of the key label"),
150 N_("\t -knfc number \tnumber of color of foreground (text) of the key name"),
151 N_("\t -knbc number \tnumber of color of background of the key name"),
152 N_("\t -stfc number \tnumber of color of foreground (text) of the status line"),
153 N_("\t -stbc number \tnumber of color of background of the status line"),
154 N_("\t -prfc number \tnumber of color of foreground (text) of a prompt"),
155 N_("\t -prbc number \tnumber of color of background of a prompt"),
156 N_("\t -q1fc number \tnumber of color of foreground (text) of level one of quoted text"),
157 N_("\t -q1bc number \tnumber of color of background of level one of quoted text"),
158 N_("\t -q2fc number \tnumber of color of foreground (text) of level two of quoted text"),
159 N_("\t -q2bc number \tnumber of color of background of level two of quoted text"),
160 N_("\t -q3fc number \tnumber of color of foreground (text) of level three of quoted text"),
161 N_("\t -q3bc number \tnumber of color of background of level three of quoted text"),
162 N_("\t -sbfc number \tnumber of color of foreground of signature block text"),
163 N_("\t -sbbc number \tnumber of color of background of signature block text"),
164 #endif /* !_WINDOWS */
165 N_("\t +[line#] \tLine - start on line# line, default=1"),
166 N_("\t -v \t\tView - view file"),
167 N_("\t -no_setlocale_collate\tdo not do setlocale(LC_COLLATE)"),
168 N_("\t -version\tPico version number"),
169 "",
170 N_("\t All arguments may be followed by a file name to display."),
172 NULL
177 * main standalone pico routine
179 #ifdef _WINDOWS
181 app_main (int argc, char *argv[])
182 #else
184 main(int argc, char *argv[])
185 #endif
187 UCS c;
188 register int f;
189 register int n;
190 register BUFFER *bp;
191 int viewflag = FALSE; /* are we starting in view mode?*/
192 int starton = 0; /* where's dot to begin with? */
193 int setlocale_collate = 1;
194 char bname[NBUFN]; /* buffer name of file to read */
195 char *file_to_edit = NULL;
196 char *display_charmap = NULL, *dc;
197 char *keyboard_charmap = NULL;
198 int use_system = 0;
199 char *err = NULL;
201 #ifndef _WINDOWS
202 utf8_parameters(SET_UCS4WIDTH, (void *) pith_ucs4width);
203 #else /* _WINDOWS */
204 chosen_dict = -1; /* do not commit any dictionary when starting */
205 #endif /* _WINDOWS */
207 set_input_timeout(600);
208 Pmaster = NULL; /* turn OFF composer functionality */
209 km_popped = 0;
212 * Read command line flags before initializing, otherwise, we never
213 * know to init for f_keys...
215 file_to_edit = pico_args(argc, argv, &starton, &viewflag, &setlocale_collate);
217 set_collation(setlocale_collate, 1);
219 #define cpstr(s) strcpy((char *)fs_get(1+strlen(s)), s)
221 #ifdef _WINDOWS
222 init_utf8_display(1, NULL);
223 #else /* UNIX */
226 if(display_character_set)
227 display_charmap = cpstr(display_character_set);
228 #if HAVE_LANGINFO_H && defined(CODESET)
229 else if((dc = nl_langinfo_codeset_wrapper()) != NULL)
230 display_charmap = cpstr(dc);
231 #endif
233 if(!display_charmap)
234 display_charmap = cpstr("US-ASCII");
236 if(keyboard_character_set)
237 keyboard_charmap = cpstr(keyboard_character_set);
238 else
239 keyboard_charmap = cpstr(display_charmap);
242 if(use_system_translation){
243 #if PREREQ_FOR_SYS_TRANSLATION
244 use_system++;
245 /* This modifies its arguments */
246 if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
247 &input_cs, &err) == -1){
248 fprintf(stderr, "%s\n", err ? err : "trouble with character set");
249 exit(1);
251 else if(err){
252 fprintf(stderr, "%s\n", err);
253 fs_give((void **) &err);
255 #endif
258 if(!use_system){
259 if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
260 &input_cs, &err) == -1){
261 fprintf(stderr, "%s\n", err ? err : "trouble with character set");
262 exit(1);
264 else if(err){
265 fprintf(stderr, "%s\n", err);
266 fs_give((void **) &err);
270 if(keyboard_charmap){
271 set_locale_charmap(keyboard_charmap);
272 free((void *) keyboard_charmap);
275 if(display_charmap)
276 free((void *) display_charmap);
278 #endif /* UNIX */
281 * There are a couple arguments that we need to be sure
282 * are converted for internal use.
284 if(alt_speller)
285 alt_speller = cpstr(fname_to_utf8(alt_speller));
287 if(opertree && opertree[0]){
288 strncpy(opertree, fname_to_utf8(opertree), sizeof(opertree));
289 opertree[sizeof(opertree)-1] = '\0';
292 if(glo_quote_str_orig)
293 glo_quote_str = utf8_to_ucs4_cpystr(fname_to_utf8(glo_quote_str_orig));
295 if(glo_wordseps_orig)
296 glo_wordseps = utf8_to_ucs4_cpystr(fname_to_utf8(glo_wordseps_orig));
298 if(file_to_edit)
299 file_to_edit = cpstr(fname_to_utf8(file_to_edit));
301 #undef cpstr
303 #if defined(DOS) || defined(OS2)
304 if(file_to_edit){ /* strip quotes? */
305 int l;
307 if(strchr("'\"", file_to_edit[0])
308 && (l = strlen(file_to_edit)) > 1
309 && file_to_edit[l-1] == file_to_edit[0]){
310 file_to_edit[l-1] = '\0'; /* blat trailing quote */
311 file_to_edit++; /* advance past leading quote */
314 #endif
316 if(!vtinit()) /* Displays. */
317 exit(1);
319 strncpy(bname, "main", sizeof(bname)); /* default buffer name */
320 bname[sizeof(bname)-1] = '\0';
321 edinit(bname); /* Buffers, windows. */
323 update(); /* let the user know we are here */
324 sgarbf = TRUE; /* next update, repaint all */
326 #ifdef _WINDOWS
327 mswin_setwindow(NULL, NULL, NULL, NULL, NULL, NULL);
328 mswin_showwindow();
329 mswin_showcaret(1); /* turn on for main window */
330 mswin_allowpaste(MSWIN_PASTE_FULL);
331 mswin_setclosetext("Use the ^X command to exit Pico.");
332 mswin_setscrollcallback (pico_scroll_callback);
333 #endif
335 #if defined(USE_TERMCAP) || defined(USE_TERMINFO) || defined(VMS)
336 if(kbesc == NULL){ /* will arrow keys work ? */
337 (*term.t_putchar)('\007');
338 emlwrite("Warning: keypad keys may be non-functional", NULL);
340 #endif /* USE_TERMCAP/USE_TERMINFO/VMS */
342 if(file_to_edit){ /* Any file to edit? */
344 makename(bname, file_to_edit); /* set up a buffer for this file */
346 bp = curbp; /* read in first file */
347 makename(bname, file_to_edit);
348 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
349 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
351 if(strlen(file_to_edit) >= NFILEN){
352 char buf[128];
354 snprintf(buf, sizeof(buf), "Filename \"%.10s...\" too long", file_to_edit);
355 emlwrite(buf, NULL);
356 file_to_edit = NULL;
358 else{
359 strncpy(bp->b_fname, file_to_edit, sizeof(bp->b_fname));
360 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
361 if (((gmode&MDTREE) && !in_oper_tree(file_to_edit)) ||
362 readin(file_to_edit, (viewflag==FALSE), TRUE) == ABORT) {
363 if ((gmode&MDTREE) && !in_oper_tree(file_to_edit)){
364 EML eml;
365 eml.s = opertree;
366 emlwrite(_("Can't read file from outside of %s"), &eml);
369 file_to_edit = NULL;
373 if(!file_to_edit){
374 strncpy(bp->b_bname, "main", sizeof(bp->b_bname));
375 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
376 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
377 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
380 bp->b_dotp = bp->b_linep;
381 bp->b_doto = 0;
383 if (viewflag) /* set the view mode */
384 bp->b_mode |= MDVIEW;
387 /* setup to process commands */
388 lastflag = 0; /* Fake last flags. */
389 curbp->b_mode |= gmode; /* and set default modes*/
391 curwp->w_flag |= WFMODE; /* and force an update */
393 if(timeoutset){
394 EML eml;
396 eml.s = comatose(get_input_timeout());
397 emlwrite(_("Checking for new mail every %s seconds"), &eml);
401 forwline(0, starton - 1); /* move dot to specified line */
403 while(1){
405 if(Pcolors)
406 pico_set_colorp(Pcolors->ntcp, PSC_NONE);
408 if(km_popped){
409 km_popped--;
410 if(km_popped == 0) /* cause bottom three lines to be repainted */
411 curwp->w_flag |= WFHARD;
414 if(km_popped){ /* temporarily change to cause menu to be painted */
415 term.t_mrow = 2;
416 curwp->w_ntrows -= 2;
417 curwp->w_flag |= WFMODE;
418 movecursor(term.t_nrow-2, 0); /* clear status line, too */
419 peeol();
422 update(); /* Fix up the screen */
423 if(km_popped){
424 term.t_mrow = 0;
425 curwp->w_ntrows += 2;
428 #ifdef MOUSE
429 #ifdef EX_MOUSE
430 /* New mouse function for real mouse text seletion. */
431 register_mfunc(mouse_in_pico, 2, 0, term.t_nrow - (term.t_mrow + 1),
432 term.t_ncol);
433 #else
434 mouse_in_content(KEY_MOUSE, -1, -1, 0, 0);
435 register_mfunc(mouse_in_content, 2, 0, term.t_nrow - (term.t_mrow + 1),
436 term.t_ncol);
437 #endif
438 #endif
439 #ifdef _WINDOWS
440 mswin_setdndcallback (pico_file_drop);
441 mswin_mousetrackcallback(pico_cursor);
442 #endif
443 c = GetKey();
444 #ifdef MOUSE
445 #ifdef EX_MOUSE
446 clear_mfunc(mouse_in_pico);
447 #else
448 clear_mfunc(mouse_in_content);
449 #endif
450 #endif
451 #ifdef _WINDOWS
452 mswin_cleardndcallback ();
453 mswin_mousetrackcallback(NULL);
454 #endif
456 if(timeoutset && (c == NODATA || time_to_check())){
457 if(pico_new_mail())
458 emlwrite(_("You may possibly have new mail."), NULL);
461 if(km_popped)
462 switch(c){
463 case NODATA:
464 case (CTRL|'L'):
465 km_popped++;
466 break;
468 default:
469 /* clear bottom three lines */
470 mlerase();
471 break;
474 if(c == NODATA)
475 continue;
477 if(mpresf){ /* erase message line? */
478 if(mpresf++ > MESSDELAY)
479 mlerase();
482 f = FALSE;
483 n = 1;
485 #ifdef MOUSE
486 clear_mfunc(mouse_in_content);
487 #endif
488 /* Do it. */
489 execute(normalize_cmd(c, fkm, 1), f, n);
493 #ifndef _WINDOWS
494 void
495 display_color_codes(void)
497 #define SPACES " "
498 int i, j, k, l, a, len, len_entry, row;
499 int ncolors;
500 COLOR_PAIR *lastc = NULL, *newcp;
501 char *fg;
503 /* this is the format "SPACE COLORED_SPACES = CODE SPACE" */
504 vtterminalinfo(gmode & MDTCAPWINS);
505 (*term.t_open)();
506 (*term.t_rev)(FALSE);
508 pico_toggle_color(0);
509 if((ncolors = pico_count_in_color_table()) <= 0){
510 fprintf(stderr, "%s", "Your screen does not support colors\r\n");
511 exit(1);
514 if(term.t_ncol < 62 || term.t_nrow < 23){
515 fprintf(stderr, "%s", "Screen must have at least 24 rows and 63 columns\r\n");
516 exit(1);
519 if(ncolors & 1) ncolors--; /* eliminate transparent colors at this time */
521 fprintf(stdout, "%s", "The code of a color is the number in the same row plus\r\n");
522 fprintf(stdout, "%s", "the number in the same column as that color.\r\n\r\n");
524 lastc = pico_get_cur_color();
525 switch(ncolors){
526 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
527 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
528 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
529 default : fprintf(stderr, "Unknown number of colors %d\n", ncolors);
530 exit(1);
531 break;
534 pico_toggle_color(1);
535 if(ncolors < 256){
536 for(k = -1; 16*k < ncolors; k++){
537 for(l = -1; l < ncolors; l++){
538 if(k == -1){
539 if(l == -1)
540 fprintf(stdout, "%s", " ");
541 else
542 fprintf(stdout, "%3d", l);
544 else{
545 if(l == -1){
546 pico_toggle_color(1);
547 fprintf(stdout, "%3d ", k);
549 else{
550 if(ncolors || l < 8){
551 i = 16*k + l;
552 newcp = new_color_pair(colorx(0), colorx(i));
553 pico_set_colorp(newcp, PSC_NONE);
554 fprintf(stdout, "%s", SPACES);
555 pico_set_colorp(lastc, PSC_NONE);
560 pico_toggle_color(0);
561 if(k == -1)
562 fprintf(stdout, " (%d colors)", ncolors);
563 fprintf(stdout, "%s", "\r\n");
565 } else {
566 fprintf(stdout, "%s", "Codes for terminal with 256 colors:\r\n");
567 a = 16;
568 for(k = -1; 36*k < ncolors; k++){
569 for(l = -1; l < ncolors && l < 16; l++){
570 if(k == -1){
571 if(l == -1)
572 fprintf(stdout, "%s", " ");
573 else
574 fprintf(stdout, "%3d", l);
576 else{
577 if(l == -1){
578 pico_toggle_color(1);
579 fprintf(stdout, "%3d ", 36*k);
581 else{
582 i = 36*k + l;
583 newcp = new_color_pair(colorx(0), colorx(i));
584 pico_set_colorp(newcp, PSC_NONE);
585 fprintf(stdout, "%s", SPACES);
586 pico_set_colorp(lastc, PSC_NONE);
590 pico_toggle_color(0);
591 fprintf(stdout, "%s", "\r\n");
593 a = 20;
594 for(k = -1; 16 + 36*k < ncolors; k++){
595 for(l = -1; l < ncolors && l < a; l++){
596 if(k == -1){
597 if(l == -1)
598 fprintf(stdout, "%s", " ");
599 else
600 fprintf(stdout, "%3d", l);
602 else{
603 if(l == -1){
604 pico_toggle_color(1);
605 fprintf(stdout, "%3d ", 16 + 36*k);
607 else{
608 i = 16 + 36*k + l;
609 newcp = new_color_pair(colorx(0), colorx(i));
610 pico_set_colorp(newcp, PSC_NONE);
611 fprintf(stdout, "%s", SPACES);
612 pico_set_colorp(lastc, PSC_NONE);
616 pico_toggle_color(0);
617 fprintf(stdout, "%s", "\r\n");
620 pico_set_colorp(lastc, PSC_NONE);
622 #endif /* ! _WINDOWS */
626 * Parse the command line args.
628 * Args ac
629 * av
630 * starton -- place to return starton value
631 * viewflag -- place to return viewflag value
633 * Result: command arguments parsed
634 * possible printing of help for command line
635 * various global flags set
636 * returns the name of any file to open, else NULL
638 char *
639 pico_args(int ac, char **av, int *starton, int *viewflag, int *setlocale_collate)
641 int c, usage = 0;
642 char *str;
643 char tmp_1k_buf[1000]; /* tmp buf to contain err msgs */
644 #ifndef _WINDOWS
645 int ncolors, ntfc, ntbc, rtfc, rtbc;
646 int tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc;
647 int q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc;
649 ncolors = 0;
650 ntfc = ntbc = rtfc = rtbc = tbfc = tbbc = klfc = klbc = knfc =
651 knbc = stfc = stbc = prfc = prbc = q1fc = q1bc = q2fc = q2bc =
652 q3fc = q3bc = sbfc = sbbc = -1;
653 #endif /* ! _WINDOWS */
655 Loop:
656 /* while more arguments with leading - or + */
657 while(--ac > 0 && (**++av == '-' || **av == '+')){
658 if(**av == '+'){
659 if(*++*av)
660 str = *av;
661 else if(--ac)
662 str = *++av;
663 else{
664 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '+');
665 pico_display_args_err(tmp_1k_buf, NULL, 1);
666 usage++;
667 goto Loop;
670 if(!isdigit((unsigned char)str[0])){
671 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '+');
672 pico_display_args_err(tmp_1k_buf, NULL, 1);
673 usage++;
676 if(starton)
677 *starton = atoi(str);
679 goto Loop;
682 /* while more chars in this argument */
683 else while(*++*av){
685 if(strcmp(*av, "version") == 0){
686 pico_vers_help();
688 #ifndef _WINDOWS /* color configuration disabled in Windows at this time */
689 else if(strcmp(*av, "ntfc") == 0
690 || strcmp(*av, "ntbc") == 0
691 || strcmp(*av, "rtfc") == 0
692 || strcmp(*av, "rtbc") == 0
693 || strcmp(*av, "tbfc") == 0
694 || strcmp(*av, "tbbc") == 0
695 || strcmp(*av, "klfc") == 0
696 || strcmp(*av, "klbc") == 0
697 || strcmp(*av, "knfc") == 0
698 || strcmp(*av, "knbc") == 0
699 || strcmp(*av, "stfc") == 0
700 || strcmp(*av, "stbc") == 0
701 || strcmp(*av, "prfc") == 0
702 || strcmp(*av, "prbc") == 0
703 || strcmp(*av, "q1fc") == 0
704 || strcmp(*av, "q1bc") == 0
705 || strcmp(*av, "q2fc") == 0
706 || strcmp(*av, "q2bc") == 0
707 || strcmp(*av, "q3fc") == 0
708 || strcmp(*av, "q3bc") == 0
709 || strcmp(*av, "sbfc") == 0
710 || strcmp(*av, "sbbc") == 0
711 || strcmp(*av, "ncolors") == 0){
712 str = *av;
713 if(--ac)
714 ++av;
715 else{
716 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '-');
717 pico_display_args_err(tmp_1k_buf, NULL, 1);
718 usage++;
719 goto Loop;
722 if(!isdigit((unsigned char)**av)){
723 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '-');
724 pico_display_args_err(tmp_1k_buf, NULL, 1);
725 usage++;
727 if(strcmp(str, "ntfc") == 0) ntfc = atoi(*av);
728 else if (strcmp(str, "ntbc") == 0) ntbc = atoi(*av);
729 else if (strcmp(str, "rtfc") == 0) rtfc = atoi(*av);
730 else if (strcmp(str, "rtbc") == 0) rtbc = atoi(*av);
731 else if (strcmp(str, "tbfc") == 0) tbfc = atoi(*av);
732 else if (strcmp(str, "tbbc") == 0) tbbc = atoi(*av);
733 else if (strcmp(str, "klfc") == 0) klfc = atoi(*av);
734 else if (strcmp(str, "klbc") == 0) klbc = atoi(*av);
735 else if (strcmp(str, "knfc") == 0) knfc = atoi(*av);
736 else if (strcmp(str, "knbc") == 0) knbc = atoi(*av);
737 else if (strcmp(str, "stfc") == 0) stfc = atoi(*av);
738 else if (strcmp(str, "stbc") == 0) stbc = atoi(*av);
739 else if (strcmp(str, "prfc") == 0) prfc = atoi(*av);
740 else if (strcmp(str, "prbc") == 0) prbc = atoi(*av);
741 else if (strcmp(str, "q1fc") == 0) q1fc = atoi(*av);
742 else if (strcmp(str, "q1bc") == 0) q1bc = atoi(*av);
743 else if (strcmp(str, "q2fc") == 0) q2fc = atoi(*av);
744 else if (strcmp(str, "q2bc") == 0) q2bc = atoi(*av);
745 else if (strcmp(str, "q3fc") == 0) q3fc = atoi(*av);
746 else if (strcmp(str, "q3bc") == 0) q3bc = atoi(*av);
747 else if (strcmp(str, "sbfc") == 0) sbfc = atoi(*av);
748 else if (strcmp(str, "sbbc") == 0) sbbc = atoi(*av);
749 else if (strcmp(str, "ncolors") == 0) ncolors = atoi(*av);
750 if(!strcmp(str, "ncolors")){
751 switch(ncolors){
752 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
753 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
754 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
755 default : snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _("Unsupported number of colors: %d"), ncolors);
756 pico_display_args_err(tmp_1k_buf, NULL, 1);
757 exit(1);
758 break;
761 goto Loop;
763 else if(strcmp(*av, "color_code") == 0){
764 display_color_codes();
765 exit(0);
767 #endif /* ! _WINDOWS */
768 else if(strcmp(*av, "no_setlocale_collate") == 0){
769 *setlocale_collate = 0;
770 goto Loop;
772 #ifndef _WINDOWS
773 else if(strcmp(*av, "syscs") == 0){
774 use_system_translation = !use_system_translation;
775 goto Loop;
777 #endif /* ! _WINDOWS */
778 #ifdef _WINDOWS
779 else if(strcmp(*av, "dict") == 0){
780 char *cmd = *av; /* save it to use below */
781 str = *++av;
782 if(--ac){
783 int i = 0;
784 char *s;
785 #define MAX_DICTIONARY 10
786 while(str && *str){
787 if(dictionary == NULL){
788 dictionary = fs_get((MAX_DICTIONARY + 1)*sizeof(char *));
789 memset((void *) dictionary, 0, (MAX_DICTIONARY+1)*sizeof(char *));
790 if(dictionary == NULL)
791 goto Loop; /* get out of here */
793 if((s = strpbrk(str, " ,")) != NULL)
794 *s++ = '\0';
795 dictionary[i] = fs_get(strlen(str) + 1);
796 strcpy(dictionary[i++], str);
797 if(s != NULL)
798 for(; *s && (*s == ' ' || *s == ','); s++);
799 else
800 goto Loop;
801 if(i == MAX_DICTIONARY + 1)
802 goto Loop;
803 else
804 str = s;
807 else{
808 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg_s), cmd);
809 pico_display_args_err(tmp_1k_buf, NULL, 1);
810 usage++;
813 goto Loop;
815 else if(strcmp(*av, "cnf") == 0
816 || strcmp(*av, "cnb") == 0
817 || strcmp(*av, "crf") == 0
818 || strcmp(*av, "crb") == 0){
820 char *cmd = *av; /* save it to use below */
822 if(--ac){
823 str = *++av;
824 if(cmd[1] == 'n'){
825 if(cmd[2] == 'f')
826 pico_nfcolor(str);
827 else if(cmd[2] == 'b')
828 pico_nbcolor(str);
830 else if(cmd[1] == 'r'){
831 if(cmd[2] == 'f')
832 pico_rfcolor(str);
833 else if(cmd[2] == 'b')
834 pico_rbcolor(str);
837 else{
838 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_color), cmd);
839 pico_display_args_err(tmp_1k_buf, NULL, 1);
840 usage++;
843 goto Loop;
845 #endif /* _WINDOWS */
846 #ifndef _WINDOWS
847 else if(strcmp(*av, "dcs") == 0 || strcmp(*av, "kcs") == 0){
848 char *cmd = *av;
850 if(--ac){
851 if(strcmp(*av, "dcs") == 0){
852 display_character_set = *++av;
853 if(!output_charset_is_supported(display_character_set)){
854 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_output_charset), display_character_set);
855 pico_display_args_err(tmp_1k_buf, NULL, 1);
856 usage++;
859 else{
860 keyboard_character_set = *++av;
861 if(!input_charset_is_supported(keyboard_character_set)){
862 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_input_charset), keyboard_character_set);
863 pico_display_args_err(tmp_1k_buf, NULL, 1);
864 usage++;
868 else{
869 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_charset), cmd);
870 pico_display_args_err(tmp_1k_buf, NULL, 1);
871 usage++;
874 goto Loop;
876 #endif /* ! _WINDOWS */
879 * Single char options.
881 switch(c = **av){
883 * These don't take arguments.
885 case 'a':
886 gmode ^= MDDOTSOK; /* show dot files */
887 break;
888 case 'b':
889 #ifdef notdef
891 * Make MDREPLACE always on instead
892 * Don't leave this to allow turning off of MDREPLACE because the
893 * polarity of -b will have changed. Don't think anybody wants to
894 * turn it off.
896 gmode ^= MDREPLACE; /* -b for replace string in where is command */
897 #endif
898 break;
899 case 'd': /* -d for rebind delete key */
900 bindtokey(0x7f, forwdel);
901 break;
902 case 'e': /* file name completion */
903 gmode ^= MDCMPLT;
904 break;
905 case 'f': /* -f for function key use */
906 gmode ^= MDFKEY;
907 break;
908 case 'g': /* show-cursor in file browser */
909 gmode ^= MDSHOCUR;
910 break;
911 case 'h':
912 usage++;
913 break;
914 case 'j': /* allow "Goto" in file browser */
915 gmode ^= MDGOTO;
916 break;
917 case 'k': /* kill from dot */
918 gmode ^= MDDTKILL;
919 break;
920 case 'm': /* turn on mouse support */
921 gmode ^= MDMOUSE;
922 break;
923 case 'p':
924 preserve_start_stop = 1;
925 break;
926 case 'q': /* -q for termcap takes precedence */
927 gmode ^= MDTCAPWINS;
928 break;
929 case 't': /* special shutdown mode */
930 gmode ^= MDTOOL;
931 rebindfunc(wquit, quickexit);
932 break;
933 case 'v': /* -v for View File */
934 case 'V':
935 *viewflag = !*viewflag;
936 break; /* break back to inner-while */
937 case 'w': /* -w turn off word wrap */
938 gmode ^= MDWRAP;
939 break;
940 case 'x': /* suppress keyhelp */
941 sup_keyhelp = !sup_keyhelp;
942 break;
943 case 'z': /* -z to suspend */
944 gmode ^= MDSSPD;
945 break;
948 * These do take arguments.
950 case 'r': /* set fill column */
951 case 'n': /* -n for new mail notification */
952 case 's' : /* speller */
953 case 'o' : /* operating tree */
954 case 'Q' : /* Quote string */
955 case 'W' : /* Word separators */
956 if(*++*av)
957 str = *av;
958 else if(--ac)
959 str = *++av;
960 else{
961 if(c == 'r')
962 str= "72";
963 else if(c == 'n')
964 str = "180";
965 else{
966 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), c);
967 pico_display_args_err(tmp_1k_buf, NULL, 1);
968 usage++;
969 goto Loop;
973 switch(c){
974 case 's':
975 alt_speller = str;
976 break;
977 case 'o':
978 strncpy(opertree, str, NLINE);
979 gmode ^= MDTREE;
980 break;
981 case 'Q':
982 glo_quote_str_orig = str;
983 break;
984 case 'W':
985 glo_wordseps_orig = str;
986 break;
988 /* numeric args */
989 case 'r':
990 case 'n':
991 if(!isdigit((unsigned char)str[0])){
992 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), c);
993 pico_display_args_err(tmp_1k_buf, NULL, 1);
994 usage++;
997 if(c == 'r'){
998 if((userfillcol = atoi(str)) < 1)
999 userfillcol = 72;
1001 else{
1002 timeoutset = 1;
1003 set_input_timeout(180);
1004 if(set_input_timeout(atoi(str)) < 30)
1005 set_input_timeout(180);
1008 break;
1011 goto Loop;
1013 default: /* huh? */
1014 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_flag), c);
1015 pico_display_args_err(tmp_1k_buf, NULL, 1);
1016 usage++;
1017 break;
1022 if(usage)
1023 pico_args_help();
1025 #ifndef _WINDOWS
1026 Pcolors = pico_set_global_colors(ncolors, ntfc, ntbc, rtfc, rtbc,
1027 tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc,
1028 q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc);
1030 if(Pcolors)
1031 pico_toggle_color(1);
1032 #endif /* ! _WINDOWS */
1034 /* return the first filename for editing */
1035 if(ac > 0)
1036 return(*av);
1037 else
1038 return(NULL);
1042 #ifndef _WINDOWS
1043 PCOLORS *
1044 pico_set_global_colors(int nc, int ntfg, int ntbg, int rtfg, int rtbg,
1045 int tbfg, int tbbg, int klfg, int klbg,
1046 int knfg, int knbg, int stfg, int stbg, int prfg, int prbg,
1047 int q1fg, int q1bg, int q2fg, int q2bg, int q3fg, int q3bg,
1048 int sbfg, int sbbg)
1050 PCOLORS *pcolors = NULL;
1051 char *fg, *bg;
1053 if(nc != 0 && nc != 8 && nc != 16 && nc != 256){
1054 fprintf(stderr, "number of colors must be either 8, 16 or 256\n");
1055 exit(1);
1058 if(nc == 0){
1059 if(ntfg != -1 || ntbg != -1 || tbfg != -1 || tbbg != -1 ||
1060 klfg != -1 || klbg != -1 || knfg != -1 || knbg != -1 ||
1061 stfg != -1 || stbg != -1 || prfg != -1 || prbg != -1 ||
1062 q1fg != -1 || q1bg != -1 || q2fg != -1 || q1bg != -1 ||
1063 q3fg != -1 || q3bg != -1 || sbfg != -1 || sbbg != -1 ||
1064 rtfg != -1 || rtbg != -1){
1065 fprintf(stderr, "can not specify color numbers without specifying number of colors\n");
1066 exit(1);
1068 else
1069 return pcolors; /* no colors used */
1072 if(ntfg >= nc || ntbg >= nc || tbfg >= nc || tbbg >= nc
1073 || klfg >= nc || klbg >= nc || knfg >= nc || knbg >= nc
1074 || stfg >= nc || stbg >= nc || prfg >= nc || prbg >= nc
1075 || q1fg >= nc || q1bg >= nc || q2fg >= nc || q2bg >= nc
1076 || q3fg >= nc || q3bg >= nc || sbfg >= nc || sbbg >= nc
1077 || rtfg >= nc || rtbg >= nc){
1078 fprintf(stderr, "Error: specified a color bigger than number of colors\n");
1079 exit(1);
1082 /* Finally, we set up colors */
1083 pico_toggle_color(0);
1084 switch(nc){
1085 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
1086 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
1087 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
1088 default : break; /* impossible case */
1090 pico_toggle_color(1);
1092 pcolors = (PCOLORS *) malloc(sizeof(PCOLORS));
1093 memset((void *)pcolors, 0, sizeof(PCOLORS));
1094 /* ignore bad pair settings, also we set tbcp backwards because it will
1095 * be reversed later in the modeline function, so tbcp->fg is actually
1096 * tbcp->bg and viceversa.
1098 if(ntfg >= 0 && ntbg >= 0){ /* set normal text color */
1099 fg = colorx(ntfg); bg = colorx(ntbg);
1100 pcolors->ntcp = new_color_pair(fg, bg);
1101 pico_nfcolor(fg);
1102 pico_nbcolor(bg);
1104 /* reverse means reverse of normal text */
1105 if((rtfg < 0 || rtbg < 0) && (ntfg >= 0 && ntbg >= 0)){
1106 rtfg = ntbg;
1107 rtbg = ntfg;
1109 if(rtfg >= 0 && rtbg >= 0){ /* set reverse text color */
1110 fg = colorx(rtfg); bg = colorx(rtbg);
1111 pcolors->rtcp = new_color_pair(fg, bg);
1112 pico_rfcolor(fg);
1113 pico_rbcolor(bg);
1115 /* If the user does not specify this, we will set up all
1116 * backgrounds for text to the normal text background
1118 if(ntbg >= 0){
1119 if(knbg < 0) knbg = ntbg;
1120 if(q1bg < 0) q1bg = ntbg;
1121 if(q2bg < 0) q2bg = ntbg;
1122 if(q3bg < 0) q3bg = ntbg;
1123 if(sbbg < 0) sbbg = ntbg;
1125 if(rtfg >= 0 && rtbg >= 0){ /* set default reverse */
1126 if(tbfg < 0 || tbbg < 0){ /* set titlebar colors to reverse color if any missing*/
1127 tbfg = rtfg; tbbg = rtbg;
1129 if(klfg < 0 || klbg < 0){ /* set key label colors */
1130 klfg = rtfg; klbg = rtbg;
1132 if(stfg < 0 || stbg < 0){ /* set status colors */
1133 stfg = rtfg; stbg = rtbg;
1135 if(prfg >= 0 && prbg >= 0){ /* set prompt colors */
1136 prfg = rtfg; prbg = rtbg;
1139 if(tbfg >= 0 && tbbg >= 0) /* set titlebar colors */
1140 pcolors->tbcp = new_color_pair(colorx(tbbg), colorx(tbfg));
1141 if(klfg >= 0 && klbg >= 0) /* set key label colors */
1142 pcolors->klcp = new_color_pair(colorx(klfg), colorx(klbg));
1143 if(knfg >= 0 && knbg >= 0) /* set key name colors */
1144 pcolors->kncp = new_color_pair(colorx(knfg), colorx(knbg));
1145 if(stfg >= 0 && stbg >= 0) /* set status colors */
1146 pcolors->stcp = new_color_pair(colorx(stfg), colorx(stbg));
1147 if(prfg >= 0 && prbg >= 0) /* set prompt colors */
1148 pcolors->prcp = new_color_pair(colorx(prfg), colorx(prbg));
1149 if(q1fg >= 0 && q1bg >= 0) /* set quote level 1 colors */
1150 pcolors->qlcp = new_color_pair(colorx(q1fg), colorx(q1bg));
1151 if(q2fg >= 0 && q2bg >= 0) /* set quote level 2 colors */
1152 pcolors->qllcp = new_color_pair(colorx(q2fg), colorx(q2bg));
1153 if(q3fg >= 0 && q3bg >= 0) /* set quote level 3 colors */
1154 pcolors->qlllcp = new_color_pair(colorx(q3fg), colorx(q3bg));
1155 if(sbfg >= 0 && sbbg >= 0) /* set signature block colors */
1156 pcolors->sbcp = new_color_pair(colorx(sbfg), colorx(sbbg));
1158 if(pico_usingcolor())
1159 pico_set_normal_color();
1161 return pcolors;
1163 #endif /* ! _WINDOWS */
1165 #ifdef _WINDOWS
1170 pico_file_drop(int x, int y, char *filename)
1173 * if current buffer is unchanged
1174 * *or* "new buffer" and no current text
1176 if(((curwp->w_bufp->b_flag & BFCHG) == 0)
1177 || (curwp->w_bufp->b_fname[0] == '\0'
1178 && curwp->w_bufp->b_linep == lforw(curwp->w_bufp->b_linep)
1179 && curwp->w_doto == 0)){
1180 register BUFFER *bp = curwp->w_bufp;
1181 char bname[NBUFN];
1183 makename(bname, filename);
1184 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
1185 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1186 strncpy(bp->b_fname, filename, sizeof(bp->b_fname));
1187 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1188 bp->b_flag &= ~BFCHG; /* turn off change bit */
1189 if (readin(filename, 1, 1) == ABORT) {
1190 strncpy(bp->b_bname, "", sizeof(bp->b_bname));
1191 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1192 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
1193 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1196 bp->b_dotp = bp->b_linep;
1197 bp->b_doto = 0;
1199 else{
1200 EML eml;
1202 ifile(filename);
1203 curwp->w_flag |= WFHARD;
1204 update();
1205 eml.s = filename;
1206 emlwrite("Inserted dropped file \"%s\"", &eml);
1209 curwp->w_flag |= WFHARD;
1210 update(); /* restore cursor */
1211 return(1);
1213 #endif
1216 /*----------------------------------------------------------------------
1217 print a few lines of help for command line arguments
1219 Args: none
1221 Result: prints help messages
1222 ----------------------------------------------------------------------*/
1223 void
1224 pico_args_help(void)
1226 char **a;
1227 char *pp[2];
1229 pp[1] = NULL;
1231 /** print out possible starting arguments... **/
1233 for(a=args_pico_args; a && *a; a++){
1234 pp[0] = _(*a);
1235 pico_display_args_err(NULL, pp, 0);
1238 exit(1);
1242 void
1243 pico_vers_help(void)
1245 char v0[100];
1246 char *v[2];
1248 snprintf(v0, sizeof(v0), "Pico %.50s", version);
1249 v[0] = v0;
1250 v[1] = NULL;
1252 pico_display_args_err(NULL, v, 0);
1253 exit(1);
1257 /*----------------------------------------------------------------------
1258 write argument error to the display...
1260 Args: none
1262 Result: prints help messages
1263 ----------------------------------------------------------------------*/
1264 void
1265 pico_display_args_err(char *s, char **a, int err)
1267 char errstr[256], *errp;
1268 FILE *fp = err ? stderr : stdout;
1269 #ifdef _WINDOWS
1270 char tmp_20k_buf[SIZEOF_20KBUF];
1271 #endif
1274 if(err && s)
1275 snprintf(errp = errstr, sizeof(errstr), _("Argument Error: %.200s"), s);
1276 else
1277 errp = s;
1279 #ifdef _WINDOWS
1280 if(errp)
1281 mswin_messagebox(errp, err);
1283 if(a && *a){
1284 strncpy(tmp_20k_buf, *a++, SIZEOF_20KBUF);
1285 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1286 while(a && *a){
1287 strncat(tmp_20k_buf, "\n", SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1288 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1289 strncat(tmp_20k_buf, *a++, SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1290 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1293 mswin_messagebox(tmp_20k_buf, err);
1295 #else
1296 if(errp)
1297 fprintf(fp, "%s\n", errp);
1299 while(a && *a)
1300 fprintf(fp, "%s\n", *a++);
1301 #endif