nano.h 16.2 KB
Newer Older
Chris Allegretta's avatar
Chris Allegretta committed
1
2
3
/**************************************************************************
 *   nano.h                                                               *
 *                                                                        *
4
 *   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,  *
5
 *   2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc.    *
Chris Allegretta's avatar
Chris Allegretta committed
6
7
 *   This program is free software; you can redistribute it and/or modify *
 *   it under the terms of the GNU General Public License as published by *
8
 *   the Free Software Foundation; either version 3, or (at your option)  *
Chris Allegretta's avatar
Chris Allegretta committed
9
10
 *   any later version.                                                   *
 *                                                                        *
11
12
13
14
 *   This program is distributed in the hope that it will be useful, but  *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    *
 *   General Public License for more details.                             *
Chris Allegretta's avatar
Chris Allegretta committed
15
16
17
 *                                                                        *
 *   You should have received a copy of the GNU General Public License    *
 *   along with this program; if not, write to the Free Software          *
18
19
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA            *
 *   02110-1301, USA.                                                     *
Chris Allegretta's avatar
Chris Allegretta committed
20
21
22
 *                                                                        *
 **************************************************************************/

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
23
24
25
#ifndef NANO_H
#define NANO_H 1

26
27
28
29
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

30
31
32
#ifdef NEED_XOPEN_SOURCE_EXTENDED
#ifndef _XOPEN_SOURCE_EXTENDED
#define _XOPEN_SOURCE_EXTENDED 1
33
34
#endif
#endif
35

36
#ifdef __TANDEM
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
37
/* Tandem NonStop Kernel support. */
38
39
40
41
42
43
#include <floss.h>
#define NANO_ROOT_UID 65535
#else
#define NANO_ROOT_UID 0
#endif

Chris Allegretta's avatar
Chris Allegretta committed
44
45
46
47
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif

48
49
50
51
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif

52
53
54
55
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif

Benno Schulenberg's avatar
Benno Schulenberg committed
56
/* Suppress warnings for __attribute__((warn_unused_result)). */
57
#define IGNORE_CALL_RESULT(call) do { if (call) {} } while(0)
58

59
60
/* Macros for flags, indexing each bit in a small array. */
#define FLAGS(flag) flags[((flag) / (sizeof(unsigned) * 8))]
61
62
63
64
65
#define FLAGMASK(flag) (1 << ((flag) % (sizeof(unsigned) * 8)))
#define SET(flag) FLAGS(flag) |= FLAGMASK(flag)
#define UNSET(flag) FLAGS(flag) &= ~FLAGMASK(flag)
#define ISSET(flag) ((FLAGS(flag) & FLAGMASK(flag)) != 0)
#define TOGGLE(flag) FLAGS(flag) ^= FLAGMASK(flag)
Chris Allegretta's avatar
Chris Allegretta committed
66

67
/* Macros for character allocation and more. */
Chris Allegretta's avatar
Chris Allegretta committed
68
#define charalloc(howmuch) (char *)nmalloc((howmuch) * sizeof(char))
69
#define charealloc(ptr, howmuch) (char *)nrealloc(ptr, (howmuch) * sizeof(char))
70
#define charmove(dest, src, n) memmove(dest, src, (n) * sizeof(char))
71
#define charset(dest, src, n) memset(dest, src, (n) * sizeof(char))
72

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
73
/* Set a default value for PATH_MAX if there isn't one. */
74
#ifndef PATH_MAX
75
#define PATH_MAX 4096
76
#endif
Chris Allegretta's avatar
Chris Allegretta committed
77

78
79
80
81
82
83
84
#ifdef USE_SLANG
/* Slang support. */
#include <slcurses.h>
/* Slang curses emulation brain damage, part 3: Slang doesn't define the
 * curses equivalents of the Insert or Delete keys. */
