2 * $Id: charmap.c,v 1.1 2004/06/30 07:55:35 kenth Exp $
4 * Revision 1.1 2004/06/30 07:55:35 kenth
10 * (C) 2004 Kent Hansen
12 * The XORcyst is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * The XORcyst is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with The XORcyst; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 /** This file contains functions for parsing a custom character map.
28 * Such a map is used by the assembler to process .char directives.
29 * The map is a text file containing a series of lines of the following form:
32 * OR: keylo-keyhi=value (specifies a range of keys starting at value)
34 * where key is a character or C escape sequence, and value is an integer.
35 * # is considered the start of a comment; the rest of the line is ignored.
38 * # map lowercase letters starting at 0xC0, so that a=0xC0, b=0xC1, ...
40 * # map some punctuation
51 /*---------------------------------------------------------------------------*/
54 * Issues a character map error.
55 * @param filename File where error occured
56 * @param line Line of file
57 * @param fmt printf-style format string
59 static void maperr(const char *filename
, int line
, char *fmt
, ...)
64 /* Print error message */
65 fprintf(stderr
, "error: %s:%d: ", filename
, line
);
66 vfprintf(stderr
, fmt
, ap
);
67 fprintf(stderr
, "\n");
72 #define IS_SPACE(c) ( ((c) == '\t') || ((c) == ' ') )
76 * @param s String with whitespace (possibly)
77 * @param i Start index in string, will be incremented beyond whitespace
79 static void eat_ws(char *s
, int *i
)
81 while (IS_SPACE(s
[*i
])) (*i
)++;
86 * @param s Pointer to buffer containing key
87 * @param i Pointer to index of first character of key in s
88 * @param d Where to store the parsed key
90 static int get_key(char *s
, int *i
, char *d
)
93 /* Read first character */
95 /* Make sure we've not hit end of string */
96 if ((key
== '\0') || (key
== '\n')) { return 0; }
97 /* Check if escape character */
100 /* Make sure we've not hit end of string */
101 if ((key
== '\0') || (key
== '\n')) { return 0; }
102 /* Convert to C escape char if applicable */
104 case '0': key
= '\0'; break;
105 case 'a': key
= '\a'; break;
106 case 'b': key
= '\b'; break;
107 case 't': key
= '\t'; break;
108 case 'f': key
= '\f'; break;
109 case 'n': key
= '\n'; break;
110 case 'r': key
= '\r'; break;
121 * @param s Pointer to first character of value
123 static unsigned char get_value(char *s
)
126 return strtol(&s
[1], NULL
, 16);
127 } else if (s
[0] == '%') {
128 return strtol(&s
[1], NULL
, 2);
130 return strtol(s
, NULL
, 0);
134 * Parses a character map from file.
135 * @param filename Name of the character map file
136 * @param map 256-byte buffer where parsed map shall be stored
137 * @return 0 if fail, 1 if OK
139 int charmap_parse(const char *filename
, unsigned char *map
)
144 /* Attempt to open the file */
145 fp
= fopen(filename
, "rt");
149 /* Reset line counter */
152 while (fgets(line
, 1023, fp
) != NULL
) {
157 /* Increase line number */
162 /* Reset line index */
165 if (get_key(line
, &i
, &key
) == 0) {
166 maperr(filename
, lineno
, "key expected");
169 /* Check if this is a range definition */
170 if (line
[i
] == '-') {
174 if (get_key(line
, &i
, &hkey
) == 0) {
175 maperr(filename
, lineno
, "high limit key expected");
178 /* Make sure hkey larger or equal to key */
180 maperr(filename
, lineno
, "invalid range");
190 if (line
[i
] != '=') {
191 maperr(filename
, lineno
, "`=' expected");
198 /* Make sure we've not hit end of string */
199 if ((line
[i
] == '\0') || (line
[i
] == '\n')) {
200 maperr(filename
, lineno
, "value expected");
204 value
= get_value(&line
[i
]);
205 /* Store mapping(s) */
206 for (; key
<= hkey
; key
++) {