FormatUtil.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: FormatUtil.c /main/9 1996/11/01 10:12:14 drk $ */
  24. /************************************<+>*************************************
  25. ****************************************************************************
  26. **
  27. ** File: FormatUtil.c
  28. **
  29. ** Project: Text Graphic Display Library
  30. **
  31. **
  32. ** Description: Semi private format utility functions that do not
  33. ** require the Display Area, Motif, Xt or X11.
  34. **
  35. **
  36. ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
  37. **
  38. ** (c) Copyright 1993, 1994 Hewlett-Packard Company
  39. ** (c) Copyright 1993, 1994 International Business Machines Corp.
  40. ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  41. ** (c) Copyright 1993, 1994 Novell, Inc.
  42. **
  43. **
  44. ****************************************************************************
  45. ************************************<+>*************************************/
  46. /*
  47. * system includes
  48. */
  49. #include <ctype.h>
  50. #include <errno.h>
  51. #include <limits.h>
  52. #include <locale.h>
  53. #include <stdlib.h>
  54. #include <stdio.h>
  55. #include <string.h>
  56. #include <time.h>
  57. #include <X11/Xos.h>
  58. #ifdef X_NOT_STDC_ENV
  59. extern int errno;
  60. #endif
  61. /*
  62. * Canvas Engine includes
  63. */
  64. #include "CanvasP.h"
  65. #include "CanvasSegP.h"
  66. /*
  67. * private includes
  68. */
  69. #include "CanvasError.h"
  70. #include "bufioI.h"
  71. #include "FormatUtilI.h"
  72. #if defined(NLS16) || !defined(NO_MESSAGE_CATALOG)
  73. #include <Dt/MsgCatP.h>
  74. #endif
  75. #ifndef NL_CAT_LOCALE
  76. static const int NL_CAT_LOCALE = 0;
  77. #endif
  78. /******** Private Function Declarations ********/
  79. /******** End Private Function Declarations ********/
  80. /******************************************************************************
  81. *
  82. * Private variables and defines.
  83. *
  84. *****************************************************************************/
  85. #define GROW_SIZE 5
  86. /******************************************************************************
  87. *
  88. * Private Functions
  89. *
  90. *****************************************************************************/
  91. /******************************************************************************
  92. *
  93. * Semi Public Functions
  94. *
  95. *****************************************************************************/
  96. /******************************************************************************
  97. * Function: int _DtHelpCeAddOctalToBuf (char *src, char **dst,
  98. * int *dst_size,
  99. * int *dst_max, int grow_size)
  100. *
  101. * Parameters:
  102. * src Specifies a pointer to a string.
  103. * dst Specifies a pointer to the buffer to
  104. * to hold the information.
  105. * dst_size Specifies the current size of 'dst'.
  106. * Returns the new size of 'dst'.
  107. * dst_max Specifies the current maximum size of 'dst'.
  108. * Returns the new maximum size of 'dst'.
  109. * grow_size Specifies the minimum grow size of 'dst'
  110. * when a malloc/realloc occurs.
  111. * If this is less than one, 'dst' will
  112. * grow only large enough to hold
  113. * the new character.
  114. *
  115. * Returns: 0 if successful, -1 if errors.
  116. *
  117. * errno Values:
  118. * EINVAL
  119. * CEErrorMalloc
  120. *
  121. * Purpose: (Re-)Allocates, if necessary, enough memory to hold the old
  122. * information plus the byte.
  123. * Coverts the 0xXX value pointed to by src to a 0-256 by value.
  124. * Appends the character to the buffer pointed to 'dst'.
  125. * Updates 'dst_size' to include the new character.
  126. * Updates 'dst_max' to the new size of 'dst' if a
  127. * malloc/realloc occurred.
  128. *
  129. *****************************************************************************/
  130. int
  131. _DtHelpCeAddOctalToBuf(
  132. char *src,
  133. char **dst,
  134. int *dst_size,
  135. int *dst_max,
  136. int grow_size )
  137. {
  138. char tmp;
  139. char *dstPtr;
  140. unsigned long value;
  141. if (src == NULL ||
  142. dst == NULL || dst_size == NULL || dst_max == NULL ||
  143. (*dst == NULL && (*dst_size || *dst_max)))
  144. {
  145. errno = EINVAL;
  146. return -1;
  147. }
  148. dstPtr = *dst;
  149. if ((*dst_size + 2) >= *dst_max)
  150. {
  151. if (grow_size > *dst_size + 3 - *dst_max)
  152. *dst_max = *dst_max + grow_size;
  153. else
  154. *dst_max = *dst_size + 3;
  155. if (dstPtr)
  156. dstPtr = (char *) realloc ((void *) dstPtr, *dst_max);
  157. else
  158. {
  159. dstPtr = (char *) malloc (sizeof(char) * (*dst_max));
  160. *dst_size = 0;
  161. }
  162. *dst = dstPtr;
  163. }
  164. /*
  165. * check to see if we have good memory
  166. */
  167. if (!dstPtr)
  168. {
  169. errno = CEErrorMalloc;
  170. return -1;
  171. }
  172. tmp = src[4];
  173. src[4] = '\0';
  174. value = strtoul (src, NULL, 16);
  175. src[4] = tmp;
  176. if ((value == ULONG_MAX && errno == ERANGE) || value > 255 || value < 1)
  177. {
  178. errno = CEErrorFormattingValue;
  179. return -1;
  180. }
  181. /*
  182. * copy the source into the destination
  183. */
  184. dstPtr[*dst_size] = (char ) value;
  185. /*
  186. * adjust the pointers.
  187. */
  188. *dst_size = *dst_size + 1;
  189. /*
  190. * null the end of the buffer.
  191. */
  192. dstPtr[*dst_size] = '\0';
  193. return 0;
  194. }
  195. /******************************************************************************
  196. * Function: int __CEAppendCharToInfo (char **src, char **dst, int *dst_size,
  197. * int *dst_max, int grow_size)
  198. *
  199. * Parameters:
  200. * src Specifies a pointer to a string.
  201. * dst Specifies a pointer to the buffer to
  202. * to hold the information.
  203. * dst_size Specifies the current size of 'dst'.
  204. * Returns the new size of 'dst'.
  205. * dst_max Specifies the current maximum size of 'dst'.
  206. * Returns the new maximum size of 'dst'.
  207. * grow_size Specifies the minimum grow size of 'dst'
  208. * when a malloc/realloc occurs.
  209. * If this is less than one, 'dst' will
  210. * grow only large enough to hold
  211. * the new character.
  212. *
  213. * Returns: 0 if successful, -1 if errors.
  214. *
  215. * errno Values:
  216. * EINVAL
  217. * CEErrorMalloc
  218. *
  219. * Purpose: (Re-)Allocates, if necessary, enough memory to hold the old
  220. * information plus the new.
  221. * Appends the character pointed to by 'src' to the buffer
  222. * pointed to 'dst'.
  223. * Updates 'src' to point to the next character after the
  224. * one appended to 'dst'.
  225. * Updates 'dst_size' to include the new character.
  226. * Updates 'dst_max' to the new size of 'dst' if a
  227. * malloc/realloc occurred.
  228. *
  229. *****************************************************************************/
  230. int
  231. _DtHelpCeAddCharToBuf(
  232. char **src,
  233. char **dst,
  234. int *dst_size,
  235. int *dst_max,
  236. int grow_size )
  237. {
  238. char *srcPtr;
  239. char *dstPtr;
  240. if (src == NULL || *src == NULL ||
  241. dst == NULL || dst_size == NULL || dst_max == NULL ||
  242. (*dst == NULL && (*dst_size || *dst_max)))
  243. {
  244. errno = EINVAL;
  245. return -1;
  246. }
  247. srcPtr = *src;
  248. dstPtr = *dst;
  249. if ((*dst_size + 2) >= *dst_max)
  250. {
  251. if (grow_size > *dst_size + 3 - *dst_max)
  252. *dst_max = *dst_max + grow_size;
  253. else
  254. *dst_max = *dst_size + 3;
  255. if (dstPtr)
  256. dstPtr = (char *) realloc ((void *) dstPtr, *dst_max);
  257. else
  258. {
  259. dstPtr = (char *) malloc (*dst_max);
  260. *dst_size = 0;
  261. }
  262. *dst = dstPtr;
  263. }
  264. /*
  265. * check to see if we have good memory
  266. */
  267. if (!dstPtr)
  268. {
  269. errno = CEErrorMalloc;
  270. return -1;
  271. }
  272. /*
  273. * copy the source into the destination
  274. */
  275. dstPtr[*dst_size] = *srcPtr++;
  276. /*
  277. * adjust the pointers.
  278. */
  279. *src = srcPtr;
  280. *dst_size = *dst_size + 1;
  281. /*
  282. * null the end of the buffer.
  283. */
  284. dstPtr[*dst_size] = '\0';
  285. return 0;
  286. }
  287. /******************************************************************************
  288. * Function: int _DtHelpCeAddStrToBuf (char **src, char **dst, int *dst_size,
  289. * int *dst_max, int copy_size, int grow_size)
  290. *
  291. * Parameters:
  292. * src Specifies a pointer to a string.
  293. * dst Specifies a pointer to the buffer to
  294. * to hold the information.
  295. * dst_size Specifies the current size of 'dst'.
  296. * Returns the new size of 'dst'.
  297. * dst_max Specifies the current maximum size of 'dst'.
  298. * Returns the new maximum size of 'dst'.
  299. * copy_size Specifies the number of characters to
  300. * copy from 'src' to 'dst'.
  301. * grow_size Specifies the minimum grow size of 'dst'
  302. * when a malloc/realloc occurs.
  303. * If this is less than one, 'dst' will
  304. * grow only large enough to hold
  305. * the new character.
  306. *
  307. * Returns: 0 if successful, -1 if errors.
  308. *
  309. * errno Values:
  310. * EINVAL
  311. * CEErrorMalloc
  312. *
  313. * Purpose: Copys 'copy_size' number of characters of 'src'
  314. * to 'dst'.
  315. * Updates 'src', to point after 'copy_size' number of
  316. * characters.
  317. * Updates the 'dst_size' to reflect the number of characters
  318. * copied.
  319. * If required, increments dst_max and (re)allocs memory
  320. * to hold the extra 'copy_size' number of characters.
  321. *
  322. *****************************************************************************/
  323. int
  324. _DtHelpCeAddStrToBuf (
  325. char **src,
  326. char **dst,
  327. int *dst_size,
  328. int *dst_max,
  329. int copy_size,
  330. int grow_size )
  331. {
  332. char *srcPtr;
  333. char *dstPtr;
  334. /*
  335. * check the input
  336. */
  337. if (src == NULL || *src == NULL || (((int)strlen(*src)) < copy_size)
  338. || dst == NULL || dst_size == NULL || dst_max == NULL
  339. || (*dst == NULL && (*dst_size || *dst_max)))
  340. {
  341. errno = EINVAL;
  342. return -1;
  343. }
  344. srcPtr = *src;
  345. dstPtr = *dst;
  346. if ((*dst_size + copy_size + 1) >= *dst_max)
  347. {
  348. if (grow_size > (*dst_size + copy_size + 2 - *dst_max))
  349. *dst_max = *dst_max + grow_size;
  350. else
  351. *dst_max = *dst_size + copy_size + 2;
  352. if (dstPtr)
  353. dstPtr = (char *) realloc ((void *) dstPtr, *dst_max);
  354. else
  355. {
  356. dstPtr = (char *) malloc (*dst_max);
  357. *dst_size = 0;
  358. }
  359. *dst = dstPtr;
  360. }
  361. if (!dstPtr)
  362. {
  363. errno = CEErrorMalloc;
  364. return -1;
  365. }
  366. /*
  367. * make sure there is a null byte to append to.
  368. */
  369. dstPtr[*dst_size] = '\0';
  370. /*
  371. * copy the source into the destination
  372. */
  373. strncat (dstPtr, srcPtr, copy_size);
  374. /*
  375. * adjust the pointers
  376. */
  377. *src = srcPtr + copy_size;
  378. *dst_size = *dst_size + copy_size;
  379. return 0;
  380. }
  381. /******************************************************************************
  382. * Function: int _DtHelpCeGetNxtBuf (FILE *file, char *dst, char **src,
  383. * int max_size)
  384. *
  385. * Parameters:
  386. * file Specifies a stream to read from.
  387. * dst Specifies the buffer where new information
  388. * is placed.
  389. * src Specifies a pointer into 'dst'. If there
  390. * is information left over, it
  391. * is moved to the begining of 'dst'.
  392. * Returns 'src' pointing to 'dst'.
  393. * max_size Specifies the maximum size of 'dst'.
  394. *
  395. * Returns: 0 if this is the last buffer that can be read for the topic.
  396. * -1 if errors.
  397. * >0 if more to be read.
  398. *
  399. * errno Values:
  400. * read (2) Errors set via a read call.
  401. * EINVAL
  402. * CEErrorReadEmpty
  403. *
  404. * Purpose: Reads the next buffer of information.
  405. *
  406. *****************************************************************************/
  407. int
  408. _DtHelpCeGetNxtBuf(
  409. BufFilePtr file,
  410. char *dst,
  411. char **src,
  412. int max_size)
  413. {
  414. int leftOver;
  415. int result;
  416. if (file == NULL)
  417. {
  418. errno = EINVAL;
  419. return -1;
  420. }
  421. (void ) strcpy (dst, (*src));
  422. leftOver = strlen (dst);
  423. result = _DtHelpCeReadBuf (file, &(dst[leftOver]), (max_size - leftOver));
  424. /*
  425. * check to see if we ran into trouble reading this buffer
  426. * of information. If not reset the pointer to the beginning
  427. * of the buffer.
  428. */
  429. if (result != -1)
  430. *src = dst;
  431. return result;
  432. }
  433. /******************************************************************************
  434. * Function: int _DtHelpCeReadBuf (FILE *file, char *buffer, int size)
  435. *
  436. * Parameters: FILE Specifies the stream to read from.
  437. * buffer Specifies a buffer to read information
  438. * into.
  439. * size Specifies the maximum number of bytes
  440. * 'buffer' can contain. It should never be
  441. * larger than 'buffer' can hold, but it can
  442. * be smaller.
  443. *
  444. * Returns: 0 if this is the last buffer that can be read for the topic.
  445. * -1 if errors.
  446. * >0 if more to be read.
  447. *
  448. * errno Values:
  449. * read (2) Errors set via a read call.
  450. *
  451. * Purpose: Get size-1 number of bytes into a buffer and possibly
  452. * check for page markers imbedded within the text.
  453. *
  454. *****************************************************************************/
  455. int
  456. _DtHelpCeReadBuf(
  457. BufFilePtr file,
  458. char *buffer,
  459. int size)
  460. {
  461. int flag;
  462. /*
  463. * take into account the last byte must be an end of string marker.
  464. */
  465. size--;
  466. flag = _DtHelpCeBufFileRd(file, buffer, size);
  467. if (flag != -1)
  468. buffer[flag] = '\0';
  469. return flag;
  470. } /* End _DtHelpCeReadBuf */
  471. /******************************************************************************
  472. * Function: char *_DtHelpGetNxtToken (char *str, char **retToken)
  473. *
  474. * Parameters:
  475. * str The string (in memory) which is being
  476. * parsed.
  477. * retToken Returns the next token from the input.
  478. * Valid tokens are strings of non-whitespace
  479. * characters, newline ("\n"), and
  480. * end-of-data (indicated by a zero length
  481. * string).
  482. *
  483. * A NULL value indicates an error.
  484. *
  485. * Newline or zero length strings are
  486. * not owned by the caller.
  487. *
  488. * Otherwise, the memory for the returned
  489. * token is owned by the caller.
  490. *
  491. * Return Value: Returns the pointer to the next unparsed character in
  492. * the input string. A NULL value indicates an error.
  493. *
  494. * errno Values:
  495. * EINVAL
  496. * CEErrorMalloc
  497. *
  498. * Purpose: Parse tokens in resource string values.
  499. *
  500. *****************************************************************************/
  501. char *
  502. _DtHelpGetNxtToken (
  503. char *str,
  504. char **retToken)
  505. {
  506. int len = 1;
  507. char *start;
  508. char *token;
  509. short quote = False;
  510. short done = False;
  511. if (retToken) *retToken = NULL; /* tested in caller code */
  512. if (str == NULL || *str == '\0' || retToken == NULL)
  513. {
  514. errno = EINVAL;
  515. return NULL;
  516. }
  517. /* Find the next token in the string. The parsing rules are:
  518. - Whitespace (except for \n) separates tokens.
  519. - \n is a token itself.
  520. - The \0 at the end of the string is a token.
  521. */
  522. /* Skip all of the whitespace (except for \n). */
  523. while (*str && (*str != '\n') && isspace (*str))
  524. str++;
  525. /* Str is pointing at the start of the next token. Depending on the
  526. type of token, malloc the memory and copy the token value. */
  527. if (*str == '\0')
  528. token = strdup(str);
  529. else if (*str == '\n') {
  530. token = strdup(str);
  531. str++;
  532. }
  533. else {
  534. /* We have some non-whitespace characters. Find the end of */
  535. /* them and copy them into new memory. */
  536. if ((MB_CUR_MAX == 1 || mblen (str, MB_CUR_MAX) == 1) && *str == '\"')
  537. {
  538. /*
  539. * found a quoted token - skip the quote.
  540. */
  541. quote = True;
  542. str++;
  543. }
  544. start = str;
  545. while (*str && !done)
  546. {
  547. /*
  548. * get the length of the item.
  549. */
  550. len = 1;
  551. if (MB_CUR_MAX != 1)
  552. {
  553. len = mblen (str, MB_CUR_MAX);
  554. if (len < 0)
  555. len = 1;
  556. }
  557. if (len == 1)
  558. {
  559. /*
  560. * check for the token terminator
  561. */
  562. if ((quote && *str == '\"') ||
  563. (!quote && (isspace (*str) || *str == '\n')))
  564. done = True;
  565. else
  566. str++;
  567. }
  568. else
  569. str += len;
  570. }
  571. /*
  572. * determine the length of the token.
  573. */
  574. token = (char *) malloc ((str - start + 1) * sizeof (char));
  575. if (token)
  576. {
  577. strncpy (token, start, str - start);
  578. *(token + (str - start)) = '\0';
  579. }
  580. else
  581. errno = CEErrorMalloc;
  582. /*
  583. * skip the quote terminator
  584. */
  585. if (quote && len == 1 && *str == '\"')
  586. str++;
  587. }
  588. *retToken = token;
  589. return (str);
  590. }
  591. /******************************************************************************
  592. * Function: _DtCvSegment *_DtHelpAllocateSegments(int malloc_size)
  593. *
  594. * Parameters:
  595. * malloc_size Specifies the number of segments to
  596. * allocate if 'alloc_size' is NULL or less
  597. * than 1 or if '*next_seg' is NULL. The
  598. * first one is returned to the caller with
  599. * the rest in 'next_seg' if 'next_seg' is
  600. * non-NULL.
  601. *
  602. * Return Value:
  603. * non-null If succeeds.
  604. * Null If failure.
  605. *
  606. * Purpose: Allocate a block of segments, zeros the structures, and
  607. * sets the link_idx of each structure to -1.
  608. *
  609. *****************************************************************************/
  610. _DtCvSegment *
  611. _DtHelpAllocateSegments (
  612. int malloc_size)
  613. {
  614. int i;
  615. _DtCvSegment *newSeg;
  616. FrmtPrivateInfo *p;
  617. /*
  618. * don't allow zero or negative allocations
  619. */
  620. if (malloc_size < 1)
  621. malloc_size = 1;
  622. /*
  623. * allocate the block of segments
  624. */
  625. newSeg = (_DtCvSegment *) calloc (sizeof(_DtCvSegment), malloc_size);
  626. if (NULL != newSeg)
  627. {
  628. /*
  629. * now allocate the same number of private information structures
  630. */
  631. p = (FrmtPrivateInfo *) calloc (sizeof(FrmtPrivateInfo), malloc_size);
  632. if (NULL != p)
  633. {
  634. /*
  635. * mark the first item as the top block. Since it will be
  636. * attached to the first segment, it marks both the segment
  637. * and the private information blocks for later frees.
  638. */
  639. p->top_block = True;
  640. for (i = 0; i < malloc_size; i++)
  641. {
  642. /*
  643. * invalidate the link index and attach a private
  644. * information structure to each segment
  645. */
  646. newSeg[i].link_idx = -1;
  647. newSeg[i].client_use = p++;
  648. }
  649. }
  650. else
  651. {
  652. /*
  653. * had trouble allocating the private information.
  654. * free the new segment list and return NULL as an error.
  655. */
  656. free(newSeg);
  657. newSeg = NULL;
  658. }
  659. }
  660. return newSeg;
  661. }
  662. /******************************************************************************
  663. * Function: int _DtHelpFmtFindBreak (char *ptr, int mb_len, int *num_chars)
  664. *
  665. * Parameters:
  666. * ptr Specifies the string to check.
  667. * mb_len Specifies if the sequence should be single
  668. * byte or multi-byte.
  669. * num_chars Returns the character count.
  670. *
  671. * Returns number of bytes in the sequence.
  672. *
  673. * errno Values:
  674. *
  675. * Purpose: Find a length of 'ptr' comprised of multi or single byte
  676. * characters.
  677. *
  678. *****************************************************************************/
  679. int
  680. _DtHelpFmtFindBreak (
  681. char *ptr,
  682. int mb_len,
  683. int *num_chars)
  684. {
  685. int len = 0;
  686. int numChars = 0;
  687. int mySize;
  688. short done = 0;
  689. while (0 == done && '\0' != *ptr)
  690. {
  691. mySize = mblen(ptr, MB_CUR_MAX);
  692. done = 1;
  693. if (0 < mySize &&
  694. ((1 != mb_len && 1 != mySize) || (1 == mb_len && 1 == mySize)))
  695. {
  696. numChars++;
  697. ptr += mySize;
  698. len += mySize;
  699. done = 0;
  700. }
  701. }
  702. *num_chars = numChars;
  703. return len;
  704. }
  705. /******************************************************************************
  706. * Function: _DtHelpLoadMultiInfo
  707. *
  708. * Returns: Loads the multi-byte formatting table for the current locale.
  709. *
  710. *****************************************************************************/
  711. void
  712. _DtHelpLoadMultiInfo (
  713. wchar_t **cant_begin_chars,
  714. wchar_t **cant_end_chars,
  715. short *nl_to_space)
  716. {
  717. #ifndef NO_MESSAGE_CATALOG
  718. int len;
  719. char *ptr;
  720. nl_catd cat_fd;
  721. cat_fd = CATOPEN("fmt_tbl", NL_CAT_LOCALE);
  722. if (cat_fd != ((nl_catd) -1))
  723. {
  724. /*
  725. * Get the list of characters that can't begin a line.
  726. */
  727. ptr = CATGETS(cat_fd, 1, 1, "");
  728. len = strlen (ptr) + 1;
  729. *cant_begin_chars = (wchar_t *) malloc (len * sizeof (wchar_t));
  730. if (NULL != *cant_begin_chars &&
  731. mbstowcs(*cant_begin_chars, ptr, len) == -1)
  732. {
  733. free (*cant_begin_chars);
  734. *cant_begin_chars = NULL;
  735. }
  736. /*
  737. * Get the list of characters that can't end a line.
  738. */
  739. ptr = CATGETS(cat_fd, 1, 2, "");
  740. len = strlen (ptr) + 1;
  741. *cant_end_chars = (wchar_t *) malloc (len * sizeof (wchar_t));
  742. if (*cant_end_chars != NULL &&
  743. mbstowcs(*cant_end_chars, ptr, len) == -1)
  744. {
  745. free (*cant_end_chars);
  746. *cant_end_chars = NULL;
  747. }
  748. /*
  749. * Get the spacing flag. I.E. when does a internal newline
  750. * get turned into a space.
  751. * 1 means all the time.
  752. * 0 means only between a multibyte string and
  753. * a singlebyte string.
  754. */
  755. ptr = CATGETS(cat_fd, 1, 3, "1");
  756. *nl_to_space = atoi(ptr);
  757. CATCLOSE(cat_fd);
  758. }
  759. else
  760. #endif
  761. {
  762. *cant_begin_chars = NULL;
  763. *cant_end_chars = NULL;
  764. *nl_to_space = 1;
  765. }
  766. }