1 /* gpg-error.c - Determining gpg-error error codes.
2 Copyright (C) 2004 g10 Code GmbH
4 This file is part of libgpg-error.
6 libgpg-error is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public License
8 as published by the Free Software Foundation; either version 2.1 of
9 the License, or (at your option) any later version.
11 libgpg-error is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with libgpg-error; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
36 #ifdef HAVE_W32_SYSTEM
41 # define _(a) gettext (a)
43 # define N_(a) gettext_noop (a)
52 #include <gpg-error.h>
56 /* The implementation follows below. */
57 static char *get_locale_dir (void);
58 static void drop_locale_dir (char *locale_dir);
60 #define get_locale_dir() LOCALEDIR
61 #define drop_locale_dir(dir)
70 #ifdef HAVE_LC_MESSAGES
71 setlocale (LC_TIME, "");
72 setlocale (LC_MESSAGES, "");
74 # ifndef HAVE_W32_SYSTEM
75 setlocale (LC_ALL, "" );
79 /* Note that for this program we would only need the textdomain call
80 because libgpg-error already initializes itself to its locale dir
81 (via gpg_err_init or a constructor). However this is only done
82 for the static standard locale and thus if the above setlocale
83 calls select a different locale the bindtext below will do
86 locale_dir = get_locale_dir ();
89 bindtextdomain (PACKAGE, locale_dir);
90 drop_locale_dir (locale_dir);
97 #ifdef HAVE_W32_SYSTEM
103 get_locale_dir (void)
105 static wchar_t moddir[MAX_PATH+5];
109 if (!GetModuleFileNameW (NULL, moddir, MAX_PATH))
112 #define SLDIR "\\share\\locale"
115 nbytes = WideCharToMultiByte (CP_UTF8, 0, moddir, -1, NULL, 0, NULL, NULL);
119 result = malloc (nbytes + strlen (SLDIR) + 1);
122 nbytes = WideCharToMultiByte (CP_UTF8, 0, moddir, -1,
123 result, nbytes, NULL, NULL);
131 p = strrchr (result, '\\');
134 /* If we are installed below "bin" strip that part and
135 use the top directory instead. */
136 p = strrchr (result, '\\');
137 if (p && !strcmp (p+1, "bin"))
139 /* Append the static part. */
140 strcat (result, SLDIR);
144 else /* Use the old default value. */
146 result = malloc (10 + strlen (SLDIR) + 1);
149 strcpy (result, "c:\\gnupg");
150 strcat (result, SLDIR);
159 drop_locale_dir (char *locale_dir)
164 #endif /* HAVE_W32_SYSTEM */
167 const char *gpg_strerror_sym (gpg_error_t err);
168 const char *gpg_strsource_sym (gpg_error_t err);
172 get_err_from_number (char *str, gpg_error_t *err)
177 gpg_err_set_errno (0);
178 nr = strtoul (str, &tail, 0);
187 unsigned long cnr = strtoul (tail + 1, &tail, 0);
191 if (nr >= GPG_ERR_SOURCE_DIM || cnr >= GPG_ERR_CODE_DIM)
194 nr = gpg_err_make (nr, cnr);
197 *err = (unsigned int) nr;
203 get_err_from_symbol_one (char *str, gpg_error_t *err,
204 int *have_source, int *have_code)
206 static const char src_prefix[] = "GPG_ERR_SOURCE_";
207 static const char code_prefix[] = "GPG_ERR_";
209 if (!strncasecmp (src_prefix, str, sizeof (src_prefix) - 1))
211 gpg_err_source_t src;
216 str += sizeof (src_prefix) - 1;
218 for (src = 0; src < GPG_ERR_SOURCE_DIM; src++)
222 src_sym = gpg_strsource_sym (src << GPG_ERR_SOURCE_SHIFT);
223 if (src_sym && !strcasecmp (str, src_sym + sizeof (src_prefix) - 1))
225 *err |= src << GPG_ERR_SOURCE_SHIFT;
230 else if (!strncasecmp (code_prefix, str, sizeof (code_prefix) - 1))
237 str += sizeof (code_prefix) - 1;
239 for (code = 0; code < GPG_ERR_CODE_DIM; code++)
241 const char *code_sym = gpg_strerror_sym (code);
243 && !strcasecmp (str, code_sym + sizeof (code_prefix) - 1))
255 get_err_from_symbol (char *str, gpg_error_t *err)
261 char *saved_pos = NULL;
265 while (*str2 && ((*str2 >= 'A' && *str2 <= 'Z')
266 || (*str2 >= '0' && *str2 <= '9')
279 ret = get_err_from_symbol_one (str, err, &have_source, &have_code);
281 ret = get_err_from_symbol_one (str2, err, &have_source, &have_code);
284 *saved_pos = saved_char;
290 get_err_from_str_one (char *str, gpg_error_t *err,
291 int *have_source, int *have_code)
293 gpg_err_source_t src;
296 for (src = 0; src < GPG_ERR_SOURCE_DIM; src++)
298 const char *src_str = gpg_strsource (src << GPG_ERR_SOURCE_SHIFT);
299 if (src_str && !strcasecmp (str, src_str))
305 *err |= src << GPG_ERR_SOURCE_SHIFT;
310 for (code = 0; code < GPG_ERR_CODE_DIM; code++)
312 const char *code_str = gpg_strerror (code);
313 if (code_str && !strcasecmp (str, code_str))
329 get_err_from_str (char *str, gpg_error_t *err)
335 char *saved_pos = NULL;
339 ret = get_err_from_str_one (str, err, &have_source, &have_code);
343 while (*str2 && ((*str2 >= 'A' && *str2 <= 'Z')
344 || (*str2 >= 'a' && *str2 <= 'z')
345 || (*str2 >= '0' && *str2 <= '9')
352 *((char *) str2) = '\0';
354 while (*str2 && !((*str2 >= 'A' && *str2 <= 'Z')
355 || (*str2 >= 'a' && *str2 <= 'z')
356 || (*str2 >= '0' && *str2 <= '9')
363 ret = get_err_from_str_one (str, err, &have_source, &have_code);
365 ret = get_err_from_str_one (str2, err, &have_source, &have_code);
368 *saved_pos = saved_char;
375 main (int argc, char *argv[])
379 const char *source_sym;
380 const char *error_sym;
383 #ifndef GPG_ERR_INITIALIZED
392 fprintf (stderr, _("Usage: %s GPG-ERROR [...]\n"),
393 strrchr (argv[0],'/')? (strrchr (argv[0], '/')+1): argv[0]);
396 else if (argc == 2 && !strcmp (argv[1], "--version"))
398 fputs ("gpg-error (" PACKAGE_NAME ") " PACKAGE_VERSION "\n", stdout);
401 else if (argc == 2 && !strcmp (argv[1], "--list"))
409 for (i=0; i < GPG_ERR_SOURCE_DIM; i++)
411 /* We use error code 1 because gpg_err_make requires a
412 non-zero error code. */
413 err = gpg_err_make (i, 1);
415 source_sym = gpg_strsource_sym (err);
417 printf ("%u = (%u, -) = (%s, -) = (%s, -)\n",
418 err, gpg_err_source (err),
419 source_sym, gpg_strsource (err));
421 for (i=0; i < GPG_ERR_CODE_DIM; i++)
423 err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i);
424 error_sym = gpg_strerror_sym (err);
426 printf ("%u = (-, %u) = (-, %s) = (-, %s)\n",
427 err, gpg_err_code (err),
428 error_sym, gpg_strerror (err));
431 i = argc; /* Don't run the usual stuff. */
435 if (get_err_from_number (argv[i], &err)
436 || get_err_from_symbol (argv[i], &err)
437 || get_err_from_str (argv[i], &err))
439 source_sym = gpg_strsource_sym (err);
440 error_sym = gpg_strerror_sym (err);
442 printf ("%u = (%u, %u) = (%s, %s) = (%s, %s)\n",
443 err, gpg_err_source (err), gpg_err_code (err),
444 source_sym ? source_sym : "-", error_sym ? error_sym : "-",
445 gpg_strsource (err), gpg_strerror (err));
448 fprintf (stderr, _("%s: warning: could not recognize %s\n"),