File: util_input.c

package info (click to toggle)
fis-gtm 7.1-006-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 32,908 kB
  • sloc: ansic: 344,906; asm: 5,184; csh: 4,859; sh: 2,000; awk: 294; makefile: 73; sed: 13
file content (144 lines) | stat: -rwxr-xr-x 3,981 bytes parent folder | download | duplicates (2)
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;
}