#define KEY_DC SL_KEY_DELETE
#define KEY_IC SL_KEY_IC
85
/* Ncurses support. */
86
87
#elif defined(HAVE_NCURSESW_NCURSES_H)
#include <ncursesw/ncurses.h>
88
#elif defined(HAVE_NCURSES_H)
Chris Allegretta's avatar
Chris Allegretta committed
89
#include <ncurses.h>
90
91
#else
/* Curses support. */
92
#include <curses.h>
Chris Allegretta's avatar
Chris Allegretta committed
93
94
#endif /* CURSES_H */

95
#ifdef ENABLE_NLS
96
/* Native language support. */
97
98
99
100
101
#ifdef HAVE_LIBINTL_H
#include <libintl.h>
#endif
#define _(string) gettext(string)
#define P_(singular, plural, number) ngettext(singular, plural, number)
102
#else
103
104
#define _(string) (string)
#define P_(singular, plural, number) (number == 1 ? singular : plural)
Chris Allegretta's avatar
Chris Allegretta committed
105
#endif
106
107
#define gettext_noop(string) (string)
#define N_(string) gettext_noop(string)
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
108
	/* Mark a string that will be sent to gettext() later. */
Chris Allegretta's avatar
Chris Allegretta committed
109

110
#include <stddef.h>
111
#include <stdlib.h>
112
113
#include <sys/types.h>
#include <sys/stat.h>
114
115
116
117
#include <dirent.h>
#ifdef HAVE_REGEX_H
#include <regex.h>
#endif
118
#include <signal.h>
119
#include <assert.h>
Chris Allegretta's avatar
Chris Allegretta committed
120

121
/* If no vsnprintf(), use the version from glib 2.x. */
122
#ifndef HAVE_VSNPRINTF
123
#include <glib.h>
124
#define vsnprintf g_vsnprintf
Chris Allegretta's avatar
Chris Allegretta committed
125
#endif
126

127
128
129
130
131
132
133
134
135
/* If no isblank(), iswblank(), strcasecmp(), strncasecmp(),
 * strcasestr(), strnlen(), getdelim(), or getline(), use the versions
 * we have. */
#ifndef HAVE_ISBLANK
#define isblank nisblank
#endif
#ifndef HAVE_ISWBLANK
#define iswblank niswblank
#endif
136
137
138
139
140
141
142
143
144
145
146
147
#ifndef HAVE_STRCASECMP
#define strcasecmp nstrcasecmp
#endif
#ifndef HAVE_STRNCASECMP
#define strncasecmp nstrncasecmp
#endif
#ifndef HAVE_STRCASESTR
#define strcasestr nstrcasestr
#endif
#ifndef HAVE_STRNLEN
#define strnlen nstrnlen
#endif
148
149
150
151
152
153
154
#ifndef HAVE_GETDELIM
#define getdelim ngetdelim
#endif
#ifndef HAVE_GETLINE
#define getline ngetline
#endif

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
155
156
/* If we aren't using ncurses with mouse support, turn the mouse support
 * off, as it's useless then. */
157
158
159
#ifndef NCURSES_MOUSE_VERSION
#define DISABLE_MOUSE 1
#endif
160

161
162
#if defined(DISABLE_WRAPPING) && defined(DISABLE_JUSTIFY)
#define DISABLE_WRAPJUSTIFY 1
163
#endif
164

165
166
167
168
169
/* Enumeration types. */
typedef enum {
    NIX_FILE, DOS_FILE, MAC_FILE
} file_format;

170
171
172
173
typedef enum {
    HUSH, MILD, ALERT
} message_type;

174
175
176
177
typedef enum {
    OVERWRITE, APPEND, PREPEND
} append_type;

178
typedef enum {
179
    UPWARD, DOWNWARD
180
} scroll_dir;
181
182

typedef enum {
183
    CENTERING, FLOWING, STATIONARY
184
} update_type;
185

186
typedef enum {
187
    CONTROL, META, FKEY, RAWINPUT
188
}  key_type;
189

190
typedef enum {
191
192
193
194
    ADD, DEL, BACK, CUT, CUT_EOF, REPLACE,
#ifndef DISABLE_WRAPPING
    SPLIT_BEGIN, SPLIT_END,
#endif
195
    JOIN, PASTE, INSERT, ENTER, OTHER
196
197
} undo_type;

198
/* Structure types. */
199
200
201
202
203
204
205
206
typedef struct color_pair {
    int pairnum;
	/* The color pair number used for this foreground color and
	 * background color. */
    bool bright;
	/* Is this color A_BOLD? */
} color_pair;

207
#ifndef DISABLE_COLOR
208
typedef struct colortype {
209
    short fg;
210
	/* This syntax's foreground color. */
211
    short bg;
212
213
214
215
216
217
	/* This syntax's background color. */
    bool bright;
	/* Is this color A_BOLD? */
    int pairnum;
	/* The color pair number used for this foreground color and
	 * background color. */
218
219
    int rex_flags;
	/* The regex compilation flags (with or without REG_ICASE). */
220
221
222
223
224
225
226
227
    char *start_regex;
	/* The start (or all) of the regex string. */
    regex_t *start;
	/* The compiled start (or all) of the regex string. */
    char *end_regex;
	/* The end (if any) of the regex string. */
    regex_t *end;
	/* The compiled end (if any) of the regex string. */
228
    struct colortype *next;
229
	/* Next set of colors. */
230
    int id;
Benno Schulenberg's avatar
Benno Schulenberg committed
231
	/* Basic id for assigning to lines later. */
232
233
} colortype;

234
typedef struct regexlisttype {
235
236
    char *full_regex;
	/* A regex string to match things that imply a certain syntax. */
237
    struct regexlisttype *next;
238
	/* The next regex. */
239
} regexlisttype;
240
241

typedef struct syntaxtype {
242
    char *name;
243
	/* The name of this syntax. */
244
    regexlisttype *extensions;
245
	/* The list of extensions that this syntax applies to. */
246
    regexlisttype *headers;
247
	/* The list of headerlines that this syntax applies to. */
248
    regexlisttype *magics;
249
	/* The list of libmagic results that this syntax applies to. */
250
    char *linter;
251
	/* The command with which to lint this type of file. */
252
    char *formatter;
253
254
255
        /* The formatting command (for programming languages mainly). */
    colortype *color;
	/* The colors and their regexes used in this syntax. */
256
    int nmultis;
257
	/* How many multiline regex strings this syntax has. */
258
    struct syntaxtype *next;
259
	/* Next syntax. */
260
} syntaxtype;
261

262
263
264
265
266
267
typedef struct lintstruct {
    ssize_t lineno;
	/* Line number of the error. */
    ssize_t colno;
	/* Column # of the error. */
    char *msg;
Benno Schulenberg's avatar
Benno Schulenberg committed
268
	/* Error message text. */
269
    char *filename;
Benno Schulenberg's avatar
Benno Schulenberg committed
270
	/* Filename. */
271
272
273
    struct lintstruct *next;
	/* Next error. */
    struct lintstruct *prev;
Benno Schulenberg's avatar
Benno Schulenberg committed
274
	/* Previous error. */
275
276
} lintstruct;

277
/* Flags that indicate how a multiline regex applies to a line. */
278
#define CNONE		(1<<1)
279
	/* Yay, regex doesn't apply to this line at all! */
280
#define CBEGINBEFORE	(1<<2)
Benno Schulenberg's avatar
Benno Schulenberg committed
281
	/* Regex starts on an earlier line, ends on this one. */
282
#define CENDAFTER	(1<<3)
Benno Schulenberg's avatar
Benno Schulenberg committed
283
	/* Regex starts on this line and ends on a later one. */
284
#define CWHOLELINE	(1<<4)
Benno Schulenberg's avatar
Benno Schulenberg committed
285
	/* Whole line engulfed by the regex, start < me, end > me. */
286
#define CSTARTENDHERE	(1<<5)
Benno Schulenberg's avatar
Benno Schulenberg committed
287
	/* Regex starts and ends within this line. */
288
#endif /* !DISABLE_COLOR */
289

290
/* More structure types. */
291
292
293
294
295
296
297
298
299
typedef struct filestruct {
    char *data;
	/* The text of this line. */
    ssize_t lineno;
	/* The number of this line. */
    struct filestruct *next;
	/* Next node. */
    struct filestruct *prev;
	/* Previous node. */
300
#ifndef DISABLE_COLOR
Benno Schulenberg's avatar
Benno Schulenberg committed
301
302
    short *multidata;
	/* Array of which multi-line regexes apply to this line. */
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#endif
} filestruct;

typedef struct partition {
    filestruct *fileage;
	/* The top line of this portion of the file. */
    filestruct *top_prev;
	/* The line before the top line of this portion of the file. */
    char *top_data;
	/* The text before the beginning of the top line of this portion
	 * of the file. */
    filestruct *filebot;
	/* The bottom line of this portion of the file. */
    filestruct *bot_next;
	/* The line after the bottom line of this portion of the
	 * file. */
    char *bot_data;
	/* The text after the end of the bottom line of this portion of
	 * the file. */
} partition;

324
325
#ifndef NANO_TINY
typedef struct undo {
326
    ssize_t lineno;
327
    undo_type type;
Benno Schulenberg's avatar
Benno Schulenberg committed
328
	/* What type of undo this was. */
329
    size_t begin;
Benno Schulenberg's avatar
Benno Schulenberg committed
330
	/* Where did this action begin or end. */
331
    char *strdata;
Benno Schulenberg's avatar
Benno Schulenberg committed
332
	/* String type data we will use for copying the affected line back. */
333
334
335
336
    size_t wassize;
	/* The file size before the action. */
    size_t newsize;
	/* The file size after the action. */
337
    int xflags;
Benno Schulenberg's avatar
Benno Schulenberg committed
338
	/* Some flag data we need. */
339

Benno Schulenberg's avatar
Benno Schulenberg committed
340
    /* Cut-specific stuff we need. */
341
    filestruct *cutbuffer;
Benno Schulenberg's avatar
Benno Schulenberg committed
342
	/* Copy of the cutbuffer. */
343
    filestruct *cutbottom;
Benno Schulenberg's avatar
Benno Schulenberg committed
344
	/* Copy of cutbottom. */
345
    bool mark_set;
Benno Schulenberg's avatar
Benno Schulenberg committed
346
	/* Was the marker set when we cut? */
347
348
    ssize_t mark_begin_lineno;
	/* copy copy copy */
349
    size_t mark_begin_x;
Benno Schulenberg's avatar
Benno Schulenberg committed
350
	/* Another shadow variable. */
351
    struct undo *next;
352
} undo;
353
#endif /* !NANO_TINY */
354

355
#ifndef DISABLE_HISTORIES
356
357
typedef struct poshiststruct {
    char *filename;
358
	/* The file. */
359
    ssize_t lineno;
Benno Schulenberg's avatar
Benno Schulenberg committed
360
	/* Line number we left off on. */
361
    ssize_t xno;
Benno Schulenberg's avatar
Benno Schulenberg committed
362
	/* x position in the file we left off on. */
363
364
    struct poshiststruct *next;
} poshiststruct;
365
#endif
366

367
typedef struct openfilestruct {
368
    char *filename;
369
	/* The file's name. */
370
    filestruct *fileage;
371
	/* The file's first line. */
372
    filestruct *filebot;
373
	/* The file's last line. */
374
    filestruct *edittop;
375
	/* The current top of the edit window for this file. */
376
    filestruct *current;
377
	/* The current line for this file. */
378
    size_t totsize;
379
	/* The file's total number of characters. */
380
    size_t current_x;
381
	/* The file's x-coordinate position. */
382
    size_t placewewant;
383
	/* The file's x position we would like. */
384
    ssize_t current_y;
385
	/* The file's y-coordinate position. */
386
    bool modified;
387
	/* Whether the file has been modified. */
388
#ifndef NANO_TINY
389
    bool mark_set;
390
	/* Whether the mark is on in this file. */
391
    filestruct *mark_begin;
392
	/* The file's line where the mark is, if any. */
393
    size_t mark_begin_x;
394
	/* The file's mark's x-coordinate position, if any. */
395
    file_format fmt;
396
	/* The file's format. */
397
    struct stat *current_stat;
398
	/* The file's current stat information. */
399
    undo *undotop;
400
	/* The top of the undo list. */
401
    undo *current_undo;
Benno Schulenberg's avatar
Benno Schulenberg committed
402
	/* The current (i.e. next) level of undo. */
403
    undo_type last_action;
404
	/* The type of the last action the user performed. */
405
    char *lock_filename;
406
	/* The path of the lockfile, if we created one. */
407
#endif
408
#ifndef DISABLE_COLOR
409
    syntaxtype *syntax;
Benno Schulenberg's avatar
Benno Schulenberg committed
410
	/* The  syntax struct for this file, if any. */
411
    colortype *colorstrings;
412
	/* The file's associated colors. */
413
#endif
414
    struct openfilestruct *next;
415
	/* The next open file, if any. */
416
    struct openfilestruct *prev;
417
	/* The preceding open file, if any. */
418
} openfilestruct;
419

420
#ifndef DISABLE_NANORC
421
typedef struct rcoption {
422
   const char *name;
423
	/* The name of the rcfile option. */
424
   long flag;
425
	/* The flag associated with it, if any. */
426
} rcoption;
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
427
#endif
428

429
430
typedef struct sc {
    char *keystr;
Benno Schulenberg's avatar
Benno Schulenberg committed
431
	/* The shortcut key for a function, ASCII version. */
432
433
    key_type type;
	/* What kind of command key it is, for convenience later. */
434
    int seq;
435
	/* The actual sequence to check once the type is determined. */
436
437
    int menus;
	/* Which menus this applies to. */
438
    void (*scfunc)(void);
439
	/* The function we're going to run. */
440
    int toggle;
441
	/* If a toggle, what we're toggling. */
442
443
444
    int ordinal;
	/* The how-manieth toggle this is, in order to be able to
	 * keep them in sequence. */
445
    struct sc *next;
446
	/* Next in the list. */
447
448
449
} sc;

typedef struct subnfunc {
450
    void (*scfunc)(void);
451
	/* The actual function to call. */
452
    int menus;
Benno Schulenberg's avatar
Benno Schulenberg committed
453
	/* In what menus this function applies. */
454
    const char *desc;
455
	/* The function's short description, for example "Where Is". */
456
457
#ifndef DISABLE_HELP
    const char *help;
458
	/* The help-screen text for this function. */
459
    bool blank_after;
460
461
	/* Whether there should be a blank line after the help text
	 * for this function. */
462
463
#endif
    bool viewok;
464
	/* Is this function allowed when in view mode? */
465
    long toggle;
466
	/* If this is a toggle, which toggle to affect. */
467
    struct subnfunc *next;
Benno Schulenberg's avatar
Benno Schulenberg committed
468
	/* Next item in the list. */
469
470
} subnfunc;

471
472
473
474
475
476
477
478
479
/* The elements of the interface that can be colored differently. */
enum
{
    TITLE_BAR = 0,
    STATUS_BAR,
    KEY_COMBO,
    FUNCTION_TAG,
    NUMBER_OF_ELEMENTS
};
480

481
/* Enumeration used in the flags array.  See the definition of FLAGMASK. */
482
483
enum
{
484
    DONTUSE,
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
    CASE_SENSITIVE,
    CONST_UPDATE,
    NO_HELP,
    SUSPEND,
    NO_WRAP,
    AUTOINDENT,
    VIEW_MODE,
    USE_MOUSE,
    USE_REGEXP,
    TEMP_FILE,
    CUT_TO_END,
    BACKWARDS_SEARCH,
    MULTIBUFFER,
    SMOOTH_SCROLL,
    REBIND_DELETE,
    REBIND_KEYPAD,
    NO_CONVERT,
    BACKUP_FILE,
503
    INSECURE_BACKUP,
504
505
506
507
508
509
510
511
512
513
514
515
516
    NO_COLOR_SYNTAX,
    PRESERVE,
    HISTORYLOG,
    RESTRICTED,
    SMART_HOME,
    WHITESPACE_DISPLAY,
    MORE_SPACE,
    TABS_TO_SPACES,
    QUICK_BLANK,
    WORD_BOUNDS,
    NO_NEWLINES,
    BOLD_TEXT,
    QUIET,
517
    SOFTWRAP,
518
    POS_HISTORY,
519
    LOCKING,
520
    NOREAD_MODE,
521
    MAKE_IT_UNIX,
522
    JUSTIFY_TRIM
523
};
Chris Allegretta's avatar
Chris Allegretta committed
524

Benno Schulenberg's avatar
Benno Schulenberg committed
525
/* Flags for the menus in which a given function should be present. */
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
#define MMAIN			(1<<0)
#define MWHEREIS		(1<<1)
#define MREPLACE		(1<<2)
#define MREPLACEWITH		(1<<3)
#define MGOTOLINE		(1<<4)
#define MWRITEFILE		(1<<5)
#define MINSERTFILE		(1<<6)
#define MEXTCMD			(1<<7)
#define MHELP			(1<<8)
#define MSPELL			(1<<9)
#define MBROWSER		(1<<10)
#define MWHEREISFILE		(1<<11)
#define MGOTODIR		(1<<12)
#define MYESNO			(1<<13)
#define MLINTER			(1<<14)
541
/* This is an abbreviation for all menus except Help and YesNo. */
542
543
#define MMOST  (MMAIN|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE|MWRITEFILE|MINSERTFILE|\
		MEXTCMD|MBROWSER|MWHEREISFILE|MGOTODIR|MSPELL|MLINTER)
544

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
545
/* Control key sequences.  Changing these would be very, very bad. */
Chris Allegretta's avatar
Chris Allegretta committed
546
#define NANO_CONTROL_SPACE 0
Chris Allegretta's avatar
Chris Allegretta committed
547
#define NANO_CONTROL_I 9
548
#define NANO_CONTROL_3 27
Chris Allegretta's avatar
Chris Allegretta committed
549
#define NANO_CONTROL_7 31
550
#define NANO_CONTROL_8 127
Chris Allegretta's avatar
Chris Allegretta committed
551

552
553
554
/* Codes for "modified" Arrow keys, beyond KEY_MAX of ncurses. */
#define CONTROL_LEFT 0x401
#define CONTROL_RIGHT 0x402
555

556
#ifndef NANO_TINY
557
558
559
/* An imaginary key for when we get a SIGWINCH (window resize). */
#define KEY_WINCH -2

560
561
562
563
/* Some extra flags for the undo function. */
#define WAS_FINAL_BACKSPACE	(1<<1)
#define WAS_MARKED_FORWARD	(1<<2)
#define WAS_WHOLE_LINE		(1<<3)
564
565
#endif /* !NANO_TINY */

566
/* The maximum number of entries displayed in the main shortcut list. */
567
#define MAIN_VISIBLE (((COLS + 40) / 20) * 2)
568

569
/* The minimum editor window columns and rows required for nano to work
570
 * correctly.  Don't make these smaller than 4 and 1. */
571
#define MIN_EDITOR_COLS 4
572
#define MIN_EDITOR_ROWS 1
573

574
575
/* The default number of characters from the end of the line where
 * wrapping occurs. */
576
577
#define CHARS_FROM_EOL 8

578
/* The default width of a tab in spaces. */
579
580
#define WIDTH_OF_TAB 8

581
582
/* The maximum number of search/replace history strings saved, not
 * counting the blank lines at their ends. */
583
#define MAX_SEARCH_HISTORY 100
Chris Allegretta's avatar
Chris Allegretta committed
584

585
/* The maximum number of bytes buffered at one time. */
586
587
#define MAX_BUF_SIZE 128

588
589
590
591
592
593
#ifdef REVISION
#define BRANDING PACKAGE_VERSION"-git  "REVISION
#else
#define BRANDING PACKAGE_STRING
#endif

Chris Allegretta's avatar
Chris Allegretta committed
594
#endif /* !NANO_H */