fis-gtm/sr_unix/util_input.c

142 lines
3.8 KiB
C

/****************************************************************
* *
* Copyright 2006, 2011 Fidelity Information Services, Inc *
* *
* 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 UNICODE_SUPPORTED
#include "gtm_icu_api.h"
#include "gtm_utf8.h"
#endif
#include "util.h"
#ifdef UNICODE_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 Unicode
*
* 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 UNICODE_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 UNICODE_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 UNICODE_SUPPORTED
}
#endif
return retptr;
}