1 /**************************************************************************
2  *   definitions.h  --  This file is part of GNU nano.                    *
3  *                                                                        *
4  *   Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc.    *
5  *   Copyright (C) 2014-2017 Benno Schulenberg                            *
6  *                                                                        *
7  *   GNU nano is free software: you can redistribute it and/or modify     *
8  *   it under the terms of the GNU General Public License as published    *
9  *   by the Free Software Foundation, either version 3 of the License,    *
10  *   or (at your option) any later version.                               *
11  *                                                                        *
12  *   GNU nano is distributed in the hope that it will be useful,          *
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty          *
14  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.              *
15  *   See the GNU General Public License for more details.                 *
16  *                                                                        *
17  *   You should have received a copy of the GNU General Public License    *
18  *   along with this program.  If not, see http://www.gnu.org/licenses/.  *
19  *                                                                        *
20  **************************************************************************/
21 
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 #ifdef NEED_XOPEN_SOURCE_EXTENDED
27 #ifndef _XOPEN_SOURCE_EXTENDED
28 #define _XOPEN_SOURCE_EXTENDED  1
29 #endif
30 #endif
31 
32 #if defined(__HAIKU__) && !defined(_DEFAULT_SOURCE)
33 #define _DEFAULT_SOURCE  1
34 #endif
35 
36 #ifdef __TANDEM
37 /* Tandem NonStop Kernel support. */
38 #include <floss.h>
39 #define ROOT_UID  65535
40 #else
41 #define ROOT_UID  0
42 #endif
43 
44 #ifdef HAVE_LIMITS_H
45 #include <limits.h>
46 #endif
47 
48 /* Set a default value for PATH_MAX if there isn't one. */
49 #ifndef PATH_MAX
50 #define PATH_MAX  4096
51 #endif
52 
53 #ifdef HAVE_SYS_PARAM_H
54 #include <sys/param.h>
55 #endif
56 
57 #include <dirent.h>
58 #include <regex.h>
59 #include <signal.h>
60 #include <stdlib.h>
61 #include <sys/stat.h>
62 
63 /* Prefer wide ncurses over normal ncurses over curses. */
64 #if defined(HAVE_NCURSESW_NCURSES_H)
65 #include <ncursesw/ncurses.h>
66 #elif defined(HAVE_NCURSES_H)
67 #include <ncurses.h>
68 #else
69 #include <curses.h>
70 #endif
71 
72 /* Native language support. */
73 #ifdef ENABLE_NLS
74 #ifdef HAVE_LIBINTL_H
75 #include <libintl.h>
76 #endif
77 #define _(string)  gettext(string)
78 #define P_(singular, plural, number)  ngettext(singular, plural, number)
79 #else
80 #define _(string)  (string)
81 #define P_(singular, plural, number)  (number == 1 ? singular : plural)
82 #endif
83 /* For marking a string on which gettext() will be called later. */
84 #define gettext_noop(string)  (string)
85 #define N_(string)  gettext_noop(string)
86 
87 /* If we aren't using an ncurses with mouse support, then
88  * exclude the mouse routines, as they are useless then. */
89 #ifndef NCURSES_MOUSE_VERSION
90 #undef ENABLE_MOUSE
91 #endif
92 
93 #if defined(ENABLE_WRAPPING) || defined(ENABLE_JUSTIFY)
94 #define ENABLED_WRAPORJUSTIFY  1
95 #endif
96 
97 /* Suppress warnings for __attribute__((warn_unused_result)). */
98 #define IGNORE_CALL_RESULT(call)  do { if (call) {} } while(0)
99 
100 /* Macros for flags, indexing each bit in a small array. */
101 #define FLAGS(flag)  flags[((flag) / (sizeof(unsigned) * 8))]
102 #define FLAGMASK(flag)  ((unsigned)1 << ((flag) % (sizeof(unsigned) * 8)))
103 #define SET(flag)  FLAGS(flag) |= FLAGMASK(flag)
104 #define UNSET(flag)  FLAGS(flag) &= ~FLAGMASK(flag)
105 #define ISSET(flag)  ((FLAGS(flag) & FLAGMASK(flag)) != 0)
106 #define TOGGLE(flag)  FLAGS(flag) ^= FLAGMASK(flag)
107 
108 #define BACKWARD  FALSE
109 #define FORWARD  TRUE
110 
111 #define BLIND  FALSE
112 #define VISIBLE  TRUE
113 
114 #define JUSTFIND   0
115 #define REPLACING  1
116 #define INREGION   2
117 
118 #define NORMAL  TRUE
119 #define SPECIAL  FALSE
120 #define TEMPORARY  FALSE
121 
122 #define ANNOTATE  TRUE
123 #define NONOTES  FALSE
124 
125 #ifdef ENABLE_UTF8
126 /* In UTF-8 a valid character is at most four bytes long. */
127 #define MAXCHARLEN  4
128 #else
129 #define MAXCHARLEN  1
130 #endif
131 
132 /* The default width of a tab in spaces. */
133 #define WIDTH_OF_TAB  8
134 
135 /* The default number of columns from end of line where wrapping occurs. */
136 #define COLUMNS_FROM_EOL  8
137 
138 /* The default comment character when a syntax does not specify any. */
139 #define GENERAL_COMMENT_CHARACTER  "#"
140 
141 /* The maximum number of search/replace history strings saved. */
142 #define MAX_SEARCH_HISTORY  100
143 
144 /* The largest size_t number that doesn't have the high bit set. */
145 #define HIGHEST_POSITIVE  ((~(size_t)0) >> 1)
146 
147 #ifdef ENABLE_COLOR
148 #define THE_DEFAULT  -1
149 #define BAD_COLOR  -2
150 
151 /* Flags for indicating how a multiline regex pair apply to a line. */
152 #define NOTHING      (1<<1)
153 		/* The start/end regexes don't cover this line at all. */
154 #define STARTSHERE   (1<<2)
155 		/* The start regex matches on this line, the end regex on a later one. */
156 #define WHOLELINE    (1<<3)
157 		/* The start regex matches on an earlier line, the end regex on a later one. */
158 #define ENDSHERE     (1<<4)
159 		/* The start regex matches on an earlier line, the end regex on this one. */
160 #define JUSTONTHIS   (1<<5)
161 		/* Both the start and end regexes match within this line. */
162 #define WOULDBE      (1<<6)
163 		/* An unpaired start match is on or before this line. */
164 #endif
165 
166 /* Basic control codes. */
167 #define ESC_CODE  0x1B
168 #define DEL_CODE  0x7F
169 
170 /* Codes for "modified" Arrow keys, beyond KEY_MAX of ncurses. */
171 #define CONTROL_LEFT    0x401
172 #define CONTROL_RIGHT   0x402
173 #define CONTROL_UP      0x403
174 #define CONTROL_DOWN    0x404
175 #define CONTROL_HOME    0x405
176 #define CONTROL_END     0x406
177 #define CONTROL_DELETE  0x40D
178 #define SHIFT_CONTROL_LEFT    0x411
179 #define SHIFT_CONTROL_RIGHT   0x412
180 #define SHIFT_CONTROL_UP      0x413
181 #define SHIFT_CONTROL_DOWN    0x414
182 #define SHIFT_CONTROL_HOME    0x415
183 #define SHIFT_CONTROL_END     0x416
184 #define CONTROL_SHIFT_DELETE  0x41D
185 #define ALT_LEFT      0x421
186 #define ALT_RIGHT     0x422
187 #define ALT_UP        0x423
188 #define ALT_DOWN      0x424
189 #define ALT_PAGEUP    0x427
190 #define ALT_PAGEDOWN  0x428
191 #define ALT_INSERT    0x42C
192 #define ALT_DELETE    0x42D
193 #define SHIFT_ALT_LEFT   0x431
194 #define SHIFT_ALT_RIGHT  0x432
195 #define SHIFT_ALT_UP     0x433
196 #define SHIFT_ALT_DOWN   0x434
197 //#define SHIFT_LEFT 0x451
198 //#define SHIFT_RIGHT 0x452
199 #define SHIFT_UP        0x453
200 #define SHIFT_DOWN      0x454
201 #define SHIFT_HOME      0x455
202 #define SHIFT_END       0x456
203 #define SHIFT_PAGEUP    0x457
204 #define SHIFT_PAGEDOWN  0x458
205 #define SHIFT_DELETE    0x45D
206 #define SHIFT_TAB       0x45F
207 
208 /* A special keycode for when <Tab> is pressed while the mark is on. */
209 #define INDENT_KEY  0x4F1
210 
211 /* A special keycode to signal the beginning and end of a bracketed paste. */
212 #define BRACKETED_PASTE_MARKER  0x4FB
213 
214 /* A special keycode for when a key produces an unknown escape sequence. */
215 #define FOREIGN_SEQUENCE  0x4FC
216 
217 /* A special keycode for plugging into the input stream after a suspension. */
218 #define KEY_FLUSH  KEY_F0
219 
220 #ifndef NANO_TINY
221 /* A special keycode for when we get a SIGWINCH (a window resize). */
222 #define KEY_WINCH  -2
223 
224 /* Some extra flags for the undo function. */
225 #define WAS_BACKSPACE_AT_EOF  (1<<1)
226 #define WAS_WHOLE_LINE        (1<<2)
227 #define INCLUDED_LAST_LINE    (1<<3)
228 #define MARK_WAS_SET          (1<<4)
229 #define CURSOR_WAS_AT_HEAD    (1<<5)
230 #define HAD_ANCHOR_AT_START   (1<<6)
231 #endif /* !NANO_TINY */
232 
233 /* Identifiers for the different menus. */
234 #define MMAIN          (1<<0)
235 #define MWHEREIS       (1<<1)
236 #define MREPLACE       (1<<2)
237 #define MREPLACEWITH   (1<<3)
238 #define MGOTOLINE      (1<<4)
239 #define MWRITEFILE     (1<<5)
240 #define MINSERTFILE    (1<<6)
241 #define MEXECUTE       (1<<7)
242 #define MHELP          (1<<8)
243 #define MSPELL         (1<<9)
244 #define MBROWSER      (1<<10)
245 #define MWHEREISFILE  (1<<11)
246 #define MGOTODIR      (1<<12)
247 #define MYESNO        (1<<13)
248 #define MLINTER       (1<<14)
249 #define MFINDINHELP   (1<<15)
250 /* This is an abbreviation for all menus except Help and Browser and YesNo. */
251 #define MMOST  (MMAIN|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE|MWRITEFILE|MINSERTFILE|\
252                 MEXECUTE|MWHEREISFILE|MGOTODIR|MFINDINHELP|MSPELL|MLINTER)
253 #ifndef NANO_TINY
254 #define MSOME  MMOST|MBROWSER
255 #else
256 #define MSOME  MMAIN|MBROWSER
257 #endif
258 
259 /* Enumeration types. */
260 typedef enum {
261 	UNSPECIFIED, NIX_FILE, DOS_FILE, MAC_FILE
262 } format_type;
263 
264 typedef enum {
265 	VACUUM, HUSH, REMARK, INFO, NOTICE, AHEM, MILD, ALERT
266 } message_type;
267 
268 typedef enum {
269 	OVERWRITE, APPEND, PREPEND
270 } kind_of_writing_type;
271 
272 typedef enum {
273 	CENTERING, FLOWING, STATIONARY
274 } update_type;
275 
276 /* The kinds of undo actions.  ADD...REPLACE must come first. */
277 typedef enum {
278 	ADD, ENTER, BACK, DEL, JOIN, REPLACE,
279 #ifdef ENABLE_WRAPPING
280 	SPLIT_BEGIN, SPLIT_END,
281 #endif
282 	INDENT, UNINDENT,
283 #ifdef ENABLE_COMMENT
284 	COMMENT, UNCOMMENT, PREFLIGHT,
285 #endif
286 	ZAP, CUT, CUT_TO_EOF, COPY, PASTE, INSERT,
287 	COUPLE_BEGIN, COUPLE_END, OTHER
288 } undo_type;
289 
290 /* The elements of the interface that can be colored differently. */
291 enum {
292 	TITLE_BAR = 0,
293 	LINE_NUMBER,
294 	GUIDE_STRIPE,
295 	SCROLL_BAR,
296 	SELECTED_TEXT,
297 	SPOTLIGHTED,
298 	MINI_INFOBAR,
299 	PROMPT_BAR,
300 	STATUS_BAR,
301 	ERROR_MESSAGE,
302 	KEY_COMBO,
303 	FUNCTION_TAG,
304 	NUMBER_OF_ELEMENTS
305 };
306 
307 /* Enumeration used in the flags array.  See the definition of FLAGMASK. */
308 enum {
309 	DONTUSE = 0,
310 	CASE_SENSITIVE,
311 	CONSTANT_SHOW,
312 	NO_HELP,
313 	SUSPENDABLE,
314 	NO_WRAP,
315 	AUTOINDENT,
316 	VIEW_MODE,
317 	USE_MOUSE,
318 	USE_REGEXP,
319 	SAVE_ON_EXIT,
320 	CUT_FROM_CURSOR,
321 	BACKWARDS_SEARCH,
322 	MULTIBUFFER,
323 	REBIND_DELETE,
324 	RAW_SEQUENCES,
325 	NO_CONVERT,
326 	MAKE_BACKUP,
327 	INSECURE_BACKUP,
328 	NO_SYNTAX,
329 	PRESERVE,
330 	HISTORYLOG,
331 	RESTRICTED,
332 	SMART_HOME,
333 	WHITESPACE_DISPLAY,
334 	TABS_TO_SPACES,
335 	QUICK_BLANK,
336 	WORD_BOUNDS,
337 	NO_NEWLINES,
338 	BOLD_TEXT,
339 	SOFTWRAP,
340 	POSITIONLOG,
341 	LOCKING,
342 	NOREAD_MODE,
343 	MAKE_IT_UNIX,
344 	TRIM_BLANKS,
345 	SHOW_CURSOR,
346 	LINE_NUMBERS,
347 	AT_BLANKS,
348 	AFTER_ENDS,
349 	LET_THEM_ZAP,
350 	BREAK_LONG_LINES,
351 	JUMPY_SCROLLING,
352 	EMPTY_LINE,
353 	INDICATOR,
354 	BOOKSTYLE,
355 	STATEFLAGS,
356 	USE_MAGIC,
357 	MINIBAR
358 };
359 
360 /* Structure types. */
361 #ifdef ENABLE_COLOR
362 typedef struct colortype {
363 	short id;
364 		/* An ordinal number (if this color combo is for a multiline regex). */
365 	short fg;
366 		/* This combo's foreground color. */
367 	short bg;
368 		/* This combo's background color. */
369 	short pairnum;
370 		/* The pair number for this foreground/background color combination. */
371 	int attributes;
372 		/* Pair number and brightness composed into ready-to-use attributes. */
373 	regex_t *start;
374 		/* The compiled regular expression for 'start=', or the only one. */
375 	regex_t *end;
376 		/* The compiled regular expression for 'end=', if any. */
377 	struct colortype *next;
378 		/* Next color combination. */
379 } colortype;
380 
381 typedef struct regexlisttype {
382 	regex_t *one_rgx;
383 		/* A regex to match things that imply a certain syntax. */
384 	struct regexlisttype *next;
385 		/* The next regex. */
386 } regexlisttype;
387 
388 typedef struct augmentstruct {
389 	char *filename;
390 		/* The file where the syntax is extended. */
391 	ssize_t lineno;
392 		/* The number of the line of the extendsyntax command. */
393 	char *data;
394 		/* The text of the line. */
395 	struct augmentstruct *next;
396 		/* Next node. */
397 } augmentstruct;
398 
399 typedef struct syntaxtype {
400 	char *name;
401 		/* The name of this syntax. */
402 	char *filename;
403 		/* File where the syntax is defined, or NULL if not an included file. */
404 	size_t lineno;
405 		/* The line number where the 'syntax' command was found. */
406 	augmentstruct *augmentations;
407 		/* List of extendsyntax commands to apply when loaded. */
408 	regexlisttype *extensions;
409 		/* The list of extensions that this syntax applies to. */
410 	regexlisttype *headers;
411 		/* The list of headerlines that this syntax applies to. */
412 	regexlisttype *magics;
413 		/* The list of libmagic results that this syntax applies to. */
414 	char *linter;
415 		/* The command with which to lint this type of file. */
416 	char *formatter;
417 		/* The command with which to format/modify/arrange this type of file. */
418 	char *tab;
419 		/* What the Tab key should produce; NULL for default behavior. */
420 #ifdef ENABLE_COMMENT
421 	char *comment;
422 		/* The line comment prefix (and postfix) for this type of file. */
423 #endif
424 	colortype *color;
425 		/* The colors and their regexes used in this syntax. */
426 	short nmultis;
427 		/* How many multiline regex strings this syntax has. */
428 	struct syntaxtype *next;
429 		/* Next syntax. */
430 } syntaxtype;
431 
432 typedef struct lintstruct {
433 	ssize_t lineno;
434 		/* Line number of the error. */
435 	ssize_t colno;
436 		/* Column # of the error. */
437 	char *msg;
438 		/* Error message text. */
439 	char *filename;
440 		/* Filename. */
441 	struct lintstruct *next;
442 		/* Next error. */
443 	struct lintstruct *prev;
444 		/* Previous error. */
445 } lintstruct;
446 #endif /* ENABLE_COLOR */
447 
448 /* More structure types. */
449 typedef struct linestruct {
450 	char *data;
451 		/* The text of this line. */
452 	ssize_t lineno;
453 		/* The number of this line. */
454 	struct linestruct *next;
455 		/* Next node. */
456 	struct linestruct *prev;
457 		/* Previous node. */
458 #ifdef ENABLE_COLOR
459 	short *multidata;
460 		/* Array of which multi-line regexes apply to this line. */
461 #endif
462 #ifndef NANO_TINY
463 	bool has_anchor;
464 		/* Whether the user has placed an anchor at this line. */
465 #endif
466 } linestruct;
467 
468 #ifndef NANO_TINY
469 typedef struct groupstruct {
470 	ssize_t top_line;
471 		/* First line of group. */
472 	ssize_t bottom_line;
473 		/* Last line of group. */
474 	char **indentations;
475 		/* String data used to restore the affected lines; one per line. */
476 	struct groupstruct *next;
477 		/* The next group, if any. */
478 } groupstruct;
479 
480 typedef struct undostruct {
481 	undo_type type;
482 		/* The operation type that this undo item is for. */
483 	int xflags;
484 		/* Some flag data to mark certain corner cases. */
485 	ssize_t head_lineno;
486 		/* The line number where the operation began or ended. */
487 	size_t head_x;
488 		/* The x position where the operation began or ended. */
489 	char *strdata;
490 		/* String data to help restore the affected line. */
491 	size_t wassize;
492 		/* The file size before the action. */
493 	size_t newsize;
494 		/* The file size after the action. */
495 	groupstruct *grouping;
496 		/* Undo info specific to groups of lines. */
497 	linestruct *cutbuffer;
498 		/* A copy of the cutbuffer. */
499 	ssize_t tail_lineno;
500 		/* Mostly the line number of the current line; sometimes something else. */
501 	size_t tail_x;
502 		/* The x position corresponding to the above line number. */
503 	struct undostruct *next;
504 		/* A pointer to the undo item of the preceding action. */
505 } undostruct;
506 #endif /* !NANO_TINY */
507 
508 #ifdef ENABLE_HISTORIES
509 typedef struct poshiststruct {
510 	char *filename;
511 		/* The full path plus name of the file. */
512 	ssize_t linenumber;
513 		/* The line where the cursor was when we closed the file. */
514 	ssize_t columnnumber;
515 		/* The column where the cursor was. */
516 	struct poshiststruct *next;
517 		/* The next item of position history. */
518 } poshiststruct;
519 #endif
520 
521 typedef struct openfilestruct {
522 	char *filename;
523 		/* The file's name. */
524 	linestruct *filetop;
525 		/* The file's first line. */
526 	linestruct *filebot;
527 		/* The file's last line. */
528 	linestruct *edittop;
529 		/* The current top of the edit window for this file. */
530 	linestruct *current;
531 		/* The current line for this file. */
532 	size_t totsize;
533 		/* The file's total number of characters. */
534 	size_t firstcolumn;
535 		/* The starting column of the top line of the edit window.
536 		 * When not in softwrap mode, it's always zero. */
537 	size_t current_x;
538 		/* The file's x-coordinate position. */
539 	size_t placewewant;
540 		/* The file's x position we would like. */
541 	ssize_t current_y;
542 		/* The file's y-coordinate position. */
543 	struct stat *statinfo;
544 		/* The file's stat information from when it was opened or last saved. */
545 #ifdef ENABLE_WRAPPING
546 	linestruct *spillage_line;
547 		/* The line for prepending stuff to during automatic hard-wrapping. */
548 #endif
549 #ifndef NANO_TINY
550 	linestruct *mark;
551 		/* The line in the file where the mark is set; NULL if not set. */
552 	size_t mark_x;
553 		/* The mark's x position in the above line. */
554 	bool softmark;
555 		/* Whether a marked region was made by holding Shift. */
556 	format_type fmt;
557 		/* The file's format -- Unix or DOS or Mac. */
558 	char *lock_filename;
559 		/* The path of the lockfile, if we created one. */
560 	undostruct *undotop;
561 		/* The top of the undo list. */
562 	undostruct *current_undo;
563 		/* The current (i.e. next) level of undo. */
564 	undostruct *last_saved;
565 		/* The undo item at which the file was last saved. */
566 	undo_type last_action;
567 		/* The type of the last action the user performed. */
568 #endif
569 	bool modified;
570 		/* Whether the file has been modified. */
571 #ifdef ENABLE_COLOR
572 	syntaxtype *syntax;
573 		/* The syntax that applies to this file, if any. */
574 #endif
575 #ifdef ENABLE_MULTIBUFFER
576 	char *errormessage;
577 		/* The ALERT message (if any) that occurred when opening the file. */
578 	struct openfilestruct *next;
579 		/* The next open file, if any. */
580 	struct openfilestruct *prev;
581 		/* The preceding open file, if any. */
582 #endif
583 } openfilestruct;
584 
585 #ifdef ENABLE_NANORC
586 typedef struct rcoption {
587 	const char *name;
588 		/* The name of the rcfile option. */
589 	long flag;
590 		/* The flag associated with it, if any. */
591 } rcoption;
592 #endif
593 
594 typedef struct keystruct {
595 	const char *keystr;
596 		/* The string that describes the keystroke, like "^C" or "M-R". */
597 	int keycode;
598 		/* The integer that, together with meta, identifies the keystroke. */
599 	int menus;
600 		/* The menus in which this keystroke is bound. */
601 	void (*func)(void);
602 		/* The function to which this keystroke is bound. */
603 #ifndef NANO_TINY
604 	int toggle;
605 		/* If a toggle, what we're toggling. */
606 	int ordinal;
607 		/* The how-manieth toggle this is, in order to be able to
608 		 * keep them in sequence. */
609 #endif
610 #ifdef ENABLE_NANORC
611 	char *expansion;
612 		/* The string of keycodes to which this shortcut is expanded. */
613 #endif
614 	struct keystruct *next;
615 		/* Next in the list. */
616 } keystruct;
617 
618 typedef struct funcstruct {
619 	void (*func)(void);
620 		/* The actual function to call. */
621 	const char *desc;
622 		/* The function's short description, for example "Where Is". */
623 #ifdef ENABLE_HELP
624 	const char *help;
625 		/* The help-screen text for this function. */
626 	bool blank_after;
627 		/* Whether there should be a blank line after the help text
628 		 * for this function. */
629 #endif
630 	bool viewok;
631 		/* Is this function allowed when in view mode? */
632 	int menus;
633 		/* In what menus this function applies. */
634 	struct funcstruct *next;
635 		/* Next item in the list. */
636 } funcstruct;
637 
638 #ifdef ENABLE_WORDCOMPLETION
639 typedef struct completionstruct {
640 	char *word;
641 	struct completionstruct *next;
642 } completionstruct;
643 #endif
644