* Update configure script to remove the search for a linking tcl
[alpine.git] / pico / main.c
blobc0ff12d4ad78296f836b3a550236de589328b4c3
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-2018 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(1);
509 if((ncolors = pico_count_in_color_table()) <= 0){
510 fprintf(stderr, "%s", "Your screen does not support colors\r\n");
511 exit(1);
515 if(term.t_ncol < 62 || term.t_nrow < 23){
516 fprintf(stderr, "%s", "Screen must have at least 24 rows and 63 columns\r\n");
517 exit(1);
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 if(ncolors != 256){
535 for(k = -1; 16*k < ncolors; k++){
536 for(l = -1; l < ncolors; l++){
537 if(k == -1){
538 if(ncolors == 8){
539 if(l == -1)
540 fprintf(stdout, "%s", " ");
541 else
542 fprintf(stdout, "%3d", l);
545 else{
546 if(l == -1){
547 pico_toggle_color(1);
548 fprintf(stdout, "%3d ", k);
550 else{
551 if(ncolors || l < 8){
552 i = 16*k + l;
553 newcp = new_color_pair(colorx(0), colorx(i));
554 pico_set_colorp(newcp, PSC_NONE);
555 fprintf(stdout, "%s", SPACES);
556 pico_set_colorp(lastc, PSC_NONE);
561 pico_toggle_color(0);
562 if(k == 0)
563 fprintf(stdout, " (%d colors)", ncolors);
564 if(k != -1 || ncolors == 8)
565 fprintf(stdout, "%s", "\r\n");
567 } else {
568 fprintf(stdout, "%s", "Codes for terminal with 256 colors:\r\n");
569 a = 16;
570 for(k = -1; 36*k < ncolors; k++){
571 for(l = -1; l < ncolors && l < 16; l++){
572 if(k == -1){
573 if(l == -1)
574 fprintf(stdout, "%s", " ");
575 else
576 fprintf(stdout, "%3d", l);
578 else{
579 if(l == -1){
580 pico_toggle_color(1);
581 fprintf(stdout, "%3d ", 36*k);
583 else{
584 i = 36*k + l;
585 newcp = new_color_pair(colorx(0), colorx(i));
586 pico_set_colorp(newcp, PSC_NONE);
587 fprintf(stdout, "%s", SPACES);
588 pico_set_colorp(lastc, PSC_NONE);
592 pico_toggle_color(0);
593 fprintf(stdout, "%s", "\r\n");
595 a = 20;
596 for(k = -1; 16 + 36*k < ncolors; k++){
597 for(l = -1; l < ncolors && l < a; l++){
598 if(k == -1){
599 if(l == -1)
600 fprintf(stdout, "%s", " ");
601 else
602 fprintf(stdout, "%3d", l);
604 else{
605 if(l == -1){
606 pico_toggle_color(1);
607 fprintf(stdout, "%3d ", 16 + 36*k);
609 else{
610 i = 16 + 36*k + l;
611 newcp = new_color_pair(colorx(0), colorx(i));
612 pico_set_colorp(newcp, PSC_NONE);
613 fprintf(stdout, "%s", SPACES);
614 pico_set_colorp(lastc, PSC_NONE);
618 pico_toggle_color(0);
619 fprintf(stdout, "%s", "\r\n");
622 pico_set_colorp(lastc, PSC_NONE);
624 #endif /* ! _WINDOWS */
628 * Parse the command line args.
630 * Args ac
631 * av
632 * starton -- place to return starton value
633 * viewflag -- place to return viewflag value
635 * Result: command arguments parsed
636 * possible printing of help for command line
637 * various global flags set
638 * returns the name of any file to open, else NULL
640 char *
641 pico_args(int ac, char **av, int *starton, int *viewflag, int *setlocale_collate)
643 int c, usage = 0;
644 char *str;
645 char tmp_1k_buf[1000]; /* tmp buf to contain err msgs */
646 #ifndef _WINDOWS
647 int ncolors, ntfc, ntbc, rtfc, rtbc;
648 int tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc;
649 int q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc;
651 ncolors = 0;
652 ntfc = ntbc = rtfc = rtbc = tbfc = tbbc = klfc = klbc = knfc =
653 knbc = stfc = stbc = prfc = prbc = q1fc = q1bc = q2fc = q2bc =
654 q3fc = q3bc = sbfc = sbbc = -1;
655 #endif /* ! _WINDOWS */
657 Loop:
658 /* while more arguments with leading - or + */
659 while(--ac > 0 && (**++av == '-' || **av == '+')){
660 if(**av == '+'){
661 if(*++*av)
662 str = *av;
663 else if(--ac)
664 str = *++av;
665 else{
666 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '+');
667 pico_display_args_err(tmp_1k_buf, NULL, 1);
668 usage++;
669 goto Loop;
672 if(!isdigit((unsigned char)str[0])){
673 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '+');
674 pico_display_args_err(tmp_1k_buf, NULL, 1);
675 usage++;
678 if(starton)
679 *starton = atoi(str);
681 goto Loop;
684 /* while more chars in this argument */
685 else while(*++*av){
687 if(strcmp(*av, "version") == 0){
688 pico_vers_help();
690 #ifndef _WINDOWS /* color configuration disabled in Windows at this time */
691 else if(strcmp(*av, "ntfc") == 0
692 || strcmp(*av, "ntbc") == 0
693 || strcmp(*av, "rtfc") == 0
694 || strcmp(*av, "rtbc") == 0
695 || strcmp(*av, "tbfc") == 0
696 || strcmp(*av, "tbbc") == 0
697 || strcmp(*av, "klfc") == 0
698 || strcmp(*av, "klbc") == 0
699 || strcmp(*av, "knfc") == 0
700 || strcmp(*av, "knbc") == 0
701 || strcmp(*av, "stfc") == 0
702 || strcmp(*av, "stbc") == 0
703 || strcmp(*av, "prfc") == 0
704 || strcmp(*av, "prbc") == 0
705 || strcmp(*av, "q1fc") == 0
706 || strcmp(*av, "q1bc") == 0
707 || strcmp(*av, "q2fc") == 0
708 || strcmp(*av, "q2bc") == 0
709 || strcmp(*av, "q3fc") == 0
710 || strcmp(*av, "q3bc") == 0
711 || strcmp(*av, "sbfc") == 0
712 || strcmp(*av, "sbbc") == 0
713 || strcmp(*av, "ncolors") == 0){
714 str = *av;
715 if(--ac)
716 ++av;
717 else{
718 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '-');
719 pico_display_args_err(tmp_1k_buf, NULL, 1);
720 usage++;
721 goto Loop;
724 if(!isdigit((unsigned char)**av)){
725 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '-');
726 pico_display_args_err(tmp_1k_buf, NULL, 1);
727 usage++;
729 if(strcmp(str, "ntfc") == 0) ntfc = atoi(*av);
730 else if (strcmp(str, "ntbc") == 0) ntbc = atoi(*av);
731 else if (strcmp(str, "rtfc") == 0) rtfc = atoi(*av);
732 else if (strcmp(str, "rtbc") == 0) rtbc = atoi(*av);
733 else if (strcmp(str, "tbfc") == 0) tbfc = atoi(*av);
734 else if (strcmp(str, "tbbc") == 0) tbbc = atoi(*av);
735 else if (strcmp(str, "klfc") == 0) klfc = atoi(*av);
736 else if (strcmp(str, "klbc") == 0) klbc = atoi(*av);
737 else if (strcmp(str, "knfc") == 0) knfc = atoi(*av);
738 else if (strcmp(str, "knbc") == 0) knbc = atoi(*av);
739 else if (strcmp(str, "stfc") == 0) stfc = atoi(*av);
740 else if (strcmp(str, "stbc") == 0) stbc = atoi(*av);
741 else if (strcmp(str, "prfc") == 0) prfc = atoi(*av);
742 else if (strcmp(str, "prbc") == 0) prbc = atoi(*av);
743 else if (strcmp(str, "q1fc") == 0) q1fc = atoi(*av);
744 else if (strcmp(str, "q1bc") == 0) q1bc = atoi(*av);
745 else if (strcmp(str, "q2fc") == 0) q2fc = atoi(*av);
746 else if (strcmp(str, "q2bc") == 0) q2bc = atoi(*av);
747 else if (strcmp(str, "q3fc") == 0) q3fc = atoi(*av);
748 else if (strcmp(str, "q3bc") == 0) q3bc = atoi(*av);
749 else if (strcmp(str, "sbfc") == 0) sbfc = atoi(*av);
750 else if (strcmp(str, "sbbc") == 0) sbbc = atoi(*av);
751 else if (strcmp(str, "ncolors") == 0) ncolors = atoi(*av);
752 if(!strcmp(str, "ncolors")){
753 switch(ncolors){
754 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
755 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
756 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
757 default : snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _("Unsupported number of colors: %d"), ncolors);
758 pico_display_args_err(tmp_1k_buf, NULL, 1);
759 exit(1);
760 break;
763 goto Loop;
765 else if(strcmp(*av, "color_codes") == 0){
766 display_color_codes();
767 exit(0);
769 #endif /* ! _WINDOWS */
770 else if(strcmp(*av, "no_setlocale_collate") == 0){
771 *setlocale_collate = 0;
772 goto Loop;
774 #ifndef _WINDOWS
775 else if(strcmp(*av, "syscs") == 0){
776 use_system_translation = !use_system_translation;
777 goto Loop;
779 #endif /* ! _WINDOWS */
780 #ifdef _WINDOWS
781 else if(strcmp(*av, "dict") == 0){
782 char *cmd = *av; /* save it to use below */
783 str = *++av;
784 if(--ac){
785 int i = 0;
786 char *s;
787 #define MAX_DICTIONARY 10
788 while(str && *str){
789 if(dictionary == NULL){
790 dictionary = fs_get((MAX_DICTIONARY + 1)*sizeof(char *));
791 memset((void *) dictionary, 0, (MAX_DICTIONARY+1)*sizeof(char *));
792 if(dictionary == NULL)
793 goto Loop; /* get out of here */
795 if((s = strpbrk(str, " ,")) != NULL)
796 *s++ = '\0';
797 dictionary[i] = fs_get(strlen(str) + 1);
798 strcpy(dictionary[i++], str);
799 if(s != NULL)
800 for(; *s && (*s == ' ' || *s == ','); s++);
801 else
802 goto Loop;
803 if(i == MAX_DICTIONARY + 1)
804 goto Loop;
805 else
806 str = s;
809 else{
810 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg_s), cmd);
811 pico_display_args_err(tmp_1k_buf, NULL, 1);
812 usage++;
815 goto Loop;
817 else if(strcmp(*av, "cnf") == 0
818 || strcmp(*av, "cnb") == 0
819 || strcmp(*av, "crf") == 0
820 || strcmp(*av, "crb") == 0){
822 char *cmd = *av; /* save it to use below */
824 if(--ac){
825 str = *++av;
826 if(cmd[1] == 'n'){
827 if(cmd[2] == 'f')
828 pico_nfcolor(str);
829 else if(cmd[2] == 'b')
830 pico_nbcolor(str);
832 else if(cmd[1] == 'r'){
833 if(cmd[2] == 'f')
834 pico_rfcolor(str);
835 else if(cmd[2] == 'b')
836 pico_rbcolor(str);
839 else{
840 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_color), cmd);
841 pico_display_args_err(tmp_1k_buf, NULL, 1);
842 usage++;
845 goto Loop;
847 #endif /* _WINDOWS */
848 #ifndef _WINDOWS
849 else if(strcmp(*av, "dcs") == 0 || strcmp(*av, "kcs") == 0){
850 char *cmd = *av;
852 if(--ac){
853 if(strcmp(*av, "dcs") == 0){
854 display_character_set = *++av;
855 if(!output_charset_is_supported(display_character_set)){
856 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_output_charset), display_character_set);
857 pico_display_args_err(tmp_1k_buf, NULL, 1);
858 usage++;
861 else{
862 keyboard_character_set = *++av;
863 if(!input_charset_is_supported(keyboard_character_set)){
864 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_input_charset), keyboard_character_set);
865 pico_display_args_err(tmp_1k_buf, NULL, 1);
866 usage++;
870 else{
871 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_charset), cmd);
872 pico_display_args_err(tmp_1k_buf, NULL, 1);
873 usage++;
876 goto Loop;
878 #endif /* ! _WINDOWS */
881 * Single char options.
883 switch(c = **av){
885 * These don't take arguments.
887 case 'a':
888 gmode ^= MDDOTSOK; /* show dot files */
889 break;
890 case 'b':
891 #ifdef notdef
893 * Make MDREPLACE always on instead
894 * Don't leave this to allow turning off of MDREPLACE because the
895 * polarity of -b will have changed. Don't think anybody wants to
896 * turn it off.
898 gmode ^= MDREPLACE; /* -b for replace string in where is command */
899 #endif
900 break;
901 case 'd': /* -d for rebind delete key */
902 bindtokey(0x7f, forwdel);
903 break;
904 case 'e': /* file name completion */
905 gmode ^= MDCMPLT;
906 break;
907 case 'f': /* -f for function key use */
908 gmode ^= MDFKEY;
909 break;
910 case 'g': /* show-cursor in file browser */
911 gmode ^= MDSHOCUR;
912 break;
913 case 'h':
914 usage++;
915 break;
916 case 'j': /* allow "Goto" in file browser */
917 gmode ^= MDGOTO;
918 break;
919 case 'k': /* kill from dot */
920 gmode ^= MDDTKILL;
921 break;
922 case 'm': /* turn on mouse support */
923 gmode ^= MDMOUSE;
924 break;
925 case 'p':
926 preserve_start_stop = 1;
927 break;
928 case 'q': /* -q for termcap takes precedence */
929 gmode ^= MDTCAPWINS;
930 break;
931 case 't': /* special shutdown mode */
932 gmode ^= MDTOOL;
933 rebindfunc(wquit, quickexit);
934 break;
935 case 'v': /* -v for View File */
936 case 'V':
937 *viewflag = !*viewflag;
938 break; /* break back to inner-while */
939 case 'w': /* -w turn off word wrap */
940 gmode ^= MDWRAP;
941 break;
942 case 'x': /* suppress keyhelp */
943 sup_keyhelp = !sup_keyhelp;
944 break;
945 case 'z': /* -z to suspend */
946 gmode ^= MDSSPD;
947 break;
950 * These do take arguments.
952 case 'r': /* set fill column */
953 case 'n': /* -n for new mail notification */
954 case 's' : /* speller */
955 case 'o' : /* operating tree */
956 case 'Q' : /* Quote string */
957 case 'W' : /* Word separators */
958 if(*++*av)
959 str = *av;
960 else if(--ac)
961 str = *++av;
962 else{
963 if(c == 'r')
964 str= "72";
965 else if(c == 'n')
966 str = "180";
967 else{
968 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), c);
969 pico_display_args_err(tmp_1k_buf, NULL, 1);
970 usage++;
971 goto Loop;
975 switch(c){
976 case 's':
977 alt_speller = str;
978 break;
979 case 'o':
980 strncpy(opertree, str, NLINE);
981 gmode ^= MDTREE;
982 break;
983 case 'Q':
984 glo_quote_str_orig = str;
985 break;
986 case 'W':
987 glo_wordseps_orig = str;
988 break;
990 /* numeric args */
991 case 'r':
992 case 'n':
993 if(!isdigit((unsigned char)str[0])){
994 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), c);
995 pico_display_args_err(tmp_1k_buf, NULL, 1);
996 usage++;
999 if(c == 'r'){
1000 if((userfillcol = atoi(str)) < 1)
1001 userfillcol = 72;
1003 else{
1004 timeoutset = 1;
1005 set_input_timeout(180);
1006 if(set_input_timeout(atoi(str)) < 30)
1007 set_input_timeout(180);
1010 break;
1013 goto Loop;
1015 default: /* huh? */
1016 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_flag), c);
1017 pico_display_args_err(tmp_1k_buf, NULL, 1);
1018 usage++;
1019 break;
1024 if(usage)
1025 pico_args_help();
1027 #ifndef _WINDOWS
1028 Pcolors = pico_set_global_colors(ncolors, ntfc, ntbc, rtfc, rtbc,
1029 tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc,
1030 q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc);
1032 if(Pcolors)
1033 pico_toggle_color(1);
1034 #endif /* ! _WINDOWS */
1036 /* return the first filename for editing */
1037 if(ac > 0)
1038 return(*av);
1039 else
1040 return(NULL);
1044 #ifndef _WINDOWS
1045 PCOLORS *
1046 pico_set_global_colors(int nc, int ntfg, int ntbg, int rtfg, int rtbg,
1047 int tbfg, int tbbg, int klfg, int klbg,
1048 int knfg, int knbg, int stfg, int stbg, int prfg, int prbg,
1049 int q1fg, int q1bg, int q2fg, int q2bg, int q3fg, int q3bg,
1050 int sbfg, int sbbg)
1052 PCOLORS *pcolors = NULL;
1053 char *fg, *bg;
1055 if(nc != 0 && nc != 8 && nc != 16 && nc != 256){
1056 fprintf(stderr, "number of colors must be either 8, 16 or 256\n");
1057 exit(1);
1060 if(nc == 0){
1061 if(ntfg != -1 || ntbg != -1 || tbfg != -1 || tbbg != -1 ||
1062 klfg != -1 || klbg != -1 || knfg != -1 || knbg != -1 ||
1063 stfg != -1 || stbg != -1 || prfg != -1 || prbg != -1 ||
1064 q1fg != -1 || q1bg != -1 || q2fg != -1 || q1bg != -1 ||
1065 q3fg != -1 || q3bg != -1 || sbfg != -1 || sbbg != -1 ||
1066 rtfg != -1 || rtbg != -1){
1067 fprintf(stderr, "can not specify color numbers without specifying number of colors\n");
1068 exit(1);
1070 else
1071 return pcolors; /* no colors used */
1074 if(ntfg >= nc || ntbg >= nc || tbfg >= nc || tbbg >= nc
1075 || klfg >= nc || klbg >= nc || knfg >= nc || knbg >= nc
1076 || stfg >= nc || stbg >= nc || prfg >= nc || prbg >= nc
1077 || q1fg >= nc || q1bg >= nc || q2fg >= nc || q2bg >= nc
1078 || q3fg >= nc || q3bg >= nc || sbfg >= nc || sbbg >= nc
1079 || rtfg >= nc || rtbg >= nc){
1080 fprintf(stderr, "Error: specified a color bigger than number of colors\n");
1081 exit(1);
1084 /* Finally, we set up colors */
1085 pico_toggle_color(0);
1086 switch(nc){
1087 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
1088 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
1089 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
1090 default : break; /* impossible case */
1092 pico_toggle_color(1);
1094 pcolors = (PCOLORS *) malloc(sizeof(PCOLORS));
1095 memset((void *)pcolors, 0, sizeof(PCOLORS));
1096 /* ignore bad pair settings, also we set tbcp backwards because it will
1097 * be reversed later in the modeline function, so tbcp->fg is actually
1098 * tbcp->bg and viceversa.
1100 if(ntfg >= 0 && ntbg >= 0){ /* set normal text color */
1101 fg = colorx(ntfg); bg = colorx(ntbg);
1102 pcolors->ntcp = new_color_pair(fg, bg);
1103 pico_nfcolor(fg);
1104 pico_nbcolor(bg);
1106 /* reverse means reverse of normal text */
1107 if((rtfg < 0 || rtbg < 0) && (ntfg >= 0 && ntbg >= 0)){
1108 rtfg = ntbg;
1109 rtbg = ntfg;
1111 if(rtfg >= 0 && rtbg >= 0){ /* set reverse text color */
1112 fg = colorx(rtfg); bg = colorx(rtbg);
1113 pcolors->rtcp = new_color_pair(fg, bg);
1114 pico_rfcolor(fg);
1115 pico_rbcolor(bg);
1117 /* If the user does not specify this, we will set up all
1118 * backgrounds for text to the normal text background
1120 if(ntbg >= 0){
1121 if(knbg < 0) knbg = ntbg;
1122 if(q1bg < 0) q1bg = ntbg;
1123 if(q2bg < 0) q2bg = ntbg;
1124 if(q3bg < 0) q3bg = ntbg;
1125 if(sbbg < 0) sbbg = ntbg;
1127 if(rtfg >= 0 && rtbg >= 0){ /* set default reverse */
1128 if(tbfg < 0 || tbbg < 0){ /* set titlebar colors to reverse color if any missing*/
1129 tbfg = rtfg; tbbg = rtbg;
1131 if(klfg < 0 || klbg < 0){ /* set key label colors */
1132 klfg = rtfg; klbg = rtbg;
1134 if(stfg < 0 || stbg < 0){ /* set status colors */
1135 stfg = rtfg; stbg = rtbg;
1137 if(prfg >= 0 && prbg >= 0){ /* set prompt colors */
1138 prfg = rtfg; prbg = rtbg;
1141 if(tbfg >= 0 && tbbg >= 0) /* set titlebar colors */
1142 pcolors->tbcp = new_color_pair(colorx(tbbg), colorx(tbfg));
1143 if(klfg >= 0 && klbg >= 0) /* set key label colors */
1144 pcolors->klcp = new_color_pair(colorx(klfg), colorx(klbg));
1145 if(knfg >= 0 && knbg >= 0) /* set key name colors */
1146 pcolors->kncp = new_color_pair(colorx(knfg), colorx(knbg));
1147 if(stfg >= 0 && stbg >= 0) /* set status colors */
1148 pcolors->stcp = new_color_pair(colorx(stfg), colorx(stbg));
1149 if(prfg >= 0 && prbg >= 0) /* set prompt colors */
1150 pcolors->prcp = new_color_pair(colorx(prfg), colorx(prbg));
1151 if(q1fg >= 0 && q1bg >= 0) /* set quote level 1 colors */
1152 pcolors->qlcp = new_color_pair(colorx(q1fg), colorx(q1bg));
1153 if(q2fg >= 0 && q2bg >= 0) /* set quote level 2 colors */
1154 pcolors->qllcp = new_color_pair(colorx(q2fg), colorx(q2bg));
1155 if(q3fg >= 0 && q3bg >= 0) /* set quote level 3 colors */
1156 pcolors->qlllcp = new_color_pair(colorx(q3fg), colorx(q3bg));
1157 if(sbfg >= 0 && sbbg >= 0) /* set signature block colors */
1158 pcolors->sbcp = new_color_pair(colorx(sbfg), colorx(sbbg));
1160 if(pico_usingcolor())
1161 pico_set_normal_color();
1163 return pcolors;
1165 #endif /* ! _WINDOWS */
1167 #ifdef _WINDOWS
1172 pico_file_drop(int x, int y, char *filename)
1175 * if current buffer is unchanged
1176 * *or* "new buffer" and no current text
1178 if(((curwp->w_bufp->b_flag & BFCHG) == 0)
1179 || (curwp->w_bufp->b_fname[0] == '\0'
1180 && curwp->w_bufp->b_linep == lforw(curwp->w_bufp->b_linep)
1181 && curwp->w_doto == 0)){
1182 register BUFFER *bp = curwp->w_bufp;
1183 char bname[NBUFN];
1185 makename(bname, filename);
1186 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
1187 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1188 strncpy(bp->b_fname, filename, sizeof(bp->b_fname));
1189 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1190 bp->b_flag &= ~BFCHG; /* turn off change bit */
1191 if (readin(filename, 1, 1) == ABORT) {
1192 strncpy(bp->b_bname, "", sizeof(bp->b_bname));
1193 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1194 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
1195 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1198 bp->b_dotp = bp->b_linep;
1199 bp->b_doto = 0;
1201 else{
1202 EML eml;
1204 ifile(filename);
1205 curwp->w_flag |= WFHARD;
1206 update();
1207 eml.s = filename;
1208 emlwrite("Inserted dropped file \"%s\"", &eml);
1211 curwp->w_flag |= WFHARD;
1212 update(); /* restore cursor */
1213 return(1);
1215 #endif
1218 /*----------------------------------------------------------------------
1219 print a few lines of help for command line arguments
1221 Args: none
1223 Result: prints help messages
1224 ----------------------------------------------------------------------*/
1225 void
1226 pico_args_help(void)
1228 char **a;
1229 char *pp[2];
1231 pp[1] = NULL;
1233 /** print out possible starting arguments... **/
1235 for(a=args_pico_args; a && *a; a++){
1236 pp[0] = _(*a);
1237 pico_display_args_err(NULL, pp, 0);
1240 exit(1);
1244 void
1245 pico_vers_help(void)
1247 char v0[100];
1248 char *v[2];
1250 snprintf(v0, sizeof(v0), "Pico %.50s", version);
1251 v[0] = v0;
1252 v[1] = NULL;
1254 pico_display_args_err(NULL, v, 0);
1255 exit(1);
1259 /*----------------------------------------------------------------------
1260 write argument error to the display...
1262 Args: none
1264 Result: prints help messages
1265 ----------------------------------------------------------------------*/
1266 void
1267 pico_display_args_err(char *s, char **a, int err)
1269 char errstr[256], *errp;
1270 FILE *fp = err ? stderr : stdout;
1271 #ifdef _WINDOWS
1272 char tmp_20k_buf[SIZEOF_20KBUF];
1273 #endif
1276 if(err && s)
1277 snprintf(errp = errstr, sizeof(errstr), _("Argument Error: %.200s"), s);
1278 else
1279 errp = s;
1281 #ifdef _WINDOWS
1282 if(errp)
1283 mswin_messagebox(errp, err);
1285 if(a && *a){
1286 strncpy(tmp_20k_buf, *a++, SIZEOF_20KBUF);
1287 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1288 while(a && *a){
1289 strncat(tmp_20k_buf, "\n", SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1290 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1291 strncat(tmp_20k_buf, *a++, SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1292 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1295 mswin_messagebox(tmp_20k_buf, err);
1297 #else
1298 if(errp)
1299 fprintf(fp, "%s\n", errp);
1301 while(a && *a)
1302 fprintf(fp, "%s\n", *a++);
1303 #endif