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
.ccfile
, "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 p
= strdup(trim(val
));
221 strncpy(val
, p
, sizeof(val
));
223 p
= strdup(trim(var
));
224 strncpy(var
, p
, sizeof(var
));
227 if (strcmp(var
, "jump_count") == 0) {
229 errx(EXIT_FAILURE
, "%s(%i): value is not an integer", filename
,
232 config
.jumpcount
= atoi(val
);
234 else if (strcmp(var
, "bind") == 0) {
235 config
.keys
= Realloc(config
.keys
, (k
+ 2) *
236 sizeof(struct key_s
*));
237 config
.keys
[k
] = Calloc(1, sizeof(struct key_s
));
241 while (*p
&& !isspace(*p
))
248 if (strcasecmp(p
, "none") == 0)
249 config
.keys
[k
]->type
= KEY_DEFAULT
;
250 else if (strcasecmp(p
, "repeat") == 0)
251 config
.keys
[k
]->type
= KEY_REPEAT
;
252 else if (strcasecmp(p
, "set") == 0)
253 config
.keys
[k
]->type
= KEY_SET
;
255 errx(EXIT_FAILURE
, "%s(%i): invalid value \"%s\"", filename
,
261 while (*p
&& isspace(*p
))
264 config
.keys
[k
]->c
= *p
++;
265 config
.keys
[k
++]->str
= strdup(p
);
266 config
.keys
[k
] = NULL
;
268 else if (strcmp(var
, "engine_init") == 0) {
269 config
.einit
= Realloc(config
.einit
, (init
+ 2) * sizeof(char *));
270 config
.einit
[init
++] = strdup(val
);
271 config
.einit
[init
] = NULL
;
273 else if (strcmp(var
, "pattern") == 0) {
274 free(config
.pattern
);
275 config
.pattern
= strdup(val
);
277 else if (strcmp(var
, "mpl") == 0) {
279 errx(EXIT_FAILURE
, "%s(%i): value is not an integer", filename
,
281 pgn_config_set(PGN_MPL
, atoi(val
));
283 else if (strcmp(var
, "stop_on_error") == 0)
284 pgn_config_set(PGN_STOP_ON_ERROR
, on_or_off(filename
, lines
, val
));
285 else if (strcmp(var
, "tag") == 0) {
286 if ((n
= sscanf(val
, "%s %s ", token
, value
)) < 1 ||
288 errx(EXIT_FAILURE
, "%s(%i): invalid value \"%s\"", filename
,
294 p
= val
+ strlen(token
);
295 strncpy(value
, p
, sizeof(value
));
298 for (n
= 0; n
< strlen(token
); n
++) {
299 if (!isalnum(token
[n
]) && token
[n
] != '_')
301 "%s(%i): token names must match 0-9A-Za-z_.",
305 token
[0] = toupper(token
[0]);
306 pgn_tag_add(&config
.tag
, token
, value
);
308 else if (strcmp(var
, "save_directory") == 0)
309 config
.savedirectory
= strdup(val
);
310 else if (strcmp(var
, "line_graphics") == 0)
311 config
.linegraphics
= on_or_off(filename
, lines
, val
);
312 else if (strcmp(var
, "save_prompt") == 0)
313 config
.saveprompt
= on_or_off(filename
, lines
, val
);
314 else if (strcmp(var
, "delete_prompt") == 0)
315 config
.deleteprompt
= on_or_off(filename
, lines
, val
);
316 else if (strcmp(var
, "valid_moves") == 0)
317 config
.validmoves
= on_or_off(filename
, lines
, val
);
318 else if (strcmp(var
, "board_details") == 0)
319 config
.details
= on_or_off(filename
, lines
, val
);
320 else if (strcmp(var
, "engine_cmd") == 0)
321 altengine
= strdup(val
);
322 else if (strcmp(var
, "color_board_window") == 0)
323 parse_color(filename
, lines
, val
, &config
.color
[CONF_BDWINDOW
]);
324 else if (strcmp(var
, "color_board_selected") == 0)
325 parse_color(filename
, lines
, val
, &config
.color
[CONF_BSELECTED
]);
326 else if (strcmp(var
, "color_board_white_moves") == 0)
327 parse_color(filename
, lines
, val
, &config
.color
[CONF_BMOVESW
]);
328 else if (strcmp(var
, "color_board_black_moves") == 0)
329 parse_color(filename
, lines
, val
, &config
.color
[CONF_BMOVESB
]);
330 else if (strcmp(var
, "color_board_count") == 0)
331 parse_color(filename
, lines
, val
, &config
.color
[CONF_BCOUNT
]);
332 else if (strcmp(var
, "color_board_cursor") == 0)
333 parse_color(filename
, lines
, val
, &config
.color
[CONF_BCURSOR
]);
334 else if (strcmp(var
, "color_board_black") == 0)
335 parse_color(filename
, lines
, val
, &config
.color
[CONF_BBLACK
]);
336 else if (strcmp(var
, "color_board_white") == 0)
337 parse_color(filename
, lines
, val
, &config
.color
[CONF_BWHITE
]);
338 else if (strcmp(var
, "color_board_graphics") == 0)
339 parse_color(filename
, lines
, val
, &config
.color
[CONF_BGRAPHICS
]);
340 else if (strcmp(var
, "color_board_coords") == 0)
341 parse_color(filename
, lines
, val
, &config
.color
[CONF_BCOORDS
]);
342 else if (strcmp(var
, "color_status_window") == 0)
343 parse_color(filename
, lines
, val
, &config
.color
[CONF_SWINDOW
]);
344 else if (strcmp(var
, "color_status_title") == 0)
345 parse_color(filename
, lines
, val
, &config
.color
[CONF_STITLE
]);
346 else if (strcmp(var
, "color_status_border") == 0)
347 parse_color(filename
, lines
, val
, &config
.color
[CONF_SBORDER
]);
348 else if (strcmp(var
, "color_status_notify") == 0)
349 parse_color(filename
, lines
, val
, &config
.color
[CONF_SNOTIFY
]);
350 else if (strcmp(var
, "color_status_engine") == 0)
351 parse_color(filename
, lines
, val
, &config
.color
[CONF_SENGINE
]);
352 else if (strcmp(var
, "color_tag_window") == 0)
353 parse_color(filename
, lines
, val
, &config
.color
[CONF_TWINDOW
]);
354 else if (strcmp(var
, "color_tag_title") == 0)
355 parse_color(filename
, lines
, val
, &config
.color
[CONF_TTITLE
]);
356 else if (strcmp(var
, "color_tag_border") == 0)
357 parse_color(filename
, lines
, val
, &config
.color
[CONF_TBORDER
]);
358 else if (strcmp(var
, "color_history_window") == 0)
359 parse_color(filename
, lines
, val
, &config
.color
[CONF_HWINDOW
]);
360 else if (strcmp(var
, "color_history_title") == 0)
361 parse_color(filename
, lines
, val
, &config
.color
[CONF_HTITLE
]);
362 else if (strcmp(var
, "color_history_border") == 0)
363 parse_color(filename
, lines
, val
, &config
.color
[CONF_HBORDER
]);
364 else if (strcmp(var
, "color_message_window") == 0)
365 parse_color(filename
, lines
, val
, &config
.color
[CONF_MWINDOW
]);
366 else if (strcmp(var
, "color_message_title") == 0)
367 parse_color(filename
, lines
, val
, &config
.color
[CONF_MTITLE
]);
368 else if (strcmp(var
, "color_message_border") == 0)
369 parse_color(filename
, lines
, val
, &config
.color
[CONF_MBORDER
]);
370 else if (strcmp(var
, "color_message_prompt") == 0)
371 parse_color(filename
, lines
, val
, &config
.color
[CONF_MPROMPT
]);
372 else if (strcmp(var
, "color_input_window") == 0)
373 parse_color(filename
, lines
, val
, &config
.color
[CONF_IWINDOW
]);
374 else if (strcmp(var
, "color_input_title") == 0)
375 parse_color(filename
, lines
, val
, &config
.color
[CONF_ITITLE
]);
376 else if (strcmp(var
, "color_input_border") == 0)
377 parse_color(filename
, lines
, val
, &config
.color
[CONF_IBORDER
]);
378 else if (strcmp(var
, "color_input_prompt") == 0)
379 parse_color(filename
, lines
, val
, &config
.color
[CONF_IPROMPT
]);
380 else if (strcmp(var
, "color_menu") == 0)
381 parse_color(filename
, lines
, val
, &config
.color
[CONF_MENU
]);
382 else if (strcmp(var
, "color_menu_selected") == 0)
383 parse_color(filename
, lines
, val
, &config
.color
[CONF_MENUS
]);
384 else if (strcmp(var
, "color_menu_highlight") == 0)
385 parse_color(filename
, lines
, val
, &config
.color
[CONF_MENUH
]);
387 errx(EXIT_FAILURE
, "%s(%i): invalid parameter \"%s\"", filename
,
394 free(config
.engine_cmd
);
395 config
.engine_cmd
= NULL
;
396 config
.engine_cmd
= altengine
;