1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/****************************************************************
* *
* Copyright (c) 2006-2023 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_ctype.h"
#include <errno.h>
#include "gtm_stdio.h"
#include "gtm_string.h"
#ifdef UTF8_SUPPORTED
#include "gtm_icu_api.h"
#include "gtm_utf8.h"
#endif
#include "util.h"
#ifdef UTF8_SUPPORTED
GBLREF boolean_t gtm_utf8_mode;
#endif
#define MAX_LINE (32767+256) /* see cli.h */
/* Get one line of input from file stream fp and
* trim any line terminators.
*
* buffersize is the size in bytes of the buffer
* where the line is returned and includes the
* terminating null.
* buffersize must be less than or equal to MAX_LINE
* for UTF8
*
* If the return is NULL, there was an error
* otherwise it is the start of the line.
* If remove_leading_spaces, the return value
* will point at the first non space, according
* to isspace_asscii. Note that this may not be
* the beginning of buffer.
*/
char *util_input(char *buffer, int buffersize, FILE *fp, boolean_t remove_leading_spaces)
{
size_t in_len;
char *retptr;
#ifdef UTF8_SUPPORTED
int mbc_len, u16_off, non_space_off;
int32_t mbc_dest_len;
boolean_t found_non_space = FALSE;
UFILE *u_fp;
UChar *uc_fgets_ret, ufgets_Ubuffer[MAX_LINE];
UChar32 uc32_cp;
UErrorCode errorcode;
#endif
#ifdef UTF8_SUPPORTED
if (gtm_utf8_mode)
{
assert(MAX_LINE >= buffersize);
ufgets_Ubuffer[0] = 0;
u_fp = u_finit(fp, NULL, UTF8_NAME);
if (NULL != u_fp)
{
do
{ /* no u_ferror */
uc_fgets_ret = u_fgets(ufgets_Ubuffer, (int32_t)(SIZEOF(ufgets_Ubuffer) / SIZEOF(UChar)) - 1, u_fp);
} while (NULL == uc_fgets_ret && !u_feof(u_fp) && ferror(fp) && EINTR == errno);
if (NULL == uc_fgets_ret)
{
if (!u_feof(u_fp))
util_out_print("Error reading from STDIN", TRUE);
u_fclose(u_fp);
return NULL;
}
in_len = u_strlen(ufgets_Ubuffer);
in_len = trim_U16_line_term(ufgets_Ubuffer, (int4)in_len);
for (non_space_off = u16_off = mbc_len = 0; u16_off < in_len && mbc_len < (buffersize - 1); )
{
U16_NEXT(ufgets_Ubuffer, u16_off, in_len, uc32_cp); /* updates u16_off */
if (remove_leading_spaces && !found_non_space)
{
if (U_ISSPACE(uc32_cp))
continue;
else
{
found_non_space = TRUE;
non_space_off = u16_off;
U16_BACK_1(ufgets_Ubuffer, 0, non_space_off); /* get non space offset */
}
}
mbc_len += U8_LENGTH(uc32_cp);
}
if (mbc_len >= (buffersize - 1))
{
U16_BACK_1(ufgets_Ubuffer, 0, u16_off);
in_len = u16_off >= 0 ? u16_off + 1 : 0; /* offset to length */
}
errorcode = U_ZERO_ERROR;
u_strToUTF8(buffer, buffersize, &mbc_dest_len, &ufgets_Ubuffer[non_space_off],
(int4)in_len - non_space_off + 1, &errorcode); /* include null */
if (U_FAILURE(errorcode))
if (U_BUFFER_OVERFLOW_ERROR == errorcode)
{ /* truncate so null terminated */
buffer[buffersize - 1] = 0;
retptr = buffer;
} else
retptr = NULL;
else
retptr = buffer;
u_fclose(u_fp);
} else
retptr = NULL;
} else
{
#endif
buffer[0] = '\0';
do
{
FGETS(buffer, buffersize, fp, retptr);
} while (NULL == retptr && !feof(fp) && ferror(fp) && EINTR == errno);
if (NULL != retptr)
{
if (remove_leading_spaces)
while (*retptr && ISSPACE_ASCII(*retptr))
retptr++;
in_len = strlen(buffer);
if ('\n' == buffer[in_len - 1])
buffer[in_len - 1] = '\0';
} else
{
if (!feof(fp))
util_out_print("Error reading from STDIN", TRUE);
}
#ifdef UTF8_SUPPORTED
}
#endif
return retptr;
}
|