PageRenderTime 77ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/hunspell-1.3.2/intl/printf.c

https://bitbucket.org/VirtualReality/3p-hunspell
C | 427 lines | 339 code | 49 blank | 39 comment | 46 complexity | 3beb97c21416071fa2a8fdb740273870 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1
  1. /* Formatted output to strings, using POSIX/XSI format strings with positions.
  2. Copyright (C) 2003, 2006-2007 Free Software Foundation, Inc.
  3. Written by Bruno Haible <bruno@clisp.org>, 2003.
  4. This program is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU Library General Public License as published
  6. by the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  15. USA. */
  16. #ifdef HAVE_CONFIG_H
  17. # include <config.h>
  18. #endif
  19. #ifdef __GNUC__
  20. # define alloca __builtin_alloca
  21. # define HAVE_ALLOCA 1
  22. #else
  23. # ifdef _MSC_VER
  24. # include <malloc.h>
  25. # define alloca _alloca
  26. # else
  27. # if defined HAVE_ALLOCA_H || defined _LIBC
  28. # include <alloca.h>
  29. # else
  30. # ifdef _AIX
  31. #pragma alloca
  32. # else
  33. # ifndef alloca
  34. char *alloca ();
  35. # endif
  36. # endif
  37. # endif
  38. # endif
  39. #endif
  40. #include <stdio.h>
  41. #if !HAVE_POSIX_PRINTF
  42. #include <errno.h>
  43. #include <limits.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
  47. #ifndef EOVERFLOW
  48. # define EOVERFLOW E2BIG
  49. #endif
  50. /* When building a DLL, we must export some functions. Note that because
  51. the functions are only defined for binary backward compatibility, we
  52. don't need to use __declspec(dllimport) in any case. */
  53. #if defined _MSC_VER && BUILDING_DLL
  54. # define DLL_EXPORTED __declspec(dllexport)
  55. #else
  56. # define DLL_EXPORTED
  57. #endif
  58. #define STATIC static
  59. /* This needs to be consistent with libgnuintl.h.in. */
  60. #if defined __NetBSD__ || defined __BEOS__ || defined __CYGWIN__ || defined __MINGW32__
  61. /* Don't break __attribute__((format(printf,M,N))).
  62. This redefinition is only possible because the libc in NetBSD, Cygwin,
  63. mingw does not have a function __printf__. */
  64. # define libintl_printf __printf__
  65. #endif
  66. /* Define auxiliary functions declared in "printf-args.h". */
  67. #include "printf-args.c"
  68. /* Define auxiliary functions declared in "printf-parse.h". */
  69. #include "printf-parse.c"
  70. /* Define functions declared in "vasnprintf.h". */
  71. #define vasnprintf libintl_vasnprintf
  72. #include "vasnprintf.c"
  73. #if 0 /* not needed */
  74. #define asnprintf libintl_asnprintf
  75. #include "asnprintf.c"
  76. #endif
  77. DLL_EXPORTED
  78. int
  79. libintl_vfprintf (FILE *stream, const char *format, va_list args)
  80. {
  81. if (strchr (format, '$') == NULL)
  82. return vfprintf (stream, format, args);
  83. else
  84. {
  85. size_t length;
  86. char *result = libintl_vasnprintf (NULL, &length, format, args);
  87. int retval = -1;
  88. if (result != NULL)
  89. {
  90. size_t written = fwrite (result, 1, length, stream);
  91. free (result);
  92. if (written == length)
  93. {
  94. if (length > INT_MAX)
  95. errno = EOVERFLOW;
  96. else
  97. retval = length;
  98. }
  99. }
  100. return retval;
  101. }
  102. }
  103. DLL_EXPORTED
  104. int
  105. libintl_fprintf (FILE *stream, const char *format, ...)
  106. {
  107. va_list args;
  108. int retval;
  109. va_start (args, format);
  110. retval = libintl_vfprintf (stream, format, args);
  111. va_end (args);
  112. return retval;
  113. }
  114. DLL_EXPORTED
  115. int
  116. libintl_vprintf (const char *format, va_list args)
  117. {
  118. return libintl_vfprintf (stdout, format, args);
  119. }
  120. DLL_EXPORTED
  121. int
  122. libintl_printf (const char *format, ...)
  123. {
  124. va_list args;
  125. int retval;
  126. va_start (args, format);
  127. retval = libintl_vprintf (format, args);
  128. va_end (args);
  129. return retval;
  130. }
  131. DLL_EXPORTED
  132. int
  133. libintl_vsprintf (char *resultbuf, const char *format, va_list args)
  134. {
  135. if (strchr (format, '$') == NULL)
  136. return vsprintf (resultbuf, format, args);
  137. else
  138. {
  139. size_t length = (size_t) ~0 / (4 * sizeof (char));
  140. char *result = libintl_vasnprintf (resultbuf, &length, format, args);
  141. if (result != resultbuf)
  142. {
  143. free (result);
  144. return -1;
  145. }
  146. if (length > INT_MAX)
  147. {
  148. errno = EOVERFLOW;
  149. return -1;
  150. }
  151. else
  152. return length;
  153. }
  154. }
  155. DLL_EXPORTED
  156. int
  157. libintl_sprintf (char *resultbuf, const char *format, ...)
  158. {
  159. va_list args;
  160. int retval;
  161. va_start (args, format);
  162. retval = libintl_vsprintf (resultbuf, format, args);
  163. va_end (args);
  164. return retval;
  165. }
  166. #if HAVE_SNPRINTF
  167. # if HAVE_DECL__SNPRINTF
  168. /* Windows. */
  169. # define system_vsnprintf _vsnprintf
  170. # else
  171. /* Unix. */
  172. # define system_vsnprintf vsnprintf
  173. # endif
  174. DLL_EXPORTED
  175. int
  176. libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list args)
  177. {
  178. if (strchr (format, '$') == NULL)
  179. return system_vsnprintf (resultbuf, length, format, args);
  180. else
  181. {
  182. size_t maxlength = length;
  183. char *result = libintl_vasnprintf (resultbuf, &length, format, args);
  184. if (result != resultbuf)
  185. {
  186. if (maxlength > 0)
  187. {
  188. size_t pruned_length =
  189. (length < maxlength ? length : maxlength - 1);
  190. memcpy (resultbuf, result, pruned_length);
  191. resultbuf[pruned_length] = '\0';
  192. }
  193. free (result);
  194. }
  195. if (length > INT_MAX)
  196. {
  197. errno = EOVERFLOW;
  198. return -1;
  199. }
  200. else
  201. return length;
  202. }
  203. }
  204. DLL_EXPORTED
  205. int
  206. libintl_snprintf (char *resultbuf, size_t length, const char *format, ...)
  207. {
  208. va_list args;
  209. int retval;
  210. va_start (args, format);
  211. retval = libintl_vsnprintf (resultbuf, length, format, args);
  212. va_end (args);
  213. return retval;
  214. }
  215. #endif
  216. #if HAVE_ASPRINTF
  217. DLL_EXPORTED
  218. int
  219. libintl_vasprintf (char **resultp, const char *format, va_list args)
  220. {
  221. size_t length;
  222. char *result = libintl_vasnprintf (NULL, &length, format, args);
  223. if (result == NULL)
  224. return -1;
  225. if (length > INT_MAX)
  226. {
  227. free (result);
  228. errno = EOVERFLOW;
  229. return -1;
  230. }
  231. *resultp = result;
  232. return length;
  233. }
  234. DLL_EXPORTED
  235. int
  236. libintl_asprintf (char **resultp, const char *format, ...)
  237. {
  238. va_list args;
  239. int retval;
  240. va_start (args, format);
  241. retval = libintl_vasprintf (resultp, format, args);
  242. va_end (args);
  243. return retval;
  244. }
  245. #endif
  246. #if HAVE_FWPRINTF
  247. #include <wchar.h>
  248. #define WIDE_CHAR_VERSION 1
  249. #include "wprintf-parse.h"
  250. /* Define auxiliary functions declared in "wprintf-parse.h". */
  251. #define CHAR_T wchar_t
  252. #define DIRECTIVE wchar_t_directive
  253. #define DIRECTIVES wchar_t_directives
  254. #define PRINTF_PARSE wprintf_parse
  255. #include "printf-parse.c"
  256. /* Define functions declared in "vasnprintf.h". */
  257. #define vasnwprintf libintl_vasnwprintf
  258. #include "vasnprintf.c"
  259. #if 0 /* not needed */
  260. #define asnwprintf libintl_asnwprintf
  261. #include "asnprintf.c"
  262. #endif
  263. # if HAVE_DECL__SNWPRINTF
  264. /* Windows. */
  265. # define system_vswprintf _vsnwprintf
  266. # else
  267. /* Unix. */
  268. # define system_vswprintf vswprintf
  269. # endif
  270. DLL_EXPORTED
  271. int
  272. libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
  273. {
  274. if (wcschr (format, '$') == NULL)
  275. return vfwprintf (stream, format, args);
  276. else
  277. {
  278. size_t length;
  279. wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
  280. int retval = -1;
  281. if (result != NULL)
  282. {
  283. size_t i;
  284. for (i = 0; i < length; i++)
  285. if (fputwc (result[i], stream) == WEOF)
  286. break;
  287. free (result);
  288. if (i == length)
  289. {
  290. if (length > INT_MAX)
  291. errno = EOVERFLOW;
  292. else
  293. retval = length;
  294. }
  295. }
  296. return retval;
  297. }
  298. }
  299. DLL_EXPORTED
  300. int
  301. libintl_fwprintf (FILE *stream, const wchar_t *format, ...)
  302. {
  303. va_list args;
  304. int retval;
  305. va_start (args, format);
  306. retval = libintl_vfwprintf (stream, format, args);
  307. va_end (args);
  308. return retval;
  309. }
  310. DLL_EXPORTED
  311. int
  312. libintl_vwprintf (const wchar_t *format, va_list args)
  313. {
  314. return libintl_vfwprintf (stdout, format, args);
  315. }
  316. DLL_EXPORTED
  317. int
  318. libintl_wprintf (const wchar_t *format, ...)
  319. {
  320. va_list args;
  321. int retval;
  322. va_start (args, format);
  323. retval = libintl_vwprintf (format, args);
  324. va_end (args);
  325. return retval;
  326. }
  327. DLL_EXPORTED
  328. int
  329. libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_list args)
  330. {
  331. if (wcschr (format, '$') == NULL)
  332. return system_vswprintf (resultbuf, length, format, args);
  333. else
  334. {
  335. size_t maxlength = length;
  336. wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
  337. if (result != resultbuf)
  338. {
  339. if (maxlength > 0)
  340. {
  341. size_t pruned_length =
  342. (length < maxlength ? length : maxlength - 1);
  343. memcpy (resultbuf, result, pruned_length * sizeof (wchar_t));
  344. resultbuf[pruned_length] = 0;
  345. }
  346. free (result);
  347. /* Unlike vsnprintf, which has to return the number of character that
  348. would have been produced if the resultbuf had been sufficiently
  349. large, the vswprintf function has to return a negative value if
  350. the resultbuf was not sufficiently large. */
  351. if (length >= maxlength)
  352. return -1;
  353. }
  354. if (length > INT_MAX)
  355. {
  356. errno = EOVERFLOW;
  357. return -1;
  358. }
  359. else
  360. return length;
  361. }
  362. }
  363. DLL_EXPORTED
  364. int
  365. libintl_swprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, ...)
  366. {
  367. va_list args;
  368. int retval;
  369. va_start (args, format);
  370. retval = libintl_vswprintf (resultbuf, length, format, args);
  371. va_end (args);
  372. return retval;
  373. }
  374. #endif
  375. #endif