File: util_input.c

package info (click to toggle)
fis-gtm 6.2-000-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 30,784 kB
  • ctags: 42,554
  • sloc: ansic: 358,483; asm: 4,847; csh: 4,574; sh: 2,261; awk: 200; makefile: 86; sed: 13
file content (141 lines) | stat: -rw-r--r-- 3,923 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
/****************************************************************
 *								*
 *	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;
}