2 * $Id: charmap.c,v 1.3 2007/11/11 22:35:22 khansen Exp $
4 * Revision 1.3 2007/11/11 22:35:22 khansen
7 * Revision 1.2 2007/07/22 13:33:26 khansen
8 * convert tabs to whitespaces
10 * Revision 1.1 2004/06/30 07:55:35 kenth
16 * (C) 2004 Kent Hansen
18 * The XORcyst is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * The XORcyst is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with The XORcyst; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 /** This file contains functions for parsing a custom character map.
34 * Such a map is used by the assembler to process .char directives.
35 * The map is a text file containing a series of lines of the following form:
38 * OR: keylo-keyhi=value (specifies a range of keys starting at value)
40 * where key is a character or C escape sequence, and value is an integer.
41 * # is considered the start of a comment; the rest of the line is ignored.
44 * # map lowercase letters starting at 0xC0, so that a=0xC0, b=0xC1, ...
46 * # map some punctuation
57 /*---------------------------------------------------------------------------*/
60 * Issues a character map error.
61 * @param filename File where error occured
62 * @param line Line of file
63 * @param fmt printf-style format string
65 static void maperr(const char *filename
, int line
, const char *fmt
, ...)
70 /* Print error message */
71 fprintf(stderr
, "%s:%d: error: ", filename
, line
);
72 vfprintf(stderr
, fmt
, ap
);
73 fprintf(stderr
, "\n");
78 #define IS_SPACE(c) ( ((c) == '\t') || ((c) == ' ') )
82 * @param s String with whitespace (possibly)
83 * @param i Start index in string, will be incremented beyond whitespace
85 static void eat_ws(const char *s
, int *i
)
87 while (IS_SPACE(s
[*i
])) (*i
)++;
92 * @param s Pointer to buffer containing key
93 * @param i Pointer to index of first character of key in s
94 * @param d Where to store the parsed key
96 static int get_key(const char *s
, int *i
, unsigned char *d
)
99 /* Read first character */
101 /* Make sure we've not hit end of string */
102 if ((key
== '\0') || (key
== '\n')) { return 0; }
103 /* Check if escape character */
106 /* Make sure we've not hit end of string */
107 if ((key
== '\0') || (key
== '\n')) { return 0; }
108 /* Convert to C escape char if applicable */
110 case '0': key
= '\0'; break;
111 case 'a': key
= '\a'; break;
112 case 'b': key
= '\b'; break;
113 case 't': key
= '\t'; break;
114 case 'f': key
= '\f'; break;
115 case 'n': key
= '\n'; break;
116 case 'r': key
= '\r'; break;
127 * @param s Pointer to first character of value
129 static unsigned char get_value(const char *s
)
132 return strtol(&s
[1], NULL
, 16);
134 else if (s
[0] == '%') {
135 return strtol(&s
[1], NULL
, 2);
137 return strtol(s
, NULL
, 0);
141 * Parses a character map from file.
142 * @param filename Name of the character map file
143 * @param map 256-byte buffer where parsed map shall be stored
144 * @return 0 if fail, 1 if OK
146 int charmap_parse(const char *filename
, unsigned char *map
)
155 /* Attempt to open the file */
156 fp
= fopen(filename
, "rt");
160 /* Reset line counter */
163 while (fgets(line
, 1023, fp
) != NULL
) {
164 /* Increase line number */
166 /* Reset line index */
169 if (get_key(line
, &i
, &key
) == 0) {
170 maperr(filename
, lineno
, "key expected");
173 /* Check if this is a range definition */
174 if (line
[i
] == '-') {
178 if (get_key(line
, &i
, &hkey
) == 0) {
179 maperr(filename
, lineno
, "high limit key expected");
182 /* Make sure hkey larger or equal to key */
184 maperr(filename
, lineno
, "invalid range");
194 if (line
[i
] != '=') {
195 maperr(filename
, lineno
, "`=' expected");
202 /* Make sure we've not hit end of string */
203 if ((line
[i
] == '\0') || (line
[i
] == '\n')) {
204 maperr(filename
, lineno
, "value expected");
208 value
= get_value(&line
[i
]);
209 /* Store mapping(s) */
210 for (; key
<= hkey
; key
++) {