1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2002-2006 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <sys/types.h>
46 static int attributes(const char *filename
, int line
, char *str
)
51 while ((tmp
= strsep(&str
, ",")) != NULL
) {
52 if (strcasecmp(tmp
, "BOLD") == 0)
54 else if (strcasecmp(tmp
, "REVERSE") == 0)
56 else if (strcasecmp(tmp
, "NONE") == 0)
58 else if (strcasecmp(tmp
, "DIM") == 0)
60 else if (strcasecmp(tmp
, "STANDOUT") == 0)
62 else if (strcasecmp(tmp
, "UNDERLINE") == 0)
64 else if (strcasecmp(tmp
, "BLINK") == 0)
66 else if (strcasecmp(tmp
, "INVISIBLE") == 0)
69 errx(EXIT_FAILURE
, "%s(%i): invalid attribute \"%s\"", filename
,
76 static short color_name(const char *filename
, int line
, const char *color
)
78 if (strcasecmp(color
, "BLACK") == 0)
80 else if (strcasecmp(color
, "WHITE") == 0)
82 else if (strcasecmp(color
, "GREEN") == 0)
84 else if (strcasecmp(color
, "YELLOW") == 0)
86 else if (strcasecmp(color
, "MAGENTA") == 0)
88 else if (strcasecmp(color
, "BLUE") == 0)
90 else if (strcasecmp(color
, "RED") == 0)
92 else if (strcasecmp(color
, "CYAN") == 0)
95 errx(EXIT_FAILURE
, "%s(%i): invalid color \"%s\"", filename
, line
,
101 static void parse_color(const char *filename
, int line
, const char *str
,
104 char fg
[16], bg
[16], attr
[64], nattr
[64];
105 struct color_s ctmp
= *c
;
108 if ((n
= sscanf(str
, "%[a-zA-Z] %[a-zA-Z] %[a-zA-Z,] %[a-zA-Z,]", fg
, bg
,
110 errx(EXIT_FAILURE
, "%s(%i): parse error", filename
, line
);
112 ctmp
.fg
= color_name(filename
, line
, fg
);
113 ctmp
.bg
= color_name(filename
, line
, bg
);
114 ctmp
.attrs
= ctmp
.nattrs
= 0;
117 ctmp
.attrs
= attributes(filename
, line
, attr
);
120 ctmp
.nattrs
= attributes(filename
, line
, nattr
);
125 static int on_or_off(const char *filename
, int lines
, const char *str
)
127 if (strcasecmp(str
, "on") == 0 || strcasecmp(str
, "1") == 0 ||
128 strcasecmp(str
, "yes") == 0 || strcasecmp(str
, "true") == 0)
131 if (strcasecmp(str
, "off") == 0 || strcasecmp(str
, "0") == 0 ||
132 strcasecmp(str
, "no") == 0 || strcasecmp(str
, "false") == 0)
135 errx(EXIT_FAILURE
, "%s(%i): invalid value \"%s\"", filename
, lines
, str
);
138 void copydatafile(const char *dst
, const char *src
)
141 char buf
[LINE_MAX
], *s
;
143 snprintf(buf
, sizeof(buf
), "%s/%s", DATA_PATH
, src
);
145 if ((fp
= fopen(buf
, "r")) == NULL
) {
151 if ((ofp
= fopen(dst
, "w+")) == NULL
) {
157 while ((s
= fgets(buf
, sizeof(buf
), fp
)) != NULL
)
158 fprintf(ofp
, "%s", s
);
164 void set_config_defaults()
168 config
.pattern
= strdup("*.pgn");
169 config
.engine_cmd
= strdup("gnuchess --xboard");
170 config
.jumpcount
= 5;
171 config
.linegraphics
= 1;
172 config
.saveprompt
= 1;
173 config
.deleteprompt
= 1;
174 config
.validmoves
= 1;
176 set_default_colors();
178 if (stat(config
.nagfile
, &st
) == -1) {
180 copydatafile(config
.nagfile
, "nag.data");
182 warn("%s", config
.nagfile
);
185 if (stat(config
.ccfile
, &st
) == -1) {
187 copydatafile(config
.nagfile
, "cc.data");
189 warn("%s", config
.ccfile
);
193 void parse_rcfile(const char *filename
)
196 char *line
, buf
[LINE_MAX
];
198 char *altengine
= NULL
;
202 if ((fp
= fopen(filename
, "r")) == NULL
)
203 err(EXIT_FAILURE
, "%s", filename
);
205 while ((line
= fgets(buf
, sizeof(buf
), fp
)) != NULL
) {
207 char var
[30], val
[50];
208 char token
[MAX_PGN_LINE_LEN
+ 1], value
[MAX_PGN_LINE_LEN
+ 1];
214 if (!line
[0] || line
[0] == '#')
217 if ((n
= sscanf(line
, "%s %[^\n]", var
, val
)) != 2)
218 errx(EXIT_FAILURE
, "%s(%i): parse error %i", filename
, lines
,n
);
220 strncpy(val
, trim(val
), sizeof(val
));
221 strncpy(var
, trim(var
), sizeof(var
));
223 if (strcmp(var
, "jump_count") == 0) {
225 errx(EXIT_FAILURE
, "%s(%i): value is not an integer", filename
,
228 config
.jumpcount
= atoi(val
);
230 else if (strcmp(var
, "bind") == 0) {
231 config
.keys
= Realloc(config
.keys
, (k
+ 2) *
232 sizeof(struct key_s
*));
233 config
.keys
[k
] = Calloc(1, sizeof(struct key_s
));
237 while (*p
&& !isspace(*p
))
244 if (strcasecmp(p
, "none") == 0)
245 config
.keys
[k
]->type
= KEY_DEFAULT
;
246 else if (strcasecmp(p
, "repeat") == 0)
247 config
.keys
[k
]->type
= KEY_REPEAT
;
248 else if (strcasecmp(p
, "set") == 0)
249 config
.keys
[k
]->type
= KEY_SET
;
251 errx(EXIT_FAILURE
, "%s(%i): invalid value \"%s\"", filename
,
257 while (*p
&& isspace(*p
))
260 config
.keys
[k
]->c
= *p
++;
261 config
.keys
[k
++]->str
= strdup(p
);
262 config
.keys
[k
] = NULL
;
264 else if (strcmp(var
, "engine_init") == 0) {
265 config
.einit
= Realloc(config
.einit
, (init
+ 2) * sizeof(char *));
266 config
.einit
[init
++] = strdup(val
);
267 config
.einit
[init
] = NULL
;
269 else if (strcmp(var
, "pattern") == 0) {
270 free(config
.pattern
);
271 config
.pattern
= strdup(val
);
273 else if (strcmp(var
, "mpl") == 0) {
275 errx(EXIT_FAILURE
, "%s(%i): value is not an integer", filename
,
277 pgn_config_set(PGN_MPL
, (int *)atoi(val
));
279 else if (strcmp(var
, "stop_on_error") == 0)
280 pgn_config_set(PGN_STOP_ON_ERROR
, (int *)on_or_off(filename
, lines
,
282 else if (strcmp(var
, "tag") == 0) {
283 if ((n
= sscanf(val
, "%s %s ", token
, value
)) < 1 ||
285 errx(EXIT_FAILURE
, "%s(%i): invalid value \"%s\"", filename
,
291 p
= val
+ strlen(token
);
292 strncpy(value
, p
, sizeof(value
));
295 for (n
= 0; n
< strlen(token
); n
++) {
296 if (!isalnum(token
[n
]) && token
[n
] != '_')
298 "%s(%i): token names must match 0-9A-Za-z_.",
302 token
[0] = toupper(token
[0]);
303 pgn_tag_add(&config
.tag
, token
, value
);
305 else if (strcmp(var
, "save_directory") == 0)
306 config
.savedirectory
= strdup(val
);
307 else if (strcmp(var
, "line_graphics") == 0)
308 config
.linegraphics
= on_or_off(filename
, lines
, val
);
309 else if (strcmp(var
, "save_prompt") == 0)
310 config
.saveprompt
= on_or_off(filename
, lines
, val
);
311 else if (strcmp(var
, "delete_prompt") == 0)
312 config
.deleteprompt
= on_or_off(filename
, lines
, val
);
313 else if (strcmp(var
, "valid_moves") == 0)
314 config
.validmoves
= on_or_off(filename
, lines
, val
);
315 else if (strcmp(var
, "board_details") == 0)
316 config
.details
= on_or_off(filename
, lines
, val
);
317 else if (strcmp(var
, "engine_cmd") == 0)
318 altengine
= strdup(val
);
319 else if (strcmp(var
, "color_board_window") == 0)
320 parse_color(filename
, lines
, val
, &config
.color
[CONF_BDWINDOW
]);
321 else if (strcmp(var
, "color_board_selected") == 0)
322 parse_color(filename
, lines
, val
, &config
.color
[CONF_BSELECTED
]);
323 else if (strcmp(var
, "color_board_white_moves") == 0)
324 parse_color(filename
, lines
, val
, &config
.color
[CONF_BMOVESW
]);
325 else if (strcmp(var
, "color_board_black_moves") == 0)
326 parse_color(filename
, lines
, val
, &config
.color
[CONF_BMOVESB
]);
327 else if (strcmp(var
, "color_board_count") == 0)
328 parse_color(filename
, lines
, val
, &config
.color
[CONF_BCOUNT
]);
329 else if (strcmp(var
, "color_board_cursor") == 0)
330 parse_color(filename
, lines
, val
, &config
.color
[CONF_BCURSOR
]);
331 else if (strcmp(var
, "color_board_black") == 0)
332 parse_color(filename
, lines
, val
, &config
.color
[CONF_BBLACK
]);
333 else if (strcmp(var
, "color_board_white") == 0)
334 parse_color(filename
, lines
, val
, &config
.color
[CONF_BWHITE
]);
335 else if (strcmp(var
, "color_board_graphics") == 0)
336 parse_color(filename
, lines
, val
, &config
.color
[CONF_BGRAPHICS
]);
337 else if (strcmp(var
, "color_board_coords") == 0)
338 parse_color(filename
, lines
, val
, &config
.color
[CONF_BCOORDS
]);
339 else if (strcmp(var
, "color_status_window") == 0)
340 parse_color(filename
, lines
, val
, &config
.color
[CONF_SWINDOW
]);
341 else if (strcmp(var
, "color_status_title") == 0)
342 parse_color(filename
, lines
, val
, &config
.color
[CONF_STITLE
]);
343 else if (strcmp(var
, "color_status_border") == 0)
344 parse_color(filename
, lines
, val
, &config
.color
[CONF_SBORDER
]);
345 else if (strcmp(var
, "color_status_notify") == 0)
346 parse_color(filename
, lines
, val
, &config
.color
[CONF_SNOTIFY
]);
347 else if (strcmp(var
, "color_status_engine") == 0)
348 parse_color(filename
, lines
, val
, &config
.color
[CONF_SENGINE
]);
349 else if (strcmp(var
, "color_tag_window") == 0)
350 parse_color(filename
, lines
, val
, &config
.color
[CONF_TWINDOW
]);
351 else if (strcmp(var
, "color_tag_title") == 0)
352 parse_color(filename
, lines
, val
, &config
.color
[CONF_TTITLE
]);
353 else if (strcmp(var
, "color_tag_border") == 0)
354 parse_color(filename
, lines
, val
, &config
.color
[CONF_TBORDER
]);
355 else if (strcmp(var
, "color_history_window") == 0)
356 parse_color(filename
, lines
, val
, &config
.color
[CONF_HWINDOW
]);
357 else if (strcmp(var
, "color_history_title") == 0)
358 parse_color(filename
, lines
, val
, &config
.color
[CONF_HTITLE
]);
359 else if (strcmp(var
, "color_history_border") == 0)
360 parse_color(filename
, lines
, val
, &config
.color
[CONF_HBORDER
]);
361 else if (strcmp(var
, "color_message_window") == 0)
362 parse_color(filename
, lines
, val
, &config
.color
[CONF_MWINDOW
]);
363 else if (strcmp(var
, "color_message_title") == 0)
364 parse_color(filename
, lines
, val
, &config
.color
[CONF_MTITLE
]);
365 else if (strcmp(var
, "color_message_border") == 0)
366 parse_color(filename
, lines
, val
, &config
.color
[CONF_MBORDER
]);
367 else if (strcmp(var
, "color_message_prompt") == 0)
368 parse_color(filename
, lines
, val
, &config
.color
[CONF_MPROMPT
]);
369 else if (strcmp(var
, "color_input_window") == 0)
370 parse_color(filename
, lines
, val
, &config
.color
[CONF_IWINDOW
]);
371 else if (strcmp(var
, "color_input_title") == 0)
372 parse_color(filename
, lines
, val
, &config
.color
[CONF_ITITLE
]);
373 else if (strcmp(var
, "color_input_border") == 0)
374 parse_color(filename
, lines
, val
, &config
.color
[CONF_IBORDER
]);
375 else if (strcmp(var
, "color_input_prompt") == 0)
376 parse_color(filename
, lines
, val
, &config
.color
[CONF_IPROMPT
]);
377 else if (strcmp(var
, "color_menu") == 0)
378 parse_color(filename
, lines
, val
, &config
.color
[CONF_MENU
]);
379 else if (strcmp(var
, "color_menu_selected") == 0)
380 parse_color(filename
, lines
, val
, &config
.color
[CONF_MENUS
]);
381 else if (strcmp(var
, "color_menu_highlight") == 0)
382 parse_color(filename
, lines
, val
, &config
.color
[CONF_MENUH
]);
384 errx(EXIT_FAILURE
, "%s(%i): invalid parameter \"%s\"", filename
,
391 free(config
.engine_cmd
);
392 config
.engine_cmd
= NULL
;
393 config
.engine_cmd
= strdup(altengine
);