Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 1 | /* $Id$ */ |
| 2 | /************************************************************************** |
Chris Allegretta | a943480 | 2001-05-05 15:02:27 +0000 | [diff] [blame] | 3 | * rcfile.c * |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 4 | * * |
Chris Allegretta | d757e25 | 2003-01-15 19:33:27 +0000 | [diff] [blame] | 5 | * Copyright (C) 1999-2003 Chris Allegretta * |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 6 | * This program is free software; you can redistribute it and/or modify * |
| 7 | * it under the terms of the GNU General Public License as published by * |
Chris Allegretta | 3a24f3f | 2001-10-24 11:33:54 +0000 | [diff] [blame] | 8 | * the Free Software Foundation; either version 2, or (at your option) * |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 9 | * any later version. * |
| 10 | * * |
| 11 | * This program is distributed in the hope that it will be useful, * |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
| 14 | * GNU General Public License for more details. * |
| 15 | * * |
| 16 | * You should have received a copy of the GNU General Public License * |
| 17 | * along with this program; if not, write to the Free Software * |
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * |
| 19 | * * |
| 20 | **************************************************************************/ |
| 21 | |
David Lawrence Ramsey | e21adfa | 2002-09-13 18:14:04 +0000 | [diff] [blame] | 22 | #include "config.h" |
| 23 | |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 24 | #include <stdlib.h> |
Chris Allegretta | 34f8098 | 2002-01-22 20:09:20 +0000 | [diff] [blame] | 25 | #include <stdarg.h> |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 26 | #include <string.h> |
| 27 | #include <stdio.h> |
| 28 | #include <errno.h> |
Chris Allegretta | 4dc03d5 | 2002-05-11 03:04:44 +0000 | [diff] [blame] | 29 | #include <unistd.h> |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 30 | #include <sys/types.h> |
| 31 | #include <sys/stat.h> |
| 32 | #include <fcntl.h> |
Chris Allegretta | 7662c86 | 2003-01-13 01:35:15 +0000 | [diff] [blame] | 33 | #include <pwd.h> |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 34 | #include <assert.h> |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 35 | #include "proto.h" |
| 36 | #include "nano.h" |
| 37 | |
| 38 | #ifdef ENABLE_NANORC |
| 39 | |
David Lawrence Ramsey | e21adfa | 2002-09-13 18:14:04 +0000 | [diff] [blame] | 40 | const static rcoption rcopts[] = { |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 41 | #ifndef NANO_SMALL |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 42 | {"autoindent", AUTOINDENT}, |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 43 | {"backup", BACKUP_FILE}, |
| 44 | #endif |
| 45 | {"const", CONSTUPDATE}, |
| 46 | #ifndef NANO_SMALL |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 47 | {"cut", CUT_TO_END}, |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 48 | #endif |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 49 | #ifndef DISABLE_WRAPJUSTIFY |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 50 | {"fill", 0}, |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 51 | #endif |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 52 | {"keypad", ALT_KEYPAD}, |
David Lawrence Ramsey | 9b13ff3 | 2002-12-22 16:30:00 +0000 | [diff] [blame] | 53 | #if !defined(DISABLE_MOUSE) && defined(NCURSES_MOUSE_VERSION) |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 54 | {"mouse", USE_MOUSE}, |
| 55 | #endif |
| 56 | #ifdef ENABLE_MULTIBUFFER |
| 57 | {"multibuffer", MULTIBUFFER}, |
| 58 | #endif |
| 59 | #ifndef NANO_SMALL |
| 60 | {"noconvert", NO_CONVERT}, |
| 61 | #endif |
David Lawrence Ramsey | 9b13ff3 | 2002-12-22 16:30:00 +0000 | [diff] [blame] | 62 | {"nofollow", NOFOLLOW_SYMLINKS}, |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 63 | {"nohelp", NO_HELP}, |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 64 | #ifndef DISABLE_WRAPPING |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 65 | {"nowrap", NO_WRAP}, |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 66 | #endif |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 67 | #ifndef DISABLE_OPERATINGDIR |
| 68 | {"operatingdir", 0}, |
| 69 | #endif |
Chris Allegretta | 7662c86 | 2003-01-13 01:35:15 +0000 | [diff] [blame] | 70 | {"preserve", PRESERVE}, |
David Lawrence Ramsey | 9b13ff3 | 2002-12-22 16:30:00 +0000 | [diff] [blame] | 71 | #ifndef DISABLE_JUSTIFY |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 72 | {"quotestr", 0}, |
| 73 | #endif |
| 74 | #ifdef HAVE_REGEX_H |
| 75 | {"regexp", USE_REGEXP}, |
| 76 | #endif |
| 77 | #ifndef NANO_SMALL |
| 78 | {"smooth", SMOOTHSCROLL}, |
| 79 | #endif |
| 80 | #ifndef DISABLE_SPELLER |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 81 | {"speller", 0}, |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 82 | #endif |
| 83 | {"suspend", SUSPEND}, |
| 84 | {"tabsize", 0}, |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 85 | {"tempfile", TEMP_OPT}, |
| 86 | {"view", VIEW_MODE}, |
Chris Allegretta | f3de8b5 | 2003-01-16 23:44:46 +0000 | [diff] [blame] | 87 | {"historylog", HISTORYLOG}, |
David Lawrence Ramsey | e21adfa | 2002-09-13 18:14:04 +0000 | [diff] [blame] | 88 | {NULL, 0} |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 89 | }; |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 90 | |
Chris Allegretta | f478f83 | 2002-01-18 21:54:35 +0000 | [diff] [blame] | 91 | static int errors = 0; |
| 92 | static int lineno = 0; |
| 93 | static char *nanorc; |
| 94 | |
Chris Allegretta | 88520c9 | 2001-05-05 17:45:54 +0000 | [diff] [blame] | 95 | /* We have an error in some part of the rcfile; put it on stderr and |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 96 | make the user hit return to continue starting up nano. */ |
David Lawrence Ramsey | 0341b58 | 2002-08-21 16:10:37 +0000 | [diff] [blame] | 97 | void rcfile_error(const char *msg, ...) |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 98 | { |
| 99 | va_list ap; |
| 100 | |
| 101 | fprintf(stderr, "\n"); |
Chris Allegretta | 78f0fc6 | 2002-03-29 19:41:57 +0000 | [diff] [blame] | 102 | if (lineno > 0) |
| 103 | fprintf(stderr, _("Error in %s on line %d: "), nanorc, lineno); |
| 104 | |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 105 | va_start(ap, msg); |
| 106 | vfprintf(stderr, msg, ap); |
| 107 | va_end(ap); |
| 108 | fprintf(stderr, _("\nPress return to continue starting nano\n")); |
| 109 | |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 110 | while (getchar() != '\n'); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 111 | } |
| 112 | |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 113 | /* Just print the error (one of many, perhaps) but don't abort, yet. */ |
David Lawrence Ramsey | 0341b58 | 2002-08-21 16:10:37 +0000 | [diff] [blame] | 114 | void rcfile_msg(const char *msg, ...) |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 115 | { |
| 116 | va_list ap; |
| 117 | |
Chris Allegretta | f478f83 | 2002-01-18 21:54:35 +0000 | [diff] [blame] | 118 | if (!errors) { |
| 119 | errors = 1; |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 120 | fprintf(stderr, "\n"); |
| 121 | } |
| 122 | va_start(ap, msg); |
| 123 | vfprintf(stderr, msg, ap); |
| 124 | va_end(ap); |
| 125 | fprintf(stderr, "\n"); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 126 | } |
| 127 | |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 128 | /* Parse the next word from the string. Returns NULL if we hit EOL. */ |
David Lawrence Ramsey | 0341b58 | 2002-08-21 16:10:37 +0000 | [diff] [blame] | 129 | char *parse_next_word(char *ptr) |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 130 | { |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 131 | while (*ptr != ' ' && *ptr != '\t' && *ptr != '\n' && *ptr != '\0') |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 132 | ptr++; |
| 133 | |
Chris Allegretta | 13fd44b | 2002-01-02 13:59:11 +0000 | [diff] [blame] | 134 | if (*ptr == '\0') |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 135 | return NULL; |
Chris Allegretta | f478f83 | 2002-01-18 21:54:35 +0000 | [diff] [blame] | 136 | |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 137 | /* Null terminate and advance ptr */ |
| 138 | *ptr++ = 0; |
| 139 | |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 140 | while (*ptr == ' ' || *ptr == '\t') |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 141 | ptr++; |
| 142 | |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 143 | return ptr; |
| 144 | } |
| 145 | |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 146 | /* The keywords operatingdir, fill, tabsize, speller, and quotestr take |
| 147 | * an argument when set. Among these, operatingdir, speller, and |
| 148 | * quotestr have to allow tabs and spaces in the argument. Thus, if the |
| 149 | * next word starts with a ", we say it ends with the last " of the line. |
| 150 | * Otherwise, the word is interpreted as usual. That is so the arguments |
| 151 | * can contain "s too. */ |
David Lawrence Ramsey | 0341b58 | 2002-08-21 16:10:37 +0000 | [diff] [blame] | 152 | char *parse_argument(char *ptr) |
| 153 | { |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 154 | const char *ptr_bak = ptr; |
| 155 | char *last_quote = NULL; |
| 156 | |
| 157 | assert(ptr != NULL); |
| 158 | |
| 159 | if (*ptr != '"') |
| 160 | return parse_next_word(ptr); |
| 161 | |
| 162 | do { |
| 163 | ptr++; |
| 164 | if (*ptr == '"') |
| 165 | last_quote = ptr; |
| 166 | } while (*ptr != '\n' && *ptr != '\0'); |
| 167 | |
| 168 | if (last_quote == NULL) { |
| 169 | if (*ptr == '\0') |
| 170 | ptr = NULL; |
| 171 | else |
| 172 | *ptr++ = '\0'; |
| 173 | rcfile_error(_("argument %s has unterminated \""), ptr_bak); |
| 174 | } else { |
| 175 | *last_quote = '\0'; |
| 176 | ptr = last_quote + 1; |
| 177 | } |
| 178 | if (ptr != NULL) |
| 179 | while (*ptr == ' ' || *ptr == '\t') |
| 180 | ptr++; |
| 181 | return ptr; |
| 182 | } |
| 183 | |
| 184 | #ifdef ENABLE_COLOR |
| 185 | |
David Lawrence Ramsey | 0341b58 | 2002-08-21 16:10:37 +0000 | [diff] [blame] | 186 | int colortoint(const char *colorname, int *bright) |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 187 | { |
| 188 | int mcolor = 0; |
| 189 | |
| 190 | if (colorname == NULL) |
| 191 | return -1; |
| 192 | |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 193 | if (!strncasecmp(colorname, "bright", 6)) { |
Chris Allegretta | 2fa11b8 | 2001-12-02 04:55:44 +0000 | [diff] [blame] | 194 | *bright = 1; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 195 | colorname += 6; |
| 196 | } |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 197 | |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 198 | if (!strcasecmp(colorname, "green")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 199 | mcolor = COLOR_GREEN; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 200 | else if (!strcasecmp(colorname, "red")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 201 | mcolor = COLOR_RED; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 202 | else if (!strcasecmp(colorname, "blue")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 203 | mcolor = COLOR_BLUE; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 204 | else if (!strcasecmp(colorname, "white")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 205 | mcolor = COLOR_WHITE; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 206 | else if (!strcasecmp(colorname, "yellow")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 207 | mcolor = COLOR_YELLOW; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 208 | else if (!strcasecmp(colorname, "cyan")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 209 | mcolor = COLOR_CYAN; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 210 | else if (!strcasecmp(colorname, "magenta")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 211 | mcolor = COLOR_MAGENTA; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 212 | else if (!strcasecmp(colorname, "black")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 213 | mcolor = COLOR_BLACK; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 214 | else { |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 215 | rcfile_error(_("color %s not understood.\n" |
| 216 | "Valid colors are \"green\", \"red\", \"blue\", \n" |
| 217 | "\"white\", \"yellow\", \"cyan\", \"magenta\" and \n" |
Chris Allegretta | d6e8436 | 2003-02-07 00:02:00 +0000 | [diff] [blame] | 218 | "\"black\", with the optional prefix \"bright\".\n"), |
| 219 | colorname); |
| 220 | mcolor = -1; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 221 | } |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 222 | return mcolor; |
| 223 | } |
| 224 | |
David Lawrence Ramsey | ad40fdb | 2002-09-06 20:35:28 +0000 | [diff] [blame] | 225 | char *parse_next_regex(char *ptr) |
| 226 | { |
| 227 | while ((*ptr != '"' || (*(ptr + 1) != ' ' && *(ptr + 1) != '\n')) |
| 228 | && *ptr != '\n' && *ptr != '\0') |
| 229 | ptr++; |
| 230 | |
| 231 | if (*ptr == '\0') |
| 232 | return NULL; |
| 233 | |
| 234 | /* Null terminate and advance ptr */ |
| 235 | *ptr++ = '\0'; |
| 236 | |
| 237 | while (*ptr == ' ' || *ptr == '\t') |
| 238 | ptr++; |
| 239 | |
| 240 | return ptr; |
| 241 | } |
| 242 | |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 243 | /* Compile the regular expression regex to preg. Returns FALSE on success, |
| 244 | TRUE if the expression is invalid. */ |
| 245 | int nregcomp(regex_t *preg, const char *regex, int flags) |
| 246 | { |
| 247 | int rc = regcomp(preg, regex, REG_EXTENDED | flags); |
| 248 | |
| 249 | if (rc != 0) { |
| 250 | size_t len = regerror(rc, preg, NULL, 0); |
| 251 | char *str = charalloc(len); |
| 252 | |
| 253 | regerror(rc, preg, str, len); |
| 254 | rcfile_error(_("Bad regex \"%s\": %s"), regex, str); |
| 255 | free(str); |
| 256 | } |
| 257 | return rc != 0; |
| 258 | } |
| 259 | |
David Lawrence Ramsey | 0341b58 | 2002-08-21 16:10:37 +0000 | [diff] [blame] | 260 | void parse_syntax(char *ptr) |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 261 | { |
| 262 | syntaxtype *tmpsyntax = NULL; |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 263 | const char *fileregptr = NULL, *nameptr = NULL; |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 264 | exttype *endext = NULL; |
| 265 | /* The end of the extensions list for this syntax. */ |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 266 | |
| 267 | while (*ptr == ' ') |
| 268 | ptr++; |
| 269 | |
| 270 | if (*ptr == '\n' || *ptr == '\0') |
| 271 | return; |
| 272 | |
| 273 | if (*ptr != '"') { |
| 274 | rcfile_error(_("regex strings must begin and end with a \" character\n")); |
Chris Allegretta | 09900ff | 2002-05-04 04:23:30 +0000 | [diff] [blame] | 275 | return; |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 276 | } |
| 277 | ptr++; |
| 278 | |
| 279 | nameptr = ptr; |
| 280 | ptr = parse_next_regex(ptr); |
| 281 | |
| 282 | if (ptr == NULL) { |
| 283 | rcfile_error(_("Missing syntax name")); |
Chris Allegretta | 09900ff | 2002-05-04 04:23:30 +0000 | [diff] [blame] | 284 | return; |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 285 | } |
| 286 | |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 287 | if (syntaxes == NULL) { |
| 288 | syntaxes = (syntaxtype *)nmalloc(sizeof(syntaxtype)); |
| 289 | tmpsyntax = syntaxes; |
Chris Allegretta | 1dd0bc9 | 2002-10-13 18:43:45 +0000 | [diff] [blame] | 290 | SET(COLOR_SYNTAX); |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 291 | } else { |
| 292 | for (tmpsyntax = syntaxes; tmpsyntax->next != NULL; |
| 293 | tmpsyntax = tmpsyntax->next) |
| 294 | ; |
| 295 | tmpsyntax->next = (syntaxtype *)nmalloc(sizeof(syntaxtype)); |
| 296 | tmpsyntax = tmpsyntax->next; |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 297 | #ifdef DEBUG |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 298 | fprintf(stderr, _("Adding new syntax after 1st\n")); |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 299 | #endif |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 300 | } |
| 301 | tmpsyntax->desc = mallocstrcpy(NULL, nameptr); |
| 302 | tmpsyntax->color = NULL; |
| 303 | tmpsyntax->extensions = NULL; |
| 304 | tmpsyntax->next = NULL; |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 305 | #ifdef DEBUG |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 306 | fprintf(stderr, _("Starting a new syntax type\n")); |
| 307 | fprintf(stderr, "string val=%s\n", nameptr); |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 308 | #endif |
| 309 | |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 310 | /* Now load in the extensions to their part of the struct */ |
| 311 | while (*ptr != '\n' && *ptr != '\0') { |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 312 | exttype *newext; |
| 313 | /* The new extension structure. */ |
| 314 | |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 315 | while (*ptr != '"' && *ptr != '\n' && *ptr != '\0') |
| 316 | ptr++; |
| 317 | |
| 318 | if (*ptr == '\n' || *ptr == '\0') |
| 319 | return; |
| 320 | ptr++; |
| 321 | |
| 322 | fileregptr = ptr; |
| 323 | ptr = parse_next_regex(ptr); |
| 324 | |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 325 | newext = (exttype *)nmalloc(sizeof(exttype)); |
| 326 | if (nregcomp(&newext->val, fileregptr, REG_NOSUB)) |
| 327 | free(newext); |
| 328 | else { |
| 329 | if (endext == NULL) |
| 330 | tmpsyntax->extensions = newext; |
| 331 | else |
| 332 | endext->next = newext; |
| 333 | endext = newext; |
| 334 | endext->next = NULL; |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 335 | } |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 336 | } |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 337 | } |
| 338 | |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 339 | /* Parse the color stuff into the colorstrings array */ |
David Lawrence Ramsey | 0341b58 | 2002-08-21 16:10:37 +0000 | [diff] [blame] | 340 | void parse_colors(char *ptr) |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 341 | { |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 342 | int fg, bg, bright = 0; |
| 343 | int expectend = 0; /* Do we expect an end= line? */ |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 344 | char *fgstr; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 345 | colortype *tmpcolor = NULL; |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 346 | syntaxtype *tmpsyntax = NULL; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 347 | |
| 348 | fgstr = ptr; |
| 349 | ptr = parse_next_word(ptr); |
| 350 | |
| 351 | if (ptr == NULL) { |
Chris Allegretta | f478f83 | 2002-01-18 21:54:35 +0000 | [diff] [blame] | 352 | rcfile_error(_("Missing color name")); |
Chris Allegretta | 09900ff | 2002-05-04 04:23:30 +0000 | [diff] [blame] | 353 | return; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 354 | } |
| 355 | |
| 356 | if (strstr(fgstr, ",")) { |
| 357 | strtok(fgstr, ","); |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 358 | bg = colortoint(strtok(NULL, ","), &bright); |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 359 | } else |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 360 | bg = -1; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 361 | |
Chris Allegretta | f478f83 | 2002-01-18 21:54:35 +0000 | [diff] [blame] | 362 | fg = colortoint(fgstr, &bright); |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 363 | |
Chris Allegretta | 17ec14b | 2003-02-07 00:19:05 +0000 | [diff] [blame] | 364 | /* Don't try and parse screwed up fg colors */ |
| 365 | if (fg == -1) |
| 366 | return; |
| 367 | |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 368 | if (syntaxes == NULL) { |
| 369 | rcfile_error(_("Cannot add a color directive without a syntax line")); |
Chris Allegretta | 09900ff | 2002-05-04 04:23:30 +0000 | [diff] [blame] | 370 | return; |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 371 | } |
| 372 | |
| 373 | for (tmpsyntax = syntaxes; tmpsyntax->next != NULL; |
| 374 | tmpsyntax = tmpsyntax->next) |
| 375 | ; |
| 376 | |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 377 | /* Now the fun part, start adding regexps to individual strings |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 378 | in the colorstrings array, woo! */ |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 379 | |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 380 | while (*ptr != '\0') { |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 381 | colortype *newcolor; |
| 382 | /* The new color structure. */ |
| 383 | int cancelled = 0; |
| 384 | /* The start expression was bad. */ |
| 385 | |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 386 | while (*ptr == ' ') |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 387 | ptr++; |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 388 | |
| 389 | if (*ptr == '\n' || *ptr == '\0') |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 390 | break; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 391 | |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 392 | if (!strncasecmp(ptr, "start=", 6)) { |
| 393 | ptr += 6; |
| 394 | expectend = 1; |
Chris Allegretta | f478f83 | 2002-01-18 21:54:35 +0000 | [diff] [blame] | 395 | } |
| 396 | |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 397 | if (*ptr != '"') { |
| 398 | rcfile_error(_("regex strings must begin and end with a \" character\n")); |
Chris Allegretta | de85262 | 2002-09-18 00:28:57 +0000 | [diff] [blame] | 399 | ptr = parse_next_regex(ptr); |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 400 | continue; |
| 401 | } |
| 402 | ptr++; |
| 403 | |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 404 | newcolor = (colortype *)nmalloc(sizeof(colortype)); |
| 405 | fgstr = ptr; |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 406 | ptr = parse_next_regex(ptr); |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 407 | if (nregcomp(&newcolor->start, fgstr, 0)) { |
| 408 | free(newcolor); |
| 409 | cancelled = 1; |
| 410 | } else { |
| 411 | newcolor->fg = fg; |
| 412 | newcolor->bg = bg; |
| 413 | newcolor->bright = bright; |
| 414 | newcolor->next = NULL; |
| 415 | newcolor->end = NULL; |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 416 | |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 417 | if (tmpsyntax->color == NULL) { |
| 418 | tmpsyntax->color = newcolor; |
| 419 | #ifdef DEBUG |
| 420 | fprintf(stderr, _("Starting a new colorstring for fg %d bg %d\n"), |
| 421 | fg, bg); |
| 422 | #endif |
| 423 | } else { |
| 424 | for (tmpcolor = tmpsyntax->color; tmpcolor->next != NULL; |
| 425 | tmpcolor = tmpcolor->next) |
| 426 | ; |
| 427 | #ifdef DEBUG |
| 428 | fprintf(stderr, _("Adding new entry for fg %d bg %d\n"), fg, bg); |
| 429 | #endif |
| 430 | tmpcolor->next = newcolor; |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | if (expectend) { |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 435 | if (ptr == NULL || strncasecmp(ptr, "end=", 4)) { |
| 436 | rcfile_error(_ |
David Lawrence Ramsey | 9b13ff3 | 2002-12-22 16:30:00 +0000 | [diff] [blame] | 437 | ("\"start=\" requires a corresponding \"end=\"")); |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 438 | return; |
| 439 | } |
| 440 | |
| 441 | ptr += 4; |
| 442 | |
| 443 | if (*ptr != '"') { |
| 444 | rcfile_error(_ |
| 445 | ("regex strings must begin and end with a \" character\n")); |
| 446 | continue; |
| 447 | } |
| 448 | ptr++; |
| 449 | |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 450 | fgstr = ptr; |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 451 | ptr = parse_next_regex(ptr); |
Chris Allegretta | ce452fb | 2003-02-03 02:56:44 +0000 | [diff] [blame] | 452 | |
| 453 | /* If the start regex was invalid, skip past the end regex to |
| 454 | * stay in sync. */ |
| 455 | if (cancelled) |
| 456 | continue; |
| 457 | newcolor->end = (regex_t *)nmalloc(sizeof(regex_t)); |
| 458 | if (nregcomp(newcolor->end, fgstr, 0)) { |
| 459 | free(newcolor->end); |
| 460 | newcolor->end = NULL; |
| 461 | } |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 462 | } |
Chris Allegretta | f478f83 | 2002-01-18 21:54:35 +0000 | [diff] [blame] | 463 | } |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 464 | } |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 465 | |
| 466 | #endif /* ENABLE_COLOR */ |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 467 | |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 468 | /* Parse the RC file, once it has been opened successfully */ |
David Lawrence Ramsey | 0341b58 | 2002-08-21 16:10:37 +0000 | [diff] [blame] | 469 | void parse_rcfile(FILE *rcstream) |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 470 | { |
| 471 | char *buf, *ptr, *keyword, *option; |
Chris Allegretta | 1596d38 | 2002-03-07 00:46:17 +0000 | [diff] [blame] | 472 | int set = 0, i, j; |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 473 | |
Chris Allegretta | 8d848af | 2001-05-18 04:44:16 +0000 | [diff] [blame] | 474 | buf = charalloc(1024); |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 475 | while (fgets(buf, 1023, rcstream) != 0) { |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 476 | lineno++; |
| 477 | ptr = buf; |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 478 | while (*ptr == ' ' || *ptr == '\t') |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 479 | ptr++; |
| 480 | |
| 481 | if (*ptr == '\n' || *ptr == '\0') |
| 482 | continue; |
| 483 | |
| 484 | if (*ptr == '#') { |
| 485 | #ifdef DEBUG |
Chris Allegretta | 0e86e60 | 2003-01-23 04:27:23 +0000 | [diff] [blame] | 486 | fprintf(stderr, _("%s: Read a comment\n"), "parse_rcfile()"); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 487 | #endif |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 488 | continue; /* Skip past commented lines */ |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 489 | } |
| 490 | |
| 491 | /* Else skip to the next space */ |
| 492 | keyword = ptr; |
| 493 | ptr = parse_next_word(ptr); |
David Lawrence Ramsey | 9b13ff3 | 2002-12-22 16:30:00 +0000 | [diff] [blame] | 494 | if (ptr == NULL) |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 495 | continue; |
| 496 | |
| 497 | /* Else try to parse the keyword */ |
| 498 | if (!strcasecmp(keyword, "set")) |
| 499 | set = 1; |
| 500 | else if (!strcasecmp(keyword, "unset")) |
| 501 | set = -1; |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 502 | #ifdef ENABLE_COLOR |
Chris Allegretta | b6c5dc2 | 2002-05-04 03:47:33 +0000 | [diff] [blame] | 503 | else if (!strcasecmp(keyword, "syntax")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 504 | parse_syntax(ptr); |
Chris Allegretta | 08893e0 | 2001-11-29 02:42:27 +0000 | [diff] [blame] | 505 | else if (!strcasecmp(keyword, "color")) |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 506 | parse_colors(ptr); |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 507 | #endif /* ENABLE_COLOR */ |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 508 | else { |
Chris Allegretta | f478f83 | 2002-01-18 21:54:35 +0000 | [diff] [blame] | 509 | rcfile_msg(_("command %s not understood"), keyword); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 510 | continue; |
| 511 | } |
| 512 | |
| 513 | option = ptr; |
| 514 | ptr = parse_next_word(ptr); |
| 515 | /* We don't care if ptr == NULL, as it should if using proper syntax */ |
| 516 | |
| 517 | if (set != 0) { |
David Lawrence Ramsey | e21adfa | 2002-09-13 18:14:04 +0000 | [diff] [blame] | 518 | for (i = 0; rcopts[i].name != NULL; i++) { |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 519 | if (!strcasecmp(option, rcopts[i].name)) { |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 520 | #ifdef DEBUG |
Chris Allegretta | 0e86e60 | 2003-01-23 04:27:23 +0000 | [diff] [blame] | 521 | fprintf(stderr, _("%s: Parsing option %s\n"), |
| 522 | "parse_rcfile()", rcopts[i].name); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 523 | #endif |
David Lawrence Ramsey | 9b13ff3 | 2002-12-22 16:30:00 +0000 | [diff] [blame] | 524 | if (set == 1) { |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 525 | if (!strcasecmp(rcopts[i].name, "tabsize") |
| 526 | #ifndef DISABLE_OPERATINGDIR |
| 527 | || !strcasecmp(rcopts[i].name, "operatingdir") |
| 528 | #endif |
Chris Allegretta | 6fe6149 | 2001-05-21 12:56:25 +0000 | [diff] [blame] | 529 | #ifndef DISABLE_WRAPJUSTIFY |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 530 | || !strcasecmp(rcopts[i].name, "fill") |
Chris Allegretta | 6fe6149 | 2001-05-21 12:56:25 +0000 | [diff] [blame] | 531 | #endif |
Chris Allegretta | d76ca2b | 2002-03-03 22:52:52 +0000 | [diff] [blame] | 532 | #ifndef DISABLE_JUSTIFY |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 533 | || !strcasecmp(rcopts[i].name, "quotestr") |
Chris Allegretta | d76ca2b | 2002-03-03 22:52:52 +0000 | [diff] [blame] | 534 | #endif |
Chris Allegretta | 6fe6149 | 2001-05-21 12:56:25 +0000 | [diff] [blame] | 535 | #ifndef DISABLE_SPELLER |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 536 | || !strcasecmp(rcopts[i].name, "speller") |
Chris Allegretta | 6fe6149 | 2001-05-21 12:56:25 +0000 | [diff] [blame] | 537 | #endif |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 538 | ) { |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 539 | if (*ptr == '\n' || *ptr == '\0') { |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 540 | rcfile_error(_ |
| 541 | ("option %s requires an argument"), |
| 542 | rcopts[i].name); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 543 | continue; |
| 544 | } |
| 545 | option = ptr; |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 546 | if (*option == '"') |
| 547 | option++; |
| 548 | ptr = parse_argument(ptr); |
| 549 | #ifdef DEBUG |
| 550 | fprintf(stderr, "option = %s\n", option); |
| 551 | #endif |
| 552 | #ifndef DISABLE_OPERATINGDIR |
| 553 | if (!strcasecmp(rcopts[i].name, "operatingdir")) |
| 554 | operating_dir = mallocstrcpy(NULL, option); |
| 555 | else |
| 556 | #endif |
Chris Allegretta | 6fe6149 | 2001-05-21 12:56:25 +0000 | [diff] [blame] | 557 | #ifndef DISABLE_WRAPJUSTIFY |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 558 | if (!strcasecmp(rcopts[i].name, "fill")) { |
| 559 | char *first_error; |
Chris Allegretta | 6fe6149 | 2001-05-21 12:56:25 +0000 | [diff] [blame] | 560 | |
Chris Allegretta | 7662c86 | 2003-01-13 01:35:15 +0000 | [diff] [blame] | 561 | /* Using strtol() instead of atoi() lets |
| 562 | * us accept 0 while checking other |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 563 | * errors. */ |
| 564 | j = (int)strtol(option, &first_error, 10); |
| 565 | if (errno == ERANGE || *option == '\0' || *first_error != '\0') |
| 566 | rcfile_error(_("requested fill size %d invalid"), |
Chris Allegretta | 1596d38 | 2002-03-07 00:46:17 +0000 | [diff] [blame] | 567 | j); |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 568 | else |
| 569 | wrap_at = j; |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 570 | } else |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 571 | #endif |
Chris Allegretta | d76ca2b | 2002-03-03 22:52:52 +0000 | [diff] [blame] | 572 | #ifndef DISABLE_JUSTIFY |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 573 | if (!strcasecmp(rcopts[i].name, "quotestr")) |
| 574 | quotestr = mallocstrcpy(NULL, option); |
| 575 | else |
Chris Allegretta | d76ca2b | 2002-03-03 22:52:52 +0000 | [diff] [blame] | 576 | #endif |
Chris Allegretta | 6fe6149 | 2001-05-21 12:56:25 +0000 | [diff] [blame] | 577 | #ifndef DISABLE_SPELLER |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 578 | if (!strcasecmp(rcopts[i].name, "speller")) |
| 579 | alt_speller = mallocstrcpy(NULL, option); |
| 580 | else |
Chris Allegretta | 6fe6149 | 2001-05-21 12:56:25 +0000 | [diff] [blame] | 581 | #endif |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 582 | { |
| 583 | char *first_error; |
| 584 | |
| 585 | /* Using strtol instead of atoi lets us |
| 586 | * accept 0 while checking other |
| 587 | * errors. */ |
| 588 | j = (int)strtol(option, &first_error, 10); |
| 589 | if (errno == ERANGE || *option == '\0' || *first_error != '\0') |
| 590 | rcfile_error(_("requested tab size %d invalid"), |
| 591 | j); |
| 592 | else |
| 593 | tabsize = j; |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 594 | } |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 595 | } else |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 596 | SET(rcopts[i].flag); |
| 597 | #ifdef DEBUG |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 598 | fprintf(stderr, _("set flag %d!\n"), |
| 599 | rcopts[i].flag); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 600 | #endif |
| 601 | } else { |
| 602 | UNSET(rcopts[i].flag); |
| 603 | #ifdef DEBUG |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 604 | fprintf(stderr, _("unset flag %d!\n"), |
| 605 | rcopts[i].flag); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 606 | #endif |
Chris Allegretta | 6c1e661 | 2002-01-19 16:52:34 +0000 | [diff] [blame] | 607 | } |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 608 | } |
| 609 | } |
| 610 | } |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 611 | } |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 612 | free(buf); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 613 | if (errors) |
| 614 | rcfile_error(_("Errors found in .nanorc file")); |
| 615 | |
| 616 | return; |
| 617 | } |
| 618 | |
| 619 | /* The main rc file function, tries to open the rc file */ |
| 620 | void do_rcfile(void) |
| 621 | { |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 622 | FILE *rcstream; |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 623 | const struct passwd *userage; |
| 624 | uid_t euid = geteuid(); |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 625 | |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 626 | #ifdef SYSCONFDIR |
| 627 | assert(sizeof(SYSCONFDIR) == strlen(SYSCONFDIR) + 1); |
| 628 | nanorc = charalloc(sizeof(SYSCONFDIR) + 7); |
Chris Allegretta | ff8a68c | 2002-02-16 20:34:57 +0000 | [diff] [blame] | 629 | sprintf(nanorc, "%s/nanorc", SYSCONFDIR); |
Chris Allegretta | ff8a68c | 2002-02-16 20:34:57 +0000 | [diff] [blame] | 630 | /* Try to open system nanorc */ |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 631 | if ((rcstream = fopen(nanorc, "r")) != NULL) { |
| 632 | /* Parse it! */ |
| 633 | parse_rcfile(rcstream); |
| 634 | fclose(rcstream); |
| 635 | } |
| 636 | #endif |
Chris Allegretta | ff8a68c | 2002-02-16 20:34:57 +0000 | [diff] [blame] | 637 | |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 638 | /* Determine home directory using getpwent(), don't rely on $HOME */ |
| 639 | do { |
| 640 | userage = getpwent(); |
| 641 | } while (userage != NULL && userage->pw_uid != euid); |
| 642 | endpwent(); |
Chris Allegretta | ff8a68c | 2002-02-16 20:34:57 +0000 | [diff] [blame] | 643 | |
Chris Allegretta | 78f0fc6 | 2002-03-29 19:41:57 +0000 | [diff] [blame] | 644 | lineno = 0; |
Chris Allegretta | 4dc03d5 | 2002-05-11 03:04:44 +0000 | [diff] [blame] | 645 | |
Chris Allegretta | 5beed50 | 2003-01-05 20:41:21 +0000 | [diff] [blame] | 646 | if (userage == NULL) { |
Chris Allegretta | 4dc03d5 | 2002-05-11 03:04:44 +0000 | [diff] [blame] | 647 | rcfile_error(_("I can't find my home directory! Wah!")); |
Chris Allegretta | 7662c86 | 2003-01-13 01:35:15 +0000 | [diff] [blame] | 648 | SET(NO_RCFILE); |
Chris Allegretta | 5beed50 | 2003-01-05 20:41:21 +0000 | [diff] [blame] | 649 | } else { |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 650 | nanorc = nrealloc(nanorc, strlen(userage->pw_dir) + 9); |
| 651 | sprintf(nanorc, "%s/.nanorc", userage->pw_dir); |
| 652 | |
David Lawrence Ramsey | dc60b72 | 2002-10-25 16:08:53 +0000 | [diff] [blame] | 653 | #if defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING) |
| 654 | /* If we've already read $SYSCONFDIR/nanorc (if it's there), we're |
| 655 | root, and --disable-wrapping-as-root is used, turn wrapping off */ |
| 656 | if (euid == 0) |
| 657 | SET(NO_WRAP); |
| 658 | #endif |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 659 | if ((rcstream = fopen(nanorc, "r")) == NULL) { |
| 660 | /* Don't complain about the file not existing */ |
Chris Allegretta | 5beed50 | 2003-01-05 20:41:21 +0000 | [diff] [blame] | 661 | if (errno != ENOENT) { |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 662 | rcfile_error(_("Unable to open ~/.nanorc file, %s"), |
| 663 | strerror(errno)); |
Chris Allegretta | 5beed50 | 2003-01-05 20:41:21 +0000 | [diff] [blame] | 664 | SET(NO_RCFILE); |
| 665 | } |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 666 | } else { |
| 667 | parse_rcfile(rcstream); |
| 668 | fclose(rcstream); |
| 669 | } |
Chris Allegretta | 4dc03d5 | 2002-05-11 03:04:44 +0000 | [diff] [blame] | 670 | } |
| 671 | |
Chris Allegretta | 6df90f5 | 2002-07-19 01:08:59 +0000 | [diff] [blame] | 672 | free(nanorc); |
David Lawrence Ramsey | 1f28b8f | 2002-09-27 14:21:59 +0000 | [diff] [blame] | 673 | #ifdef ENABLE_COLOR |
| 674 | set_colorpairs(); |
| 675 | #endif |
Chris Allegretta | 8d8e012 | 2001-04-18 04:28:54 +0000 | [diff] [blame] | 676 | } |
| 677 | |
David Lawrence Ramsey | 5db0cdc | 2002-06-28 22:45:14 +0000 | [diff] [blame] | 678 | #endif /* ENABLE_NANORC */ |