Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

600 lines
17 KiB

  1. /*
  2. * Adobe Universal Font Library
  3. *
  4. * Copyright (c) 1996 Adobe Systems Inc.
  5. * All Rights Reserved
  6. *
  7. * UFLSProc.h
  8. *
  9. * This file contents standard C procedure implementation.
  10. *
  11. *
  12. * $Header:
  13. */
  14. #include "UFLCnfig.h"
  15. #include "UFLTypes.h"
  16. #include "UFLStd.h"
  17. #ifdef UNIX
  18. #include <sys/varargs.h>
  19. #include <assert.h>
  20. #else
  21. #ifdef MAC_ENV
  22. #include <assert.h>
  23. #endif
  24. #include <stdarg.h>
  25. #endif
  26. #ifdef __cplusplus
  27. extern "C" {
  28. #endif
  29. int strcmpW( unsigned short *str1, unsigned short *str2 )
  30. {
  31. int retVal = 0;
  32. if( str1 == NULL || str2 == NULL )
  33. retVal = (int)(str1 - str2);
  34. else
  35. {
  36. while( *str1 != 0 && *str2 != 0 && *str1 == *str2 )
  37. {
  38. str1++;
  39. str2++;
  40. }
  41. retVal = *str1 - *str2;
  42. }
  43. return retVal;
  44. }
  45. /* Digit characters used for converting numbers to ASCII */
  46. const char DigitString[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  47. #define HexDigit(n) DigitString[(n) & 0x0F]
  48. int
  49. UFLvsprintf(
  50. char *buf,
  51. size_t cchDest,
  52. const char *fmtstr,
  53. va_list arglist
  54. )
  55. /*++
  56. Routine Description:
  57. Takes a pointer to an argument list, then formats and writes
  58. the given data to the memory pointed to by buffer.
  59. Arguments:
  60. buf Storage location for output
  61. cchDest size (in chars) of the destination buffer
  62. fmtstr Format specification
  63. arglist Pointer to list of arguments
  64. Return Value:
  65. Return the number of characters written, not including
  66. the terminating null character, or a negative value if
  67. an output error occurs.
  68. [Note:]
  69. This is NOT a full implementation of "vsprintf" as found
  70. in the C runtime library. Specifically, the only form of
  71. format specification allowed is %type, where "type" can
  72. be one of the following characters:
  73. d int signed decimal integer
  74. l long signed decimal integer
  75. ld long signed decimal integer
  76. lu unsigned long unsigned decimal integer
  77. u unsigned int unsigned decimal integer
  78. s char* character string
  79. c char character
  80. x,X unsigned long hex number (emits at least two digits, uppercase)
  81. b UFLBool boolean (true or false)
  82. f long 24.8 fixed-pointed number
  83. --*/
  84. {
  85. char *ptr, *ptrEnd;
  86. char achTmp[36]; // for _ltoa/_ultoa use
  87. if (buf == 0 || cchDest == 0 || fmtstr == 0)
  88. return 0;
  89. ptr = buf;
  90. ptrEnd = ptr + cchDest;
  91. while (*fmtstr != '\0')
  92. {
  93. if (*fmtstr != '%')
  94. {
  95. /* Normal character */
  96. *ptr++ = *fmtstr++;
  97. }
  98. else
  99. {
  100. /* Format specification */
  101. switch (*++fmtstr) {
  102. case 'd': /* signed decimal integer */
  103. _ltoa((long) va_arg(arglist, int), achTmp, 10);
  104. KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
  105. ptr += UFLstrlen(ptr);
  106. break;
  107. case 'l': /* signed decimal integer */
  108. if (*++fmtstr != '\0')
  109. {
  110. if (*fmtstr == 'u')
  111. {
  112. _ultoa(va_arg(arglist, unsigned long), achTmp, 10);
  113. KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
  114. ptr += UFLstrlen(ptr);
  115. break;
  116. }
  117. else if (*fmtstr == 'd')
  118. {
  119. _ltoa((long) va_arg(arglist, long), achTmp, 10);
  120. KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
  121. ptr += UFLstrlen(ptr);
  122. break;
  123. }
  124. }
  125. /* Default to unsigned long */
  126. _ltoa(va_arg(arglist, long), achTmp, 10);
  127. KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
  128. ptr += UFLstrlen(ptr);
  129. fmtstr--;
  130. break;
  131. case 'u': /* unsigned decimal integer */
  132. _ultoa((unsigned long)va_arg(arglist, unsigned int), achTmp, 10);
  133. KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
  134. ptr += UFLstrlen(ptr);
  135. break;
  136. case 's': /* character string */
  137. {
  138. char *s = va_arg(arglist, char *);
  139. while (*s)
  140. {
  141. *ptr++ = *s++;
  142. if (ptr >= ptrEnd)
  143. {
  144. break;
  145. }
  146. }
  147. }
  148. break;
  149. case 'c': /* character */
  150. *ptr++ = va_arg(arglist, char);
  151. break;
  152. case 'x':
  153. case 'X': /* hexdecimal number */
  154. {
  155. unsigned long ul = va_arg(arglist, unsigned long);
  156. int ndigits = 8;
  157. while (ndigits > 2 && ((ul >> (ndigits-1)*4) & 0xf) == 0)
  158. ndigits--;
  159. while (ndigits-- > 0)
  160. {
  161. *ptr++ = HexDigit(ul >> ndigits*4);
  162. if (ptr >= ptrEnd)
  163. {
  164. break;
  165. }
  166. }
  167. }
  168. break;
  169. case 'b': /* boolean */
  170. KStringCchCopyA(ptr, ptrEnd - ptr, (va_arg(arglist, UFLBool)) ? "true" : "false");
  171. ptr += UFLstrlen(ptr);
  172. break;
  173. case 'f': /* 24.8 fixed-pointed number */
  174. {
  175. long l = va_arg(arglist, long);
  176. unsigned long ul, scale;
  177. /* sign character */
  178. if (l < 0)
  179. {
  180. *ptr++ = '-';
  181. if (ptr >= ptrEnd)
  182. {
  183. break;
  184. }
  185. ul = -l;
  186. } else
  187. ul = l;
  188. // integer portion
  189. _ultoa(ul >> 8, achTmp, 10);
  190. KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
  191. ptr += UFLstrlen(ptr);
  192. if (ptr >= ptrEnd)
  193. {
  194. break;
  195. }
  196. // fraction
  197. ul &= 0xff;
  198. if (ul != 0)
  199. {
  200. // We output a maximum of 3 digits after the
  201. // decimal point, but we'll compute to the 5th
  202. // decimal point and round it to 3rd.
  203. ul = ((ul*100000 >> 8) + 50) / 100;
  204. scale = 100;
  205. *ptr++ = '.';
  206. do {
  207. if (ptr >= ptrEnd)
  208. {
  209. break;
  210. }
  211. *ptr++ = (char) (ul/scale + '0');
  212. ul %= scale;
  213. scale /= 10;
  214. } while (scale != 0 && ul != 0) ;
  215. }
  216. }
  217. break;
  218. default:
  219. if (*fmtstr != '\0')
  220. *ptr++ = *fmtstr;
  221. else
  222. {
  223. fmtstr--;
  224. }
  225. break;
  226. }
  227. /* Skip the type characterr */
  228. fmtstr++;
  229. }
  230. //
  231. // If we are beyond the end of dest buffer,
  232. // we need to go back so the dest buffer will
  233. // be null terminated.
  234. //
  235. if (ptr >= ptrEnd)
  236. {
  237. ptr = ptrEnd - 1;
  238. break;
  239. }
  240. }
  241. *ptr = '\0';
  242. return (int)(ptr - buf);
  243. }
  244. /*
  245. This is NOT a full implementation of "sprintf" as found
  246. in the C runtime library. Specifically, the only form of
  247. format specification allowed is %type, where "type" can
  248. be one of the following characters:
  249. d int signed decimal integer
  250. l long signed decimal integer
  251. ld long signed decimal integer
  252. lu unsigned long unsigned decimal integer
  253. u unsigned int unsigned decimal integer
  254. s char* character string
  255. c char character
  256. x,X unsigned long hex number (emits at least two digits, uppercase)
  257. b UFLBool boolean (true or false)
  258. f long 24.8 fixed-pointed number
  259. Normally, you should use UFLsprintf. Use this function
  260. only when you want to sprintf with %f in the form of 24.8 fixed point
  261. number.
  262. */
  263. int
  264. UFLsprintfEx(
  265. char *buf,
  266. size_t cchDest,
  267. const char *fmtstr,
  268. ...
  269. )
  270. {
  271. va_list arglist;
  272. int retval;
  273. va_start(arglist, fmtstr);
  274. retval = UFLvsprintf(buf, cchDest, fmtstr, arglist);
  275. va_end(arglist);
  276. return retval;
  277. }
  278. /****************************************************************************/
  279. #if defined(UNIX) || defined(MAC_ENV) /* Define needed functions */
  280. /****************************************************************************/
  281. char *_ltoa( long val, char *str, int radix )
  282. {
  283. /* This is the only supported radix: */
  284. assert( radix == 10 );
  285. sprintf( str, "%ld", val );
  286. return str;
  287. }
  288. char *_ultoa( unsigned long val, char *str, int radix )
  289. {
  290. /* This is the only supported radix: */
  291. assert( radix == 10 );
  292. sprintf( str, "%lu", val );
  293. return str;
  294. }
  295. #endif
  296. /****************************************************************************/
  297. #ifdef WIN32KERNEL
  298. /****************************************************************************/
  299. #include <stdio.h>
  300. int
  301. UFLsprintf(
  302. char *buf,
  303. size_t cchDest,
  304. const char *fmtstr,
  305. ...
  306. )
  307. {
  308. va_list arglist;
  309. int retval;
  310. va_start(arglist, fmtstr);
  311. retval = vsprintf(buf, fmtstr, arglist);
  312. va_end(arglist);
  313. return retval;
  314. }
  315. /***
  316. *strtol, strtoul(nptr,endptr,ibase) - Convert ascii string to long un/signed
  317. * int.
  318. *
  319. *Purpose:
  320. * Convert an ascii string to a long 32-bit value. The base
  321. * used for the caculations is supplied by the caller. The base
  322. * must be in the range 0, 2-36. If a base of 0 is supplied, the
  323. * ascii string must be examined to determine the base of the
  324. * number:
  325. * (a) First char = '0', second char = 'x' or 'X',
  326. * use base 16.
  327. * (b) First char = '0', use base 8
  328. * (c) First char in range '1' - '9', use base 10.
  329. *
  330. * If the 'endptr' value is non-NULL, then strtol/strtoul places
  331. * a pointer to the terminating character in this value.
  332. * See ANSI standard for details
  333. *
  334. *Entry:
  335. * nptr == NEAR/FAR pointer to the start of string.
  336. * endptr == NEAR/FAR pointer to the end of the string.
  337. * ibase == integer base to use for the calculations.
  338. *
  339. * string format: [whitespace] [sign] [0] [x] [digits/letters]
  340. *
  341. *Exit:
  342. * Good return:
  343. * result
  344. *
  345. * Overflow return:
  346. * strtol -- LONG_MAX or LONG_MIN
  347. * strtoul -- ULONG_MAX
  348. * strtol/strtoul -- errno == ERANGE
  349. *
  350. * No digits or bad base return:
  351. * 0
  352. * endptr = nptr*
  353. *
  354. *Exceptions:
  355. * None.
  356. *******************************************************************************/
  357. /* flag values */
  358. #include <limits.h>
  359. #include <errno.h>
  360. #define FL_UNSIGNED 1 /* strtoul called */
  361. #define FL_NEG 2 /* negative sign found */
  362. #define FL_OVERFLOW 4 /* overflow occured */
  363. #define FL_READDIGIT 8 /* we've read at least one correct digit */
  364. static unsigned long UFLstrtolx (
  365. const char *nptr,
  366. const char **endptr,
  367. int ibase,
  368. int flags
  369. )
  370. {
  371. const char *p;
  372. char c;
  373. unsigned long number;
  374. unsigned digval;
  375. unsigned long maxval;
  376. p = nptr; /* p is our scanning pointer */
  377. number = 0; /* start with zero */
  378. c = *p++; /* read char */
  379. while ( isspace((int)(unsigned char)c) )
  380. c = *p++; /* skip whitespace */
  381. if (c == '-') {
  382. flags |= FL_NEG; /* remember minus sign */
  383. c = *p++;
  384. }
  385. else if (c == '+')
  386. c = *p++; /* skip sign */
  387. if (ibase < 0 || ibase == 1 || ibase > 36) {
  388. /* bad base! */
  389. if (endptr)
  390. /* store beginning of string in endptr */
  391. *endptr = nptr;
  392. return 0L; /* return 0 */
  393. }
  394. else if (ibase == 0) {
  395. /* determine base free-lance, based on first two chars of
  396. string */
  397. if (c != '0')
  398. ibase = 10;
  399. else if (*p == 'x' || *p == 'X')
  400. ibase = 16;
  401. else
  402. ibase = 8;
  403. }
  404. if (ibase == 16) {
  405. /* we might have 0x in front of number; remove if there */
  406. if (c == '0' && (*p == 'x' || *p == 'X')) {
  407. ++p;
  408. c = *p++; /* advance past prefix */
  409. }
  410. }
  411. /* if our number exceeds this, we will overflow on multiply */
  412. maxval = ULONG_MAX / ibase;
  413. for (;;) { /* exit in middle of loop */
  414. /* convert c to value */
  415. if ( isdigit((int)(unsigned char)c) )
  416. digval = c - '0';
  417. else if ( isalpha((int)(unsigned char)c) )
  418. digval = toupper(c) - 'A' + 10;
  419. else
  420. break;
  421. if (digval >= (unsigned)ibase)
  422. break; /* exit loop if bad digit found */
  423. /* record the fact we have read one digit */
  424. flags |= FL_READDIGIT;
  425. /* we now need to compute number = number * base + digval,
  426. but we need to know if overflow occured. This requires
  427. a tricky pre-check. */
  428. if (number < maxval || (number == maxval &&
  429. (unsigned long)digval <= ULONG_MAX % ibase)) {
  430. /* we won't overflow, go ahead and multiply */
  431. number = number * ibase + digval;
  432. }
  433. else {
  434. /* we would have overflowed -- set the overflow flag */
  435. flags |= FL_OVERFLOW;
  436. }
  437. c = *p++; /* read next digit */
  438. }
  439. --p; /* point to place that stopped scan */
  440. if (!(flags & FL_READDIGIT)) {
  441. /* no number there; return 0 and point to beginning of
  442. string */
  443. if (endptr)
  444. /* store beginning of string in endptr later on */
  445. p = nptr;
  446. number = 0L; /* return 0 */
  447. }
  448. else if ( (flags & FL_OVERFLOW) ||
  449. ( !(flags & FL_UNSIGNED) &&
  450. ( ( (flags & FL_NEG) && (number > -LONG_MIN) ) ||
  451. ( !(flags & FL_NEG) && (number > LONG_MAX) ) ) ) )
  452. {
  453. /* overflow or signed overflow occurred */
  454. errno = ERANGE;
  455. if ( flags & FL_UNSIGNED )
  456. number = ULONG_MAX;
  457. else if ( flags & FL_NEG )
  458. number = (unsigned long)(-LONG_MIN);
  459. else
  460. number = LONG_MAX;
  461. }
  462. if (endptr != NULL)
  463. /* store pointer to char that stopped the scan */
  464. *endptr = p;
  465. if (flags & FL_NEG)
  466. /* negate result if there was a neg sign */
  467. number = (unsigned long)(-(long)number);
  468. return number; /* done. */
  469. }
  470. long UFLstrtol (
  471. const char *nptr,
  472. char **endptr,
  473. int ibase
  474. )
  475. {
  476. return (long) UFLstrtolx(nptr, endptr, ibase, 0);
  477. }
  478. #endif // ifdef WIN32KERNEL
  479. #ifdef __cplusplus
  480. }
  481. #endif