123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: FormatUtil.c /main/9 1996/11/01 10:12:14 drk $ */
- /************************************<+>*************************************
- ****************************************************************************
- **
- ** File: FormatUtil.c
- **
- ** Project: Text Graphic Display Library
- **
- **
- ** Description: Semi private format utility functions that do not
- ** require the Display Area, Motif, Xt or X11.
- **
- **
- ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
- **
- ** (c) Copyright 1993, 1994 Hewlett-Packard Company
- ** (c) Copyright 1993, 1994 International Business Machines Corp.
- ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
- ** (c) Copyright 1993, 1994 Novell, Inc.
- **
- **
- ****************************************************************************
- ************************************<+>*************************************/
- /*
- * system includes
- */
- #include <ctype.h>
- #include <errno.h>
- #include <limits.h>
- #include <locale.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <X11/Xos.h>
- #ifdef X_NOT_STDC_ENV
- extern int errno;
- #endif
- /*
- * Canvas Engine includes
- */
- #include "CanvasP.h"
- #include "CanvasSegP.h"
- /*
- * private includes
- */
- #include "CanvasError.h"
- #include "bufioI.h"
- #include "FormatUtilI.h"
- #if defined(NLS16) || !defined(NO_MESSAGE_CATALOG)
- #include <Dt/MsgCatP.h>
- #endif
- #ifndef NL_CAT_LOCALE
- static const int NL_CAT_LOCALE = 0;
- #endif
- /******** Private Function Declarations ********/
- /******** End Private Function Declarations ********/
- /******************************************************************************
- *
- * Private variables and defines.
- *
- *****************************************************************************/
- #define GROW_SIZE 5
- /******************************************************************************
- *
- * Private Functions
- *
- *****************************************************************************/
- /******************************************************************************
- *
- * Semi Public Functions
- *
- *****************************************************************************/
- /******************************************************************************
- * Function: int _DtHelpCeAddOctalToBuf (char *src, char **dst,
- * int *dst_size,
- * int *dst_max, int grow_size)
- *
- * Parameters:
- * src Specifies a pointer to a string.
- * dst Specifies a pointer to the buffer to
- * to hold the information.
- * dst_size Specifies the current size of 'dst'.
- * Returns the new size of 'dst'.
- * dst_max Specifies the current maximum size of 'dst'.
- * Returns the new maximum size of 'dst'.
- * grow_size Specifies the minimum grow size of 'dst'
- * when a malloc/realloc occurs.
- * If this is less than one, 'dst' will
- * grow only large enough to hold
- * the new character.
- *
- * Returns: 0 if successful, -1 if errors.
- *
- * errno Values:
- * EINVAL
- * CEErrorMalloc
- *
- * Purpose: (Re-)Allocates, if necessary, enough memory to hold the old
- * information plus the byte.
- * Coverts the 0xXX value pointed to by src to a 0-256 by value.
- * Appends the character to the buffer pointed to 'dst'.
- * Updates 'dst_size' to include the new character.
- * Updates 'dst_max' to the new size of 'dst' if a
- * malloc/realloc occurred.
- *
- *****************************************************************************/
- int
- _DtHelpCeAddOctalToBuf(
- char *src,
- char **dst,
- int *dst_size,
- int *dst_max,
- int grow_size )
- {
- char tmp;
- char *dstPtr;
- unsigned long value;
- if (src == NULL ||
- dst == NULL || dst_size == NULL || dst_max == NULL ||
- (*dst == NULL && (*dst_size || *dst_max)))
- {
- errno = EINVAL;
- return -1;
- }
- dstPtr = *dst;
- if ((*dst_size + 2) >= *dst_max)
- {
- if (grow_size > *dst_size + 3 - *dst_max)
- *dst_max = *dst_max + grow_size;
- else
- *dst_max = *dst_size + 3;
- if (dstPtr)
- dstPtr = (char *) realloc ((void *) dstPtr, *dst_max);
- else
- {
- dstPtr = (char *) malloc (sizeof(char) * (*dst_max));
- *dst_size = 0;
- }
- *dst = dstPtr;
- }
- /*
- * check to see if we have good memory
- */
- if (!dstPtr)
- {
- errno = CEErrorMalloc;
- return -1;
- }
- tmp = src[4];
- src[4] = '\0';
- value = strtoul (src, NULL, 16);
- src[4] = tmp;
- if ((value == ULONG_MAX && errno == ERANGE) || value > 255 || value < 1)
- {
- errno = CEErrorFormattingValue;
- return -1;
- }
- /*
- * copy the source into the destination
- */
- dstPtr[*dst_size] = (char ) value;
- /*
- * adjust the pointers.
- */
- *dst_size = *dst_size + 1;
- /*
- * null the end of the buffer.
- */
- dstPtr[*dst_size] = '\0';
- return 0;
- }
- /******************************************************************************
- * Function: int __CEAppendCharToInfo (char **src, char **dst, int *dst_size,
- * int *dst_max, int grow_size)
- *
- * Parameters:
- * src Specifies a pointer to a string.
- * dst Specifies a pointer to the buffer to
- * to hold the information.
- * dst_size Specifies the current size of 'dst'.
- * Returns the new size of 'dst'.
- * dst_max Specifies the current maximum size of 'dst'.
- * Returns the new maximum size of 'dst'.
- * grow_size Specifies the minimum grow size of 'dst'
- * when a malloc/realloc occurs.
- * If this is less than one, 'dst' will
- * grow only large enough to hold
- * the new character.
- *
- * Returns: 0 if successful, -1 if errors.
- *
- * errno Values:
- * EINVAL
- * CEErrorMalloc
- *
- * Purpose: (Re-)Allocates, if necessary, enough memory to hold the old
- * information plus the new.
- * Appends the character pointed to by 'src' to the buffer
- * pointed to 'dst'.
- * Updates 'src' to point to the next character after the
- * one appended to 'dst'.
- * Updates 'dst_size' to include the new character.
- * Updates 'dst_max' to the new size of 'dst' if a
- * malloc/realloc occurred.
- *
- *****************************************************************************/
- int
- _DtHelpCeAddCharToBuf(
- char **src,
- char **dst,
- int *dst_size,
- int *dst_max,
- int grow_size )
- {
- char *srcPtr;
- char *dstPtr;
- if (src == NULL || *src == NULL ||
- dst == NULL || dst_size == NULL || dst_max == NULL ||
- (*dst == NULL && (*dst_size || *dst_max)))
- {
- errno = EINVAL;
- return -1;
- }
- srcPtr = *src;
- dstPtr = *dst;
- if ((*dst_size + 2) >= *dst_max)
- {
- if (grow_size > *dst_size + 3 - *dst_max)
- *dst_max = *dst_max + grow_size;
- else
- *dst_max = *dst_size + 3;
- if (dstPtr)
- dstPtr = (char *) realloc ((void *) dstPtr, *dst_max);
- else
- {
- dstPtr = (char *) malloc (*dst_max);
- *dst_size = 0;
- }
- *dst = dstPtr;
- }
- /*
- * check to see if we have good memory
- */
- if (!dstPtr)
- {
- errno = CEErrorMalloc;
- return -1;
- }
- /*
- * copy the source into the destination
- */
- dstPtr[*dst_size] = *srcPtr++;
- /*
- * adjust the pointers.
- */
- *src = srcPtr;
- *dst_size = *dst_size + 1;
- /*
- * null the end of the buffer.
- */
- dstPtr[*dst_size] = '\0';
- return 0;
- }
- /******************************************************************************
- * Function: int _DtHelpCeAddStrToBuf (char **src, char **dst, int *dst_size,
- * int *dst_max, int copy_size, int grow_size)
- *
- * Parameters:
- * src Specifies a pointer to a string.
- * dst Specifies a pointer to the buffer to
- * to hold the information.
- * dst_size Specifies the current size of 'dst'.
- * Returns the new size of 'dst'.
- * dst_max Specifies the current maximum size of 'dst'.
- * Returns the new maximum size of 'dst'.
- * copy_size Specifies the number of characters to
- * copy from 'src' to 'dst'.
- * grow_size Specifies the minimum grow size of 'dst'
- * when a malloc/realloc occurs.
- * If this is less than one, 'dst' will
- * grow only large enough to hold
- * the new character.
- *
- * Returns: 0 if successful, -1 if errors.
- *
- * errno Values:
- * EINVAL
- * CEErrorMalloc
- *
- * Purpose: Copys 'copy_size' number of characters of 'src'
- * to 'dst'.
- * Updates 'src', to point after 'copy_size' number of
- * characters.
- * Updates the 'dst_size' to reflect the number of characters
- * copied.
- * If required, increments dst_max and (re)allocs memory
- * to hold the extra 'copy_size' number of characters.
- *
- *****************************************************************************/
- int
- _DtHelpCeAddStrToBuf (
- char **src,
- char **dst,
- int *dst_size,
- int *dst_max,
- int copy_size,
- int grow_size )
- {
- char *srcPtr;
- char *dstPtr;
- /*
- * check the input
- */
- if (src == NULL || *src == NULL || (((int)strlen(*src)) < copy_size)
- || dst == NULL || dst_size == NULL || dst_max == NULL
- || (*dst == NULL && (*dst_size || *dst_max)))
- {
- errno = EINVAL;
- return -1;
- }
- srcPtr = *src;
- dstPtr = *dst;
- if ((*dst_size + copy_size + 1) >= *dst_max)
- {
- if (grow_size > (*dst_size + copy_size + 2 - *dst_max))
- *dst_max = *dst_max + grow_size;
- else
- *dst_max = *dst_size + copy_size + 2;
- if (dstPtr)
- dstPtr = (char *) realloc ((void *) dstPtr, *dst_max);
- else
- {
- dstPtr = (char *) malloc (*dst_max);
- *dst_size = 0;
- }
- *dst = dstPtr;
- }
- if (!dstPtr)
- {
- errno = CEErrorMalloc;
- return -1;
- }
- /*
- * make sure there is a null byte to append to.
- */
- dstPtr[*dst_size] = '\0';
- /*
- * copy the source into the destination
- */
- strncat (dstPtr, srcPtr, copy_size);
- /*
- * adjust the pointers
- */
- *src = srcPtr + copy_size;
- *dst_size = *dst_size + copy_size;
- return 0;
- }
- /******************************************************************************
- * Function: int _DtHelpCeGetNxtBuf (FILE *file, char *dst, char **src,
- * int max_size)
- *
- * Parameters:
- * file Specifies a stream to read from.
- * dst Specifies the buffer where new information
- * is placed.
- * src Specifies a pointer into 'dst'. If there
- * is information left over, it
- * is moved to the begining of 'dst'.
- * Returns 'src' pointing to 'dst'.
- * max_size Specifies the maximum size of 'dst'.
- *
- * Returns: 0 if this is the last buffer that can be read for the topic.
- * -1 if errors.
- * >0 if more to be read.
- *
- * errno Values:
- * read (2) Errors set via a read call.
- * EINVAL
- * CEErrorReadEmpty
- *
- * Purpose: Reads the next buffer of information.
- *
- *****************************************************************************/
- int
- _DtHelpCeGetNxtBuf(
- BufFilePtr file,
- char *dst,
- char **src,
- int max_size)
- {
- int leftOver;
- int result;
- if (file == NULL)
- {
- errno = EINVAL;
- return -1;
- }
- (void ) strcpy (dst, (*src));
- leftOver = strlen (dst);
- result = _DtHelpCeReadBuf (file, &(dst[leftOver]), (max_size - leftOver));
- /*
- * check to see if we ran into trouble reading this buffer
- * of information. If not reset the pointer to the beginning
- * of the buffer.
- */
- if (result != -1)
- *src = dst;
- return result;
- }
- /******************************************************************************
- * Function: int _DtHelpCeReadBuf (FILE *file, char *buffer, int size)
- *
- * Parameters: FILE Specifies the stream to read from.
- * buffer Specifies a buffer to read information
- * into.
- * size Specifies the maximum number of bytes
- * 'buffer' can contain. It should never be
- * larger than 'buffer' can hold, but it can
- * be smaller.
- *
- * Returns: 0 if this is the last buffer that can be read for the topic.
- * -1 if errors.
- * >0 if more to be read.
- *
- * errno Values:
- * read (2) Errors set via a read call.
- *
- * Purpose: Get size-1 number of bytes into a buffer and possibly
- * check for page markers imbedded within the text.
- *
- *****************************************************************************/
- int
- _DtHelpCeReadBuf(
- BufFilePtr file,
- char *buffer,
- int size)
- {
- int flag;
- /*
- * take into account the last byte must be an end of string marker.
- */
- size--;
- flag = _DtHelpCeBufFileRd(file, buffer, size);
- if (flag != -1)
- buffer[flag] = '\0';
- return flag;
- } /* End _DtHelpCeReadBuf */
- /******************************************************************************
- * Function: char *_DtHelpGetNxtToken (char *str, char **retToken)
- *
- * Parameters:
- * str The string (in memory) which is being
- * parsed.
- * retToken Returns the next token from the input.
- * Valid tokens are strings of non-whitespace
- * characters, newline ("\n"), and
- * end-of-data (indicated by a zero length
- * string).
- *
- * A NULL value indicates an error.
- *
- * Newline or zero length strings are
- * not owned by the caller.
- *
- * Otherwise, the memory for the returned
- * token is owned by the caller.
- *
- * Return Value: Returns the pointer to the next unparsed character in
- * the input string. A NULL value indicates an error.
- *
- * errno Values:
- * EINVAL
- * CEErrorMalloc
- *
- * Purpose: Parse tokens in resource string values.
- *
- *****************************************************************************/
- char *
- _DtHelpGetNxtToken (
- char *str,
- char **retToken)
- {
- int len = 1;
- char *start;
- char *token;
- short quote = False;
- short done = False;
- if (retToken) *retToken = NULL; /* tested in caller code */
- if (str == NULL || *str == '\0' || retToken == NULL)
- {
- errno = EINVAL;
- return NULL;
- }
- /* Find the next token in the string. The parsing rules are:
- - Whitespace (except for \n) separates tokens.
- - \n is a token itself.
- - The \0 at the end of the string is a token.
- */
- /* Skip all of the whitespace (except for \n). */
- while (*str && (*str != '\n') && isspace (*str))
- str++;
- /* Str is pointing at the start of the next token. Depending on the
- type of token, malloc the memory and copy the token value. */
- if (*str == '\0')
- token = strdup(str);
- else if (*str == '\n') {
- token = strdup(str);
- str++;
- }
- else {
- /* We have some non-whitespace characters. Find the end of */
- /* them and copy them into new memory. */
- if ((MB_CUR_MAX == 1 || mblen (str, MB_CUR_MAX) == 1) && *str == '\"')
- {
- /*
- * found a quoted token - skip the quote.
- */
- quote = True;
- str++;
- }
- start = str;
- while (*str && !done)
- {
- /*
- * get the length of the item.
- */
- len = 1;
- if (MB_CUR_MAX != 1)
- {
- len = mblen (str, MB_CUR_MAX);
- if (len < 0)
- len = 1;
- }
- if (len == 1)
- {
- /*
- * check for the token terminator
- */
- if ((quote && *str == '\"') ||
- (!quote && (isspace (*str) || *str == '\n')))
- done = True;
- else
- str++;
- }
- else
- str += len;
- }
- /*
- * determine the length of the token.
- */
- token = (char *) malloc ((str - start + 1) * sizeof (char));
- if (token)
- {
- strncpy (token, start, str - start);
- *(token + (str - start)) = '\0';
- }
- else
- errno = CEErrorMalloc;
- /*
- * skip the quote terminator
- */
- if (quote && len == 1 && *str == '\"')
- str++;
- }
- *retToken = token;
- return (str);
- }
- /******************************************************************************
- * Function: _DtCvSegment *_DtHelpAllocateSegments(int malloc_size)
- *
- * Parameters:
- * malloc_size Specifies the number of segments to
- * allocate if 'alloc_size' is NULL or less
- * than 1 or if '*next_seg' is NULL. The
- * first one is returned to the caller with
- * the rest in 'next_seg' if 'next_seg' is
- * non-NULL.
- *
- * Return Value:
- * non-null If succeeds.
- * Null If failure.
- *
- * Purpose: Allocate a block of segments, zeros the structures, and
- * sets the link_idx of each structure to -1.
- *
- *****************************************************************************/
- _DtCvSegment *
- _DtHelpAllocateSegments (
- int malloc_size)
- {
- int i;
- _DtCvSegment *newSeg;
- FrmtPrivateInfo *p;
- /*
- * don't allow zero or negative allocations
- */
- if (malloc_size < 1)
- malloc_size = 1;
- /*
- * allocate the block of segments
- */
- newSeg = (_DtCvSegment *) calloc (sizeof(_DtCvSegment), malloc_size);
- if (NULL != newSeg)
- {
- /*
- * now allocate the same number of private information structures
- */
- p = (FrmtPrivateInfo *) calloc (sizeof(FrmtPrivateInfo), malloc_size);
- if (NULL != p)
- {
- /*
- * mark the first item as the top block. Since it will be
- * attached to the first segment, it marks both the segment
- * and the private information blocks for later frees.
- */
- p->top_block = True;
- for (i = 0; i < malloc_size; i++)
- {
- /*
- * invalidate the link index and attach a private
- * information structure to each segment
- */
- newSeg[i].link_idx = -1;
- newSeg[i].client_use = p++;
- }
- }
- else
- {
- /*
- * had trouble allocating the private information.
- * free the new segment list and return NULL as an error.
- */
- free(newSeg);
- newSeg = NULL;
- }
- }
- return newSeg;
- }
- /******************************************************************************
- * Function: int _DtHelpFmtFindBreak (char *ptr, int mb_len, int *num_chars)
- *
- * Parameters:
- * ptr Specifies the string to check.
- * mb_len Specifies if the sequence should be single
- * byte or multi-byte.
- * num_chars Returns the character count.
- *
- * Returns number of bytes in the sequence.
- *
- * errno Values:
- *
- * Purpose: Find a length of 'ptr' comprised of multi or single byte
- * characters.
- *
- *****************************************************************************/
- int
- _DtHelpFmtFindBreak (
- char *ptr,
- int mb_len,
- int *num_chars)
- {
- int len = 0;
- int numChars = 0;
- int mySize;
- short done = 0;
- while (0 == done && '\0' != *ptr)
- {
- mySize = mblen(ptr, MB_CUR_MAX);
- done = 1;
- if (0 < mySize &&
- ((1 != mb_len && 1 != mySize) || (1 == mb_len && 1 == mySize)))
- {
- numChars++;
- ptr += mySize;
- len += mySize;
- done = 0;
- }
- }
- *num_chars = numChars;
- return len;
- }
- /******************************************************************************
- * Function: _DtHelpLoadMultiInfo
- *
- * Returns: Loads the multi-byte formatting table for the current locale.
- *
- *****************************************************************************/
- void
- _DtHelpLoadMultiInfo (
- wchar_t **cant_begin_chars,
- wchar_t **cant_end_chars,
- short *nl_to_space)
- {
- #ifndef NO_MESSAGE_CATALOG
- int len;
- char *ptr;
- nl_catd cat_fd;
- cat_fd = CATOPEN("fmt_tbl", NL_CAT_LOCALE);
- if (cat_fd != ((nl_catd) -1))
- {
- /*
- * Get the list of characters that can't begin a line.
- */
- ptr = CATGETS(cat_fd, 1, 1, "");
- len = strlen (ptr) + 1;
- *cant_begin_chars = (wchar_t *) malloc (len * sizeof (wchar_t));
- if (NULL != *cant_begin_chars &&
- mbstowcs(*cant_begin_chars, ptr, len) == -1)
- {
- free (*cant_begin_chars);
- *cant_begin_chars = NULL;
- }
- /*
- * Get the list of characters that can't end a line.
- */
- ptr = CATGETS(cat_fd, 1, 2, "");
- len = strlen (ptr) + 1;
- *cant_end_chars = (wchar_t *) malloc (len * sizeof (wchar_t));
- if (*cant_end_chars != NULL &&
- mbstowcs(*cant_end_chars, ptr, len) == -1)
- {
- free (*cant_end_chars);
- *cant_end_chars = NULL;
- }
- /*
- * Get the spacing flag. I.E. when does a internal newline
- * get turned into a space.
- * 1 means all the time.
- * 0 means only between a multibyte string and
- * a singlebyte string.
- */
- ptr = CATGETS(cat_fd, 1, 3, "1");
- *nl_to_space = atoi(ptr);
- CATCLOSE(cat_fd);
- }
- else
- #endif
- {
- *cant_begin_chars = NULL;
- *cant_end_chars = NULL;
- *nl_to_space = 1;
- }
- }
|