]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/genErrorStrings/genErrorStrings.cpp
Security-57031.10.10.tar.gz
[apple/security.git] / SecurityTests / cspxutils / genErrorStrings / genErrorStrings.cpp
1 /*
2 * genErrorStrings.cpp - parse supplied files, generate error table from
3 * them of the following form:
4 *
5 * typedef struct {
6 * CSSM_RETURN errCode;
7 * const char *errStr;
8 * } ErrString;
9 *
10 * ErrString errStrings[] = {
11 * { CSSMERR_CSSM_INTERNAL_ERROR, "CSSMERR_CSSM_INTERNAL_ERROR" },
12 * ...
13 * { CSSMERR_CSP_FUNCTION_FAILED, "CSSMERR_CSP_FUNCTION_FAILED" }
14 * };
15 *
16 * The error table is written to stdout.
17 */
18
19 #include <stdlib.h>
20 #include <strings.h>
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <ctype.h>
24 #include "fileIo.h"
25
26 #define MAX_LINE_LEN 256
27
28 static void usage(char **argv)
29 {
30 printf("usage: %s inFile [inFile...]\n", argv[0]);
31 exit(1);
32 }
33
34 static void writePreamble(
35 FILE *f)
36 {
37 fprintf(f, "/*\n");
38 fprintf(f, " * This file autogenerated by genErrorStrings. Do not edit. \n");
39 fprintf(f, " */\n\n");
40 fprintf(f, "#include <Security/Security.h>\n\n");
41 fprintf(f, "typedef struct {\n");
42 fprintf(f, "\tCSSM_RETURN errCode;\n");
43 fprintf(f, "\tconst char *errStr;\n");
44 fprintf(f, "} ErrString;\n\n");
45 fprintf(f, "static const ErrString errStrings[] = {\n");
46 }
47
48 static void writePostamble(
49 FILE *f)
50 {
51 /* generate a null entry as terminator */
52 fprintf(f, "\t{0, NULL}\n");
53 fprintf(f, "};\n");
54 }
55
56 static void writeToken(
57 const char *token,
58 FILE *f)
59 {
60 printf("\t{ %s,\"%s\"},\n", token, token);
61 }
62
63 /* skip whitespace (but not line terminators) */
64 static void skipWhite(
65 const char *&cp,
66 unsigned &bytesLeft)
67 {
68 while(bytesLeft != 0) {
69 switch(*cp) {
70 case ' ':
71 case '\t':
72 cp++;
73 bytesLeft--;
74 break;
75 default:
76 return;
77 }
78 }
79 }
80
81 static void getLine(
82 const char *&cp, // IN/OUT
83 unsigned &bytesLeft, // IN/OUT bytes left
84 char *lineBuf)
85 {
86 char *outp = lineBuf;
87 char *endOfOut = outp + MAX_LINE_LEN - 2;
88 while(bytesLeft != 0) {
89 switch(*cp) {
90 case '\n':
91 case '\r':
92 cp++;
93 bytesLeft--;
94 *outp = 0;
95 return;
96 default:
97 *outp++ = *cp++;
98 bytesLeft--;
99 break;
100 }
101 if(outp == endOfOut) {
102 printf("***getLine: line length exceeded!\n");
103 break;
104 }
105 }
106 /* end of file */
107 *outp = 0;
108 }
109
110 /* incoming line is NULL terminated even if it's empty */
111 static bool isLineEmpty(
112 const char *cp)
113 {
114 for( ; *cp; cp++) {
115 switch(*cp) {
116 case ' ':
117 case '\t':
118 break;
119 default:
120 return false;
121 }
122 }
123 return true;
124 }
125
126 /* process one file */
127 static void processFile(
128 const char *fileName,
129 const char *in,
130 unsigned inLen,
131 FILE *f)
132 {
133 char lineBuf[MAX_LINE_LEN];
134 unsigned lineLen;
135 const char *cp;
136 const char *endOfToken;
137 char tokenBuf[MAX_LINE_LEN];
138 unsigned tokenLen;
139 const char *lastSlash = fileName;
140 const char *nextSlash;
141
142 while((nextSlash = strchr(lastSlash, '/')) != NULL) {
143 lastSlash = nextSlash + 1;
144 }
145 fprintf(f, "\t/* Error codes from %s */\n", lastSlash);
146
147 while(inLen != 0) {
148 /* get one line, NULL terminated */
149 getLine(in, inLen, lineBuf);
150 if(isLineEmpty(lineBuf)) {
151 continue;
152 }
153
154 /* skip leading whitespace */
155 lineLen = strlen(lineBuf);
156 cp = lineBuf;
157 skipWhite(cp, lineLen);
158
159 /* interesting? */
160 if(strncmp((char *)cp, "CSSMERR_", 8)) {
161 continue;
162 }
163
164 /*
165 * cp is the start of the CSSMERR_ token
166 * find end of token
167 */
168 endOfToken = cp + 8;
169 for(;;) {
170 if(isalnum(*endOfToken) || (*endOfToken == '_')) {
171 endOfToken++;
172 continue;
173 }
174 else {
175 break;
176 }
177 }
178
179 /* endOfToken is one past the end of the CSSMERR_ token */
180 tokenLen = endOfToken - cp;
181 memmove(tokenBuf, cp, tokenLen);
182 tokenBuf[tokenLen] = '\0';
183
184 /* write the stuff */
185 writeToken(tokenBuf, f);
186 }
187 }
188
189 int main(int argc, char **argv)
190 {
191 unsigned char *inFile;
192 unsigned inFileLen;
193 int dex;
194
195 if(argc < 2) {
196 usage(argv);
197 }
198
199 writePreamble(stdout);
200 writeToken("CSSM_OK", stdout);
201 for(dex=1; dex<argc; dex++) {
202 if(readFile(argv[dex], &inFile, &inFileLen)) {
203 printf("***Error reading %s. Aborting.\n", argv[dex]);
204 exit(1);
205 }
206 processFile(argv[dex], (const char *)inFile, inFileLen, stdout);
207 free(inFile);
208 }
209 writePostamble(stdout);
210 return 0;
211 }