* Update to packages/alpine.spec to account for the new location of man
[alpine.git] / pico / main.c
blob274222e17afb2b124322faff3fdb6ec53357b3fb
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-2017 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 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);
83 void display_color_codes(void);
86 /* TRANSLATORS: An error message about an unknown flag (option)
87 on the command line */
88 char args_pico_missing_flag[] = N_("unknown flag \"%c\"");
89 /* TRANSLATORS: error message about command line */
90 char args_pico_missing_arg[] = N_("missing or empty argument to \"%c\" flag");
91 char args_pico_missing_num[] = N_("non numeric argument for \"%c\" flag");
92 char args_pico_missing_color[] = N_("missing color for \"%s\" flag");
93 char args_pico_missing_charset[] = N_("missing character set for \"%s\" flag");
94 char args_pico_input_charset[] = N_("input character set \"%s\" is unsupported");
95 char args_pico_output_charset[] = N_("output character set \"%s\" is unsupported");
97 char *args_pico_args[] = {
98 /* TRANSLATORS: little help printed out when incorrect arguments
99 are given to pico program. */
100 N_("Possible Starting Arguments for Pico editor:"),
102 N_("\tArgument\t\tMeaning"),
103 N_("\t -e \t\tComplete - allow file name completion"),
104 N_("\t -k \t\tCut - let ^K cut from cursor position to end of line"),
105 N_("\t -a \t\tShowDot - show dot files in file browser"),
106 N_("\t -j \t\tGoto - allow 'Goto' command in file browser"),
107 N_("\t -g \t\tShow - show cursor in file browser"),
108 N_("\t -m \t\tMouse - turn on mouse support"),
109 N_("\t -x \t\tNoKeyhelp - suppress keyhelp"),
110 N_("\t -p \t\tPreserveStartStop - preserve \"start\"(^Q) and \"stop\"(^S) characters"),
111 N_("\t -q \t\tTermdefWins - termcap or terminfo takes precedence over defaults"),
112 N_("\t -Q <quotestr> \tSet quote string (eg. \"> \") esp. for composing email"),
113 N_("\t -d \t\tRebind - let delete key delete current character"),
114 N_("\t -f \t\tKeys - force use of function keys"),
115 N_("\t -b \t\tReplace - allow search and replace"),
116 N_("\t -h \t\tHelp - give this list of options"),
117 N_("\t -r[#cols] \tFill - set fill column to #cols columns, default=72"),
118 N_("\t -n[#s] \tMail - notify about new mail every #s seconds, default=180"),
119 N_("\t -s <speller> \tSpeller - specify alternative speller"),
120 N_("\t -t \t\tShutdown - enable special shutdown mode"),
121 N_("\t -o <dir>\tOperation - specify the operating directory"),
122 N_("\t -z \t\tSuspend - allow use of ^Z suspension"),
123 N_("\t -w \t\tNoWrap - turn off word wrap"),
124 N_("\t -W <wordseps> \tSet word separators other than whitespace"),
125 #ifndef _WINDOWS
126 N_("\t -dcs <display_character_set> \tdefault uses LANG or LC_CTYPE from environment"),
127 N_("\t -kcs <keyboard_character_set> \tdefaults to display_character_set"),
128 N_("\t -syscs\t\tuse system-supplied translation routines"),
129 #endif /* ! _WINDOWS */
130 #ifdef _WINDOWS
131 N_("\t -cnf color \tforeground color"),
132 N_("\t -cnb color \tbackground color"),
133 N_("\t -crf color \treverse foreground color"),
134 N_("\t -crb color \treverse background color"),
135 #endif /* _WINDOWS */
136 N_("\t -color_code \tdisplay number codes for different colors"),
137 N_("\t -ncolors number \tnumber of colors for screen (8, 16, or 256)"),
138 N_("\t -ntfc number \tnumber of color of foreground text"),
139 N_("\t -ntbc number \tnumber of color of the background"),
140 N_("\t -rtfc number \tnumber of color of reverse text"),
141 N_("\t -rtbc number \tnumber of color of reverse background"),
142 N_("\t -tbfc number \tnumber of color of foreground (text) of the title bar"),
143 N_("\t -tbbc number \tnumber of color of background of the title bar"),
144 N_("\t -klfc number \tnumber of color of foreground (text) of the key label"),
145 N_("\t -klbc number \tnumber of color of background of the key label"),
146 N_("\t -knfc number \tnumber of color of foreground (text) of the key name"),
147 N_("\t -knbc number \tnumber of color of background of the key name"),
148 N_("\t -stfc number \tnumber of color of foreground (text) of the status line"),
149 N_("\t -stbc number \tnumber of color of background of the status line"),
150 N_("\t -prfc number \tnumber of color of foreground (text) of a prompt"),
151 N_("\t -prbc number \tnumber of color of background of a prompt"),
152 N_("\t -q1fc number \tnumber of color of foreground (text) of level one of quoted text"),
153 N_("\t -q1bc number \tnumber of color of background of level one of quoted text"),
154 N_("\t -q2fc number \tnumber of color of foreground (text) of level two of quoted text"),
155 N_("\t -q2bc number \tnumber of color of background of level two of quoted text"),
156 N_("\t -q3fc number \tnumber of color of foreground (text) of level three of quoted text"),
157 N_("\t -q3bc number \tnumber of color of background of level three of quoted text"),
158 N_("\t -sbfc number \tnumber of color of foreground of signature block text"),
159 N_("\t -sbbc number \tnumber of color of background of signature block text"),
160 N_("\t +[line#] \tLine - start on line# line, default=1"),
161 N_("\t -v \t\tView - view file"),
162 N_("\t -no_setlocale_collate\tdo not do setlocale(LC_COLLATE)"),
163 N_("\t -version\tPico version number"),
164 "",
165 N_("\t All arguments may be followed by a file name to display."),
167 NULL
172 * main standalone pico routine
174 #ifdef _WINDOWS
176 app_main (int argc, char *argv[])
177 #else
179 main(int argc, char *argv[])
180 #endif
182 UCS c;
183 register int f;
184 register int n;
185 register BUFFER *bp;
186 int viewflag = FALSE; /* are we starting in view mode?*/
187 int starton = 0; /* where's dot to begin with? */
188 int setlocale_collate = 1;
189 char bname[NBUFN]; /* buffer name of file to read */
190 char *file_to_edit = NULL;
191 char *display_charmap = NULL, *dc;
192 char *keyboard_charmap = NULL;
193 int use_system = 0;
194 char *err = NULL;
196 #ifndef _WINDOWS
197 utf8_parameters(SET_UCS4WIDTH, (void *) pith_ucs4width);
198 #endif /* _WINDOWS */
200 set_input_timeout(600);
201 Pmaster = NULL; /* turn OFF composer functionality */
202 km_popped = 0;
205 * Read command line flags before initializing, otherwise, we never
206 * know to init for f_keys...
208 file_to_edit = pico_args(argc, argv, &starton, &viewflag, &setlocale_collate);
210 set_collation(setlocale_collate, 1);
212 #define cpstr(s) strcpy((char *)fs_get(1+strlen(s)), s)
214 #ifdef _WINDOWS
215 init_utf8_display(1, NULL);
216 #else /* UNIX */
219 if(display_character_set)
220 display_charmap = cpstr(display_character_set);
221 #if HAVE_LANGINFO_H && defined(CODESET)
222 else if((dc = nl_langinfo_codeset_wrapper()) != NULL)
223 display_charmap = cpstr(dc);
224 #endif
226 if(!display_charmap)
227 display_charmap = cpstr("US-ASCII");
229 if(keyboard_character_set)
230 keyboard_charmap = cpstr(keyboard_character_set);
231 else
232 keyboard_charmap = cpstr(display_charmap);
235 if(use_system_translation){
236 #if PREREQ_FOR_SYS_TRANSLATION
237 use_system++;
238 /* This modifies its arguments */
239 if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
240 &input_cs, &err) == -1){
241 fprintf(stderr, "%s\n", err ? err : "trouble with character set");
242 exit(1);
244 else if(err){
245 fprintf(stderr, "%s\n", err);
246 fs_give((void **) &err);
248 #endif
251 if(!use_system){
252 if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
253 &input_cs, &err) == -1){
254 fprintf(stderr, "%s\n", err ? err : "trouble with character set");
255 exit(1);
257 else if(err){
258 fprintf(stderr, "%s\n", err);
259 fs_give((void **) &err);
263 if(keyboard_charmap){
264 set_locale_charmap(keyboard_charmap);
265 free((void *) keyboard_charmap);
268 if(display_charmap)
269 free((void *) display_charmap);
271 #endif /* UNIX */
274 * There are a couple arguments that we need to be sure
275 * are converted for internal use.
277 if(alt_speller)
278 alt_speller = cpstr(fname_to_utf8(alt_speller));
280 if(opertree && opertree[0]){
281 strncpy(opertree, fname_to_utf8(opertree), sizeof(opertree));
282 opertree[sizeof(opertree)-1] = '\0';
285 if(glo_quote_str_orig)
286 glo_quote_str = utf8_to_ucs4_cpystr(fname_to_utf8(glo_quote_str_orig));
288 if(glo_wordseps_orig)
289 glo_wordseps = utf8_to_ucs4_cpystr(fname_to_utf8(glo_wordseps_orig));
291 if(file_to_edit)
292 file_to_edit = cpstr(fname_to_utf8(file_to_edit));
294 #undef cpstr
296 #if defined(DOS) || defined(OS2)
297 if(file_to_edit){ /* strip quotes? */
298 int l;
300 if(strchr("'\"", file_to_edit[0])
301 && (l = strlen(file_to_edit)) > 1
302 && file_to_edit[l-1] == file_to_edit[0]){
303 file_to_edit[l-1] = '\0'; /* blat trailing quote */
304 file_to_edit++; /* advance past leading quote */
307 #endif
309 if(!vtinit()) /* Displays. */
310 exit(1);
312 strncpy(bname, "main", sizeof(bname)); /* default buffer name */
313 bname[sizeof(bname)-1] = '\0';
314 edinit(bname); /* Buffers, windows. */
316 update(); /* let the user know we are here */
317 sgarbf = TRUE; /* next update, repaint all */
319 #ifdef _WINDOWS
320 mswin_setwindow(NULL, NULL, NULL, NULL, NULL, NULL);
321 mswin_showwindow();
322 mswin_showcaret(1); /* turn on for main window */
323 mswin_allowpaste(MSWIN_PASTE_FULL);
324 mswin_setclosetext("Use the ^X command to exit Pico.");
325 mswin_setscrollcallback (pico_scroll_callback);
326 #endif
328 #if defined(USE_TERMCAP) || defined(USE_TERMINFO) || defined(VMS)
329 if(kbesc == NULL){ /* will arrow keys work ? */
330 (*term.t_putchar)('\007');
331 emlwrite("Warning: keypad keys may be non-functional", NULL);
333 #endif /* USE_TERMCAP/USE_TERMINFO/VMS */
335 if(file_to_edit){ /* Any file to edit? */
337 makename(bname, file_to_edit); /* set up a buffer for this file */
339 bp = curbp; /* read in first file */
340 makename(bname, file_to_edit);
341 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
342 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
344 if(strlen(file_to_edit) >= NFILEN){
345 char buf[128];
347 snprintf(buf, sizeof(buf), "Filename \"%.10s...\" too long", file_to_edit);
348 emlwrite(buf, NULL);
349 file_to_edit = NULL;
351 else{
352 strncpy(bp->b_fname, file_to_edit, sizeof(bp->b_fname));
353 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
354 if (((gmode&MDTREE) && !in_oper_tree(file_to_edit)) ||
355 readin(file_to_edit, (viewflag==FALSE), TRUE) == ABORT) {
356 if ((gmode&MDTREE) && !in_oper_tree(file_to_edit)){
357 EML eml;
358 eml.s = opertree;
359 emlwrite(_("Can't read file from outside of %s"), &eml);
362 file_to_edit = NULL;
366 if(!file_to_edit){
367 strncpy(bp->b_bname, "main", sizeof(bp->b_bname));
368 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
369 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
370 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
373 bp->b_dotp = bp->b_linep;
374 bp->b_doto = 0;
376 if (viewflag) /* set the view mode */
377 bp->b_mode |= MDVIEW;
380 /* setup to process commands */
381 lastflag = 0; /* Fake last flags. */
382 curbp->b_mode |= gmode; /* and set default modes*/
384 curwp->w_flag |= WFMODE; /* and force an update */
386 if(timeoutset){
387 EML eml;
389 eml.s = comatose(get_input_timeout());
390 emlwrite(_("Checking for new mail every %s seconds"), &eml);
394 forwline(0, starton - 1); /* move dot to specified line */
396 while(1){
398 if(Pcolors)
399 pico_set_colorp(Pcolors->ntcp, PSC_NONE);
401 if(km_popped){
402 km_popped--;
403 if(km_popped == 0) /* cause bottom three lines to be repainted */
404 curwp->w_flag |= WFHARD;
407 if(km_popped){ /* temporarily change to cause menu to be painted */
408 term.t_mrow = 2;
409 curwp->w_ntrows -= 2;
410 curwp->w_flag |= WFMODE;
411 movecursor(term.t_nrow-2, 0); /* clear status line, too */
412 peeol();
415 update(); /* Fix up the screen */
416 if(km_popped){
417 term.t_mrow = 0;
418 curwp->w_ntrows += 2;
421 #ifdef MOUSE
422 #ifdef EX_MOUSE
423 /* New mouse function for real mouse text seletion. */
424 register_mfunc(mouse_in_pico, 2, 0, term.t_nrow - (term.t_mrow + 1),
425 term.t_ncol);
426 #else
427 mouse_in_content(KEY_MOUSE, -1, -1, 0, 0);
428 register_mfunc(mouse_in_content, 2, 0, term.t_nrow - (term.t_mrow + 1),
429 term.t_ncol);
430 #endif
431 #endif
432 #ifdef _WINDOWS
433 mswin_setdndcallback (pico_file_drop);
434 mswin_mousetrackcallback(pico_cursor);
435 #endif
436 c = GetKey();
437 #ifdef MOUSE
438 #ifdef EX_MOUSE
439 clear_mfunc(mouse_in_pico);
440 #else
441 clear_mfunc(mouse_in_content);
442 #endif
443 #endif
444 #ifdef _WINDOWS
445 mswin_cleardndcallback ();
446 mswin_mousetrackcallback(NULL);
447 #endif
449 if(timeoutset && (c == NODATA || time_to_check())){
450 if(pico_new_mail())
451 emlwrite(_("You may possibly have new mail."), NULL);
454 if(km_popped)
455 switch(c){
456 case NODATA:
457 case (CTRL|'L'):
458 km_popped++;
459 break;
461 default:
462 /* clear bottom three lines */
463 mlerase();
464 break;
467 if(c == NODATA)
468 continue;
470 if(mpresf){ /* erase message line? */
471 if(mpresf++ > MESSDELAY)
472 mlerase();
475 f = FALSE;
476 n = 1;
478 #ifdef MOUSE
479 clear_mfunc(mouse_in_content);
480 #endif
481 /* Do it. */
482 execute(normalize_cmd(c, fkm, 1), f, n);
486 void
487 display_color_codes(void)
489 #define SPACES " "
490 int i, j, k, l, a, len, len_entry, row;
491 int ncolors;
492 COLOR_PAIR *lastc = NULL, *newcp;
493 char *fg;
495 /* this is the format "SPACE COLORED_SPACES = CODE SPACE" */
496 vtterminalinfo(gmode & MDTCAPWINS);
497 (*term.t_open)();
498 (*term.t_rev)(FALSE);
500 pico_toggle_color(1);
501 if((ncolors = pico_count_in_color_table()) <= 0){
502 fprintf(stderr, "%s", "Your screen does not support colors\r\n");
503 exit(1);
507 if(term.t_ncol < 62 || term.t_nrow < 23){
508 fprintf(stderr, "%s", "Screen must have at least 24 rows and 63 columns\r\n");
509 exit(1);
513 fprintf(stdout, "%s", "The code of a color is the number in the same row plus\r\n");
514 fprintf(stdout, "%s", "the number in the same column as that color.\r\n\r\n");
516 lastc = pico_get_cur_color();
517 switch(ncolors){
518 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
519 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
520 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
521 default : fprintf(stderr, "Unknown number of colors %d\n", ncolors);
522 exit(1);
523 break;
526 if(ncolors != 256){
527 for(k = -1; 16*k < ncolors; k++){
528 for(l = -1; l < ncolors; l++){
529 if(k == -1){
530 if(ncolors == 8){
531 if(l == -1)
532 fprintf(stdout, "%s", " ");
533 else
534 fprintf(stdout, "%3d", l);
537 else{
538 if(l == -1){
539 pico_toggle_color(1);
540 fprintf(stdout, "%3d ", k);
542 else{
543 if(ncolors || l < 8){
544 i = 16*k + l;
545 newcp = new_color_pair(colorx(0), colorx(i));
546 pico_set_colorp(newcp, PSC_NONE);
547 fprintf(stdout, "%s", SPACES);
548 pico_set_colorp(lastc, PSC_NONE);
553 pico_toggle_color(0);
554 if(k == 0)
555 fprintf(stdout, " (%d colors)", ncolors);
556 if(k != -1 || ncolors == 8)
557 fprintf(stdout, "%s", "\r\n");
559 } else {
560 fprintf(stdout, "%s", "Codes for terminal with 256 colors:\r\n");
561 a = 16;
562 for(k = -1; 36*k < ncolors; k++){
563 for(l = -1; l < ncolors && l < 16; l++){
564 if(k == -1){
565 if(l == -1)
566 fprintf(stdout, "%s", " ");
567 else
568 fprintf(stdout, "%3d", l);
570 else{
571 if(l == -1){
572 pico_toggle_color(1);
573 fprintf(stdout, "%3d ", 36*k);
575 else{
576 i = 36*k + l;
577 newcp = new_color_pair(colorx(0), colorx(i));
578 pico_set_colorp(newcp, PSC_NONE);
579 fprintf(stdout, "%s", SPACES);
580 pico_set_colorp(lastc, PSC_NONE);
584 pico_toggle_color(0);
585 fprintf(stdout, "%s", "\r\n");
587 a = 20;
588 for(k = -1; 16 + 36*k < ncolors; k++){
589 for(l = -1; l < ncolors && l < a; l++){
590 if(k == -1){
591 if(l == -1)
592 fprintf(stdout, "%s", " ");
593 else
594 fprintf(stdout, "%3d", l);
596 else{
597 if(l == -1){
598 pico_toggle_color(1);
599 fprintf(stdout, "%3d ", 16 + 36*k);
601 else{
602 i = 16 + 36*k + l;
603 newcp = new_color_pair(colorx(0), colorx(i));
604 pico_set_colorp(newcp, PSC_NONE);
605 fprintf(stdout, "%s", SPACES);
606 pico_set_colorp(lastc, PSC_NONE);
610 pico_toggle_color(0);
611 fprintf(stdout, "%s", "\r\n");
614 pico_set_colorp(lastc, PSC_NONE);
619 * Parse the command line args.
621 * Args ac
622 * av
623 * starton -- place to return starton value
624 * viewflag -- place to return viewflag value
626 * Result: command arguments parsed
627 * possible printing of help for command line
628 * various global flags set
629 * returns the name of any file to open, else NULL
631 char *
632 pico_args(int ac, char **av, int *starton, int *viewflag, int *setlocale_collate)
634 int c, usage = 0;
635 char *str;
636 char tmp_1k_buf[1000]; /* tmp buf to contain err msgs */
637 int ncolors, ntfc, ntbc, rtfc, rtbc;
638 int tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc;
639 int q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc;
641 ncolors = 0;
642 ntfc = ntbc = rtfc = rtbc = tbfc = tbbc = klfc = klbc = knfc =
643 knbc = stfc = stbc = prfc = prbc = q1fc = q1bc = q2fc = q2bc =
644 q3fc = q3bc = sbfc = sbbc = -1;
645 Loop:
646 /* while more arguments with leading - or + */
647 while(--ac > 0 && (**++av == '-' || **av == '+')){
648 if(**av == '+'){
649 if(*++*av)
650 str = *av;
651 else if(--ac)
652 str = *++av;
653 else{
654 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '+');
655 pico_display_args_err(tmp_1k_buf, NULL, 1);
656 usage++;
657 goto Loop;
660 if(!isdigit((unsigned char)str[0])){
661 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '+');
662 pico_display_args_err(tmp_1k_buf, NULL, 1);
663 usage++;
666 if(starton)
667 *starton = atoi(str);
669 goto Loop;
672 /* while more chars in this argument */
673 else while(*++*av){
675 if(strcmp(*av, "version") == 0){
676 pico_vers_help();
678 else if(strcmp(*av, "ntfc") == 0
679 || strcmp(*av, "ntbc") == 0
680 || strcmp(*av, "rtfc") == 0
681 || strcmp(*av, "rtbc") == 0
682 || strcmp(*av, "tbfc") == 0
683 || strcmp(*av, "tbbc") == 0
684 || strcmp(*av, "klfc") == 0
685 || strcmp(*av, "klbc") == 0
686 || strcmp(*av, "knfc") == 0
687 || strcmp(*av, "knbc") == 0
688 || strcmp(*av, "stfc") == 0
689 || strcmp(*av, "stbc") == 0
690 || strcmp(*av, "prfc") == 0
691 || strcmp(*av, "prbc") == 0
692 || strcmp(*av, "q1fc") == 0
693 || strcmp(*av, "q1bc") == 0
694 || strcmp(*av, "q2fc") == 0
695 || strcmp(*av, "q2bc") == 0
696 || strcmp(*av, "q3fc") == 0
697 || strcmp(*av, "q3bc") == 0
698 || strcmp(*av, "sbfc") == 0
699 || strcmp(*av, "sbbc") == 0
700 || strcmp(*av, "ncolors") == 0){
701 str = *av;
702 if(--ac)
703 ++av;
704 else{
705 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '-');
706 pico_display_args_err(tmp_1k_buf, NULL, 1);
707 usage++;
708 goto Loop;
711 if(!isdigit((unsigned char)**av)){
712 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '-');
713 pico_display_args_err(tmp_1k_buf, NULL, 1);
714 usage++;
716 if(strcmp(str, "ntfc") == 0) ntfc = atoi(*av);
717 else if (strcmp(str, "ntbc") == 0) ntbc = atoi(*av);
718 else if (strcmp(str, "rtfc") == 0) rtfc = atoi(*av);
719 else if (strcmp(str, "rtbc") == 0) rtbc = atoi(*av);
720 else if (strcmp(str, "tbfc") == 0) tbfc = atoi(*av);
721 else if (strcmp(str, "tbbc") == 0) tbbc = atoi(*av);
722 else if (strcmp(str, "klfc") == 0) klfc = atoi(*av);
723 else if (strcmp(str, "klbc") == 0) klbc = atoi(*av);
724 else if (strcmp(str, "knfc") == 0) knfc = atoi(*av);
725 else if (strcmp(str, "knbc") == 0) knbc = atoi(*av);
726 else if (strcmp(str, "stfc") == 0) stfc = atoi(*av);
727 else if (strcmp(str, "stbc") == 0) stbc = atoi(*av);
728 else if (strcmp(str, "prfc") == 0) prfc = atoi(*av);
729 else if (strcmp(str, "prbc") == 0) prbc = atoi(*av);
730 else if (strcmp(str, "q1fc") == 0) q1fc = atoi(*av);
731 else if (strcmp(str, "q1bc") == 0) q1bc = atoi(*av);
732 else if (strcmp(str, "q2fc") == 0) q2fc = atoi(*av);
733 else if (strcmp(str, "q2bc") == 0) q2bc = atoi(*av);
734 else if (strcmp(str, "q3fc") == 0) q3fc = atoi(*av);
735 else if (strcmp(str, "q3bc") == 0) q3bc = atoi(*av);
736 else if (strcmp(str, "sbfc") == 0) sbfc = atoi(*av);
737 else if (strcmp(str, "sbbc") == 0) sbbc = atoi(*av);
738 else if (strcmp(str, "ncolors") == 0) ncolors = atoi(*av);
739 if(!strcmp(str, "ncolors")){
740 switch(ncolors){
741 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
742 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
743 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
744 default : snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _("Unsupported number of colors: %d"), ncolors);
745 pico_display_args_err(tmp_1k_buf, NULL, 1);
746 exit(1);
747 break;
750 goto Loop;
752 else if(strcmp(*av, "color_codes") == 0){
753 display_color_codes();
754 exit(0);
756 else if(strcmp(*av, "no_setlocale_collate") == 0){
757 *setlocale_collate = 0;
758 goto Loop;
760 #ifndef _WINDOWS
761 else if(strcmp(*av, "syscs") == 0){
762 use_system_translation = !use_system_translation;
763 goto Loop;
765 #endif /* ! _WINDOWS */
766 #ifdef _WINDOWS
767 else if(strcmp(*av, "cnf") == 0
768 || strcmp(*av, "cnb") == 0
769 || strcmp(*av, "crf") == 0
770 || strcmp(*av, "crb") == 0){
772 char *cmd = *av; /* save it to use below */
774 if(--ac){
775 str = *++av;
776 if(cmd[1] == 'n'){
777 if(cmd[2] == 'f')
778 pico_nfcolor(str);
779 else if(cmd[2] == 'b')
780 pico_nbcolor(str);
782 else if(cmd[1] == 'r'){
783 if(cmd[2] == 'f')
784 pico_rfcolor(str);
785 else if(cmd[2] == 'b')
786 pico_rbcolor(str);
789 else{
790 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_color), cmd);
791 pico_display_args_err(tmp_1k_buf, NULL, 1);
792 usage++;
795 goto Loop;
797 #endif /* _WINDOWS */
798 #ifndef _WINDOWS
799 else if(strcmp(*av, "dcs") == 0 || strcmp(*av, "kcs") == 0){
800 char *cmd = *av;
802 if(--ac){
803 if(strcmp(*av, "dcs") == 0){
804 display_character_set = *++av;
805 if(!output_charset_is_supported(display_character_set)){
806 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_output_charset), display_character_set);
807 pico_display_args_err(tmp_1k_buf, NULL, 1);
808 usage++;
811 else{
812 keyboard_character_set = *++av;
813 if(!input_charset_is_supported(keyboard_character_set)){
814 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_input_charset), keyboard_character_set);
815 pico_display_args_err(tmp_1k_buf, NULL, 1);
816 usage++;
820 else{
821 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_charset), cmd);
822 pico_display_args_err(tmp_1k_buf, NULL, 1);
823 usage++;
826 goto Loop;
828 #endif /* ! _WINDOWS */
831 * Single char options.
833 switch(c = **av){
835 * These don't take arguments.
837 case 'a':
838 gmode ^= MDDOTSOK; /* show dot files */
839 break;
840 case 'b':
841 #ifdef notdef
843 * Make MDREPLACE always on instead
844 * Don't leave this to allow turning off of MDREPLACE because the
845 * polarity of -b will have changed. Don't think anybody wants to
846 * turn it off.
848 gmode ^= MDREPLACE; /* -b for replace string in where is command */
849 #endif
850 break;
851 case 'd': /* -d for rebind delete key */
852 bindtokey(0x7f, forwdel);
853 break;
854 case 'e': /* file name completion */
855 gmode ^= MDCMPLT;
856 break;
857 case 'f': /* -f for function key use */
858 gmode ^= MDFKEY;
859 break;
860 case 'g': /* show-cursor in file browser */
861 gmode ^= MDSHOCUR;
862 break;
863 case 'h':
864 usage++;
865 break;
866 case 'j': /* allow "Goto" in file browser */
867 gmode ^= MDGOTO;
868 break;
869 case 'k': /* kill from dot */
870 gmode ^= MDDTKILL;
871 break;
872 case 'm': /* turn on mouse support */
873 gmode ^= MDMOUSE;
874 break;
875 case 'p':
876 preserve_start_stop = 1;
877 break;
878 case 'q': /* -q for termcap takes precedence */
879 gmode ^= MDTCAPWINS;
880 break;
881 case 't': /* special shutdown mode */
882 gmode ^= MDTOOL;
883 rebindfunc(wquit, quickexit);
884 break;
885 case 'v': /* -v for View File */
886 case 'V':
887 *viewflag = !*viewflag;
888 break; /* break back to inner-while */
889 case 'w': /* -w turn off word wrap */
890 gmode ^= MDWRAP;
891 break;
892 case 'x': /* suppress keyhelp */
893 sup_keyhelp = !sup_keyhelp;
894 break;
895 case 'z': /* -z to suspend */
896 gmode ^= MDSSPD;
897 break;
900 * These do take arguments.
902 case 'r': /* set fill column */
903 case 'n': /* -n for new mail notification */
904 case 's' : /* speller */
905 case 'o' : /* operating tree */
906 case 'Q' : /* Quote string */
907 case 'W' : /* Word separators */
908 if(*++*av)
909 str = *av;
910 else if(--ac)
911 str = *++av;
912 else{
913 if(c == 'r')
914 str= "72";
915 else if(c == 'n')
916 str = "180";
917 else{
918 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), c);
919 pico_display_args_err(tmp_1k_buf, NULL, 1);
920 usage++;
921 goto Loop;
925 switch(c){
926 case 's':
927 alt_speller = str;
928 break;
929 case 'o':
930 strncpy(opertree, str, NLINE);
931 gmode ^= MDTREE;
932 break;
933 case 'Q':
934 glo_quote_str_orig = str;
935 break;
936 case 'W':
937 glo_wordseps_orig = str;
938 break;
940 /* numeric args */
941 case 'r':
942 case 'n':
943 if(!isdigit((unsigned char)str[0])){
944 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), c);
945 pico_display_args_err(tmp_1k_buf, NULL, 1);
946 usage++;
949 if(c == 'r'){
950 if((userfillcol = atoi(str)) < 1)
951 userfillcol = 72;
953 else{
954 timeoutset = 1;
955 set_input_timeout(180);
956 if(set_input_timeout(atoi(str)) < 30)
957 set_input_timeout(180);
960 break;
963 goto Loop;
965 default: /* huh? */
966 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_flag), c);
967 pico_display_args_err(tmp_1k_buf, NULL, 1);
968 usage++;
969 break;
974 if(usage)
975 pico_args_help();
977 Pcolors = pico_set_global_colors(ncolors, ntfc, ntbc, rtfc, rtbc,
978 tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc,
979 q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc);
981 if(Pcolors)
982 pico_toggle_color(1);
984 /* return the first filename for editing */
985 if(ac > 0)
986 return(*av);
987 else
988 return(NULL);
992 PCOLORS *
993 pico_set_global_colors(int nc, int ntfg, int ntbg, int rtfg, int rtbg,
994 int tbfg, int tbbg, int klfg, int klbg,
995 int knfg, int knbg, int stfg, int stbg, int prfg, int prbg,
996 int q1fg, int q1bg, int q2fg, int q2bg, int q3fg, int q3bg,
997 int sbfg, int sbbg)
999 PCOLORS *pcolors = NULL;
1000 char *fg, *bg;
1002 if(nc != 0 && nc != 8 && nc != 16 && nc != 256){
1003 fprintf(stderr, "number of colors must be either 8, 16 or 256\n");
1004 exit(1);
1007 if(nc == 0){
1008 if(ntfg != -1 || ntbg != -1 || tbfg != -1 || tbbg != -1 ||
1009 klfg != -1 || klbg != -1 || knfg != -1 || knbg != -1 ||
1010 stfg != -1 || stbg != -1 || prfg != -1 || prbg != -1 ||
1011 q1fg != -1 || q1bg != -1 || q2fg != -1 || q1bg != -1 ||
1012 q3fg != -1 || q3bg != -1 || sbfg != -1 || sbbg != -1 ||
1013 rtfg != -1 || rtbg != -1){
1014 fprintf(stderr, "can not specify color numbers without specifying number of colors\n");
1015 exit(1);
1017 else
1018 return pcolors; /* no colors used */
1021 if(ntfg >= nc || ntbg >= nc || tbfg >= nc || tbbg >= nc
1022 || klfg >= nc || klbg >= nc || knfg >= nc || knbg >= nc
1023 || stfg >= nc || stbg >= nc || prfg >= nc || prbg >= nc
1024 || q1fg >= nc || q1bg >= nc || q2fg >= nc || q2bg >= nc
1025 || q3fg >= nc || q3bg >= nc || sbfg >= nc || sbbg >= nc
1026 || rtfg >= nc || rtbg >= nc){
1027 fprintf(stderr, "Error: specified a color bigger than number of colors\n");
1028 exit(1);
1031 /* Finally, we set up colors */
1032 pico_toggle_color(0);
1033 switch(nc){
1034 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
1035 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
1036 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
1037 default : break; /* impossible case */
1039 pico_toggle_color(1);
1041 pcolors = (PCOLORS *) malloc(sizeof(PCOLORS));
1042 memset((void *)pcolors, 0, sizeof(PCOLORS));
1043 /* ignore bad pair settings, also we set tbcp backwards because it will
1044 * be reversed later in the modeline function, so tbcp->fg is actually
1045 * tbcp->bg and viceversa.
1047 if(ntfg >= 0 && ntbg >= 0){ /* set normal text color */
1048 fg = colorx(ntfg); bg = colorx(ntbg);
1049 pcolors->ntcp = new_color_pair(fg, bg);
1050 pico_nfcolor(fg);
1051 pico_nbcolor(bg);
1053 /* reverse means reverse of normal text */
1054 if((rtfg < 0 || rtbg < 0) && (ntfg >= 0 && ntbg >= 0)){
1055 rtfg = ntbg;
1056 rtbg = ntfg;
1058 if(rtfg >= 0 && rtbg >= 0){ /* set reverse text color */
1059 fg = colorx(rtfg); bg = colorx(rtbg);
1060 pcolors->rtcp = new_color_pair(fg, bg);
1061 pico_rfcolor(fg);
1062 pico_rbcolor(bg);
1064 /* If the user does not specify this, we will set up all
1065 * backgrounds for text to the normal text background
1067 if(ntbg >= 0){
1068 if(knbg < 0) knbg = ntbg;
1069 if(q1bg < 0) q1bg = ntbg;
1070 if(q2bg < 0) q2bg = ntbg;
1071 if(q3bg < 0) q3bg = ntbg;
1072 if(sbbg < 0) sbbg = ntbg;
1074 if(rtfg >= 0 && rtbg >= 0){ /* set default reverse */
1075 if(tbfg < 0 || tbbg < 0){ /* set titlebar colors to reverse color if any missing*/
1076 tbfg = rtfg; tbbg = rtbg;
1078 if(klfg < 0 || klbg < 0){ /* set key label colors */
1079 klfg = rtfg; klbg = rtbg;
1081 if(stfg < 0 || stbg < 0){ /* set status colors */
1082 stfg = rtfg; stbg = rtbg;
1084 if(prfg >= 0 && prbg >= 0){ /* set prompt colors */
1085 prfg = rtfg; prbg = rtbg;
1088 if(tbfg >= 0 && tbbg >= 0) /* set titlebar colors */
1089 pcolors->tbcp = new_color_pair(colorx(tbbg), colorx(tbfg));
1090 if(klfg >= 0 && klbg >= 0) /* set key label colors */
1091 pcolors->klcp = new_color_pair(colorx(klfg), colorx(klbg));
1092 if(knfg >= 0 && knbg >= 0) /* set key name colors */
1093 pcolors->kncp = new_color_pair(colorx(knfg), colorx(knbg));
1094 if(stfg >= 0 && stbg >= 0) /* set status colors */
1095 pcolors->stcp = new_color_pair(colorx(stfg), colorx(stbg));
1096 if(prfg >= 0 && prbg >= 0) /* set prompt colors */
1097 pcolors->prcp = new_color_pair(colorx(prfg), colorx(prbg));
1098 if(q1fg >= 0 && q1bg >= 0) /* set quote level 1 colors */
1099 pcolors->qlcp = new_color_pair(colorx(q1fg), colorx(q1bg));
1100 if(q2fg >= 0 && q2bg >= 0) /* set quote level 2 colors */
1101 pcolors->qllcp = new_color_pair(colorx(q2fg), colorx(q2bg));
1102 if(q3fg >= 0 && q3bg >= 0) /* set quote level 3 colors */
1103 pcolors->qlllcp = new_color_pair(colorx(q3fg), colorx(q3bg));
1104 if(sbfg >= 0 && sbbg >= 0) /* set signature block colors */
1105 pcolors->sbcp = new_color_pair(colorx(sbfg), colorx(sbbg));
1107 if(pico_usingcolor())
1108 pico_set_normal_color();
1110 return pcolors;
1113 #ifdef _WINDOWS
1118 pico_file_drop(int x, int y, char *filename)
1121 * if current buffer is unchanged
1122 * *or* "new buffer" and no current text
1124 if(((curwp->w_bufp->b_flag & BFCHG) == 0)
1125 || (curwp->w_bufp->b_fname[0] == '\0'
1126 && curwp->w_bufp->b_linep == lforw(curwp->w_bufp->b_linep)
1127 && curwp->w_doto == 0)){
1128 register BUFFER *bp = curwp->w_bufp;
1129 char bname[NBUFN];
1131 makename(bname, filename);
1132 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
1133 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1134 strncpy(bp->b_fname, filename, sizeof(bp->b_fname));
1135 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1136 bp->b_flag &= ~BFCHG; /* turn off change bit */
1137 if (readin(filename, 1, 1) == ABORT) {
1138 strncpy(bp->b_bname, "", sizeof(bp->b_bname));
1139 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1140 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
1141 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1144 bp->b_dotp = bp->b_linep;
1145 bp->b_doto = 0;
1147 else{
1148 EML eml;
1150 ifile(filename);
1151 curwp->w_flag |= WFHARD;
1152 update();
1153 eml.s = filename;
1154 emlwrite("Inserted dropped file \"%s\"", &eml);
1157 curwp->w_flag |= WFHARD;
1158 update(); /* restore cursor */
1159 return(1);
1161 #endif
1164 /*----------------------------------------------------------------------
1165 print a few lines of help for command line arguments
1167 Args: none
1169 Result: prints help messages
1170 ----------------------------------------------------------------------*/
1171 void
1172 pico_args_help(void)
1174 char **a;
1175 char *pp[2];
1177 pp[1] = NULL;
1179 /** print out possible starting arguments... **/
1181 for(a=args_pico_args; a && *a; a++){
1182 pp[0] = _(*a);
1183 pico_display_args_err(NULL, pp, 0);
1186 exit(1);
1190 void
1191 pico_vers_help(void)
1193 char v0[100];
1194 char *v[2];
1196 snprintf(v0, sizeof(v0), "Pico %.50s", version);
1197 v[0] = v0;
1198 v[1] = NULL;
1200 pico_display_args_err(NULL, v, 0);
1201 exit(1);
1205 /*----------------------------------------------------------------------
1206 write argument error to the display...
1208 Args: none
1210 Result: prints help messages
1211 ----------------------------------------------------------------------*/
1212 void
1213 pico_display_args_err(char *s, char **a, int err)
1215 char errstr[256], *errp;
1216 FILE *fp = err ? stderr : stdout;
1217 #ifdef _WINDOWS
1218 char tmp_20k_buf[SIZEOF_20KBUF];
1219 #endif
1222 if(err && s)
1223 snprintf(errp = errstr, sizeof(errstr), _("Argument Error: %.200s"), s);
1224 else
1225 errp = s;
1227 #ifdef _WINDOWS
1228 if(errp)
1229 mswin_messagebox(errp, err);
1231 if(a && *a){
1232 strncpy(tmp_20k_buf, *a++, SIZEOF_20KBUF);
1233 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1234 while(a && *a){
1235 strncat(tmp_20k_buf, "\n", SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1236 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1237 strncat(tmp_20k_buf, *a++, SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1238 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1241 mswin_messagebox(tmp_20k_buf, err);
1243 #else
1244 if(errp)
1245 fprintf(fp, "%s\n", errp);
1247 while(a && *a)
1248 fprintf(fp, "%s\n", *a++);
1249 #endif