2 * Copyright (C) 2010 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 (* Please read generator/README first. *)
26 open Generator_docstrings
28 (* Generate the functions errno_to_string and string_to_errno which
29 * convert errno (eg. EINVAL) into string ("EINVAL") and back again,
30 * allowing us to portably pass error values over the protocol between
31 * different versions of Un*x.
34 (* Errors found in POSIX plus additional errors found in the Linux
35 * header files. NOTE keep this sorted and avoid duplicates.
62 (*"EDEADLK"; - same as EDEADLOCK*)
138 (*"EOPNOTSUPP"; - duplicates another error, and we don't care because
139 it's a network error *)
169 (*"EWOULDBLOCK"; - same as EAGAIN*)
173 (* This is a non-existent errno which is simply used to test that
174 * the generated code can handle such cases on future platforms
175 * where one of the above error codes might not exist.
181 (* Check list is sorted and no duplicates. *)
182 let file = "generator/generator_errnostring.ml" in
184 let len = String.length str in
185 if len == 0 || len > 32 then
186 failwithf "%s: errno empty or length > 32 (%s)" file str;
187 if str.[0] <> 'E' then
188 failwithf "%s: errno string does not begin with letter 'E' (%s)" file str;
189 for i = 0 to len-1 do
191 if Char.uppercase c <> c then
192 failwithf "%s: errno string is not all uppercase (%s)" file str
195 let rec loop = function
197 | x :: y :: xs when x = y ->
198 failwithf "%s: errnos list contains duplicates (%s)" file x
199 | x :: y :: xs when x > y ->
200 failwithf "%s: errnos list is not sorted (%s > %s)" file x y
201 | x :: xs -> check x; loop xs
205 let generate_errnostring_h () =
206 generate_header CStyle LGPLv2plus;
209 #ifndef GUESTFS_ERRNOSTRING_H_
210 #define GUESTFS_ERRNOSTRING_H_
212 /* Convert errno (eg. EIO) to its string representation (\"EIO\").
213 * This only works for a set of errors that are listed in the generator
214 * AND are supported on the local operating system. For other errors
215 * the string (\"EINVAL\") is returned.
217 * NOTE: It is an error to call this function with errnum == 0.
219 extern const char *guestfs___errno_to_string (int errnum);
221 /* Convert string representation of an error (eg. \"EIO\") to the errno
222 * value (EIO). As for the function above, this only works for a
223 * subset of errors. For errors not supported by the local operating
224 * system, EINVAL is returned (all POSIX-conforming systems must
227 extern int guestfs___string_to_errno (const char *errnostr);
229 /* Private structure and function used by the perfect hash implementation. */
230 struct errnostring_entry { char *name; int errnum; };
231 extern const struct errnostring_entry *guestfs___string_to_errno_lookup (register const char *str, register unsigned int len);
233 #endif /* GUESTFS_ERRNOSTRING_H_ */
236 let generate_errnostring_c () =
237 generate_header CStyle LGPLv2plus;
246 #include \"errnostring.h\"
248 static const char *errno_to_string[] = {
254 pr " [%s] = \"%s\",\n" e e;
261 #define ERRNO_TO_STRING_SIZE \\
262 (sizeof errno_to_string / sizeof errno_to_string[0])
265 guestfs___errno_to_string (int errnum)
267 /* See function documentation. */
271 if (errnum < 0 || (size_t) errnum >= ERRNO_TO_STRING_SIZE ||
272 errno_to_string[errnum] == NULL)
275 return errno_to_string[errnum];
279 guestfs___string_to_errno (const char *errnostr)
281 const struct errnostring_entry *v =
282 guestfs___string_to_errno_lookup (errnostr, strlen (errnostr));
283 if (v /* not necessary to check v->name != NULL here */)
290 let generate_errnostring_gperf () =
291 generate_header CStyle LGPLv2plus;
295 %%define lookup-function-name guestfs___string_to_errno_lookup
307 #include \"errnostring.h\"
311 (* Some of these errnos might not exist on the target platform, but
312 * we are going to include E_ macros directly in the C output of
313 * gperf. To avoid this causing errors, we include macros to define
314 * unknown errors as EINVAL (see specification of
315 * guestfs___string_to_errno above). Note this only affects the
316 * single output file containing gperf-generated code.
321 pr "#define %s EINVAL\n" e;
329 struct errnostring_entry;