File: parse_file.h

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 (222 lines) | stat: -rwxr-xr-x 8,180 bytes parent folder | download | duplicates (5)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/****************************************************************
 *								*
 * Copyright (c) 2001-2018 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.	*
 *								*
 ****************************************************************/

#ifndef PARSE_FILE_H_INCLUDED
#define PARSE_FILE_H_INCLUDED

#define DEF_DBEXT	"*.dat"
#define DEF_NODBEXT	"*"

typedef struct parse_blk_struct
{
	unsigned char	b_esl;		/* Resultant name length */
	unsigned char	b_node;		/* Length of node name at front - db opening only */
	unsigned char	b_dir;		/* Length of directory path */
	unsigned char	b_name;		/* Length of file name */
	unsigned char	b_ext;		/* Length of extension */
	unsigned char	def1_size;	/* Default 1 string size */
	char		*def1_buf;	/* Default 1 buffer */
	unsigned char	def2_size;	/* Default 2 string size */
	char		*def2_buf;	/* Default 2 buffer */
	unsigned char	buff_size;	/* Result buffer size */
	char		*buffer;	/* Result buffer */
	int4		fnb;		/* Parse result characteristics */
	int4		fop;		/* Parse options SYNTAX_ONLY only */
	char		*l_node,	/* Pointer to node specification - db opening only */
			*l_dir,		/* Pointer to directory path string */
			*l_name,	/* Pointer to file name string */
			*l_ext;		/* Pointer to extension string */
} parse_blk;

typedef struct plength_struct
{
	union
	{
		int4	pint;
		struct
		{
			unsigned char	b_esl;	/* Resultant name length */
			unsigned char	b_dir;	/* Length of directory path */
			unsigned char	b_name;	/* Length of file name */
			unsigned char	b_ext;	/* Length of extension */
		} pblk;
	} p;
} plength;

#define F_HAS_EXT	1	/* 0x01 If file has explicit extension */
#define F_HAS_NAME	2	/* 0x02 If file has explicit name */
#define F_HAS_DIR	4	/* 0x04 If file has explicit directory path */
#define F_WILD_NAME	8	/* 0x08 If there is a wild card character in the name */
#define F_WILD_DIR	16	/* 0x10 If there is a wild card character in the directory */
#define F_WILD		24	/* 0x18 If there is a wild card character in the result (dir or name) */
#define F_HAS_NODE	32	/* 0x20 If there is a node specification on the front - db opening only */

#define V_HAS_EXT	0	/* Bit offsets for F_ constants */
#define V_HAS_NAME	1
#define V_HAS_DIR	2
#define V_WILD_NAME	3
#define V_WILD_DIR	4
#define V_HAS_NODE	5	/* DB opening only */

#define F_SYNTAXO	1	/* SYNTAX ONLY - Otherwise checks on directory existence returning ERR_FILENOTFOUND if
				 * directory does not exist or is not a directory.
				 */
#define F_PARNODE	2	/* Look for a node specification - db opening only */

/* Sets the relevant length fields in a plength-typed structure:
 *  b_esl  - full length of PATH;
 *  b_dir  - length of the PATH preceding the file name (includes the slash);
 *  b_name - length of the file name in PATH (excludes the extension); and
 *  b_ext  - length of the file name extension.
 * Note that PLEN is a pointer-type argument. ABSOLUTE expects the indication of whether the PATH is absolute or relative.
 */
#define SET_LENGTHS(PLEN, PATH, LENGTH, ABSOLUTE)								\
{														\
	int		i;											\
	boolean_t	seen_ext;										\
														\
	(PLEN)->p.pblk.b_esl = LENGTH;										\
	(PLEN)->p.pblk.b_ext = 0;										\
	for (i = LENGTH - 1, seen_ext = FALSE; i >= 0; i--)							\
	{													\
		if ('.' == *((PATH) + i))									\
		{												\
			if (!seen_ext)										\
			{											\
				(PLEN)->p.pblk.b_ext = LENGTH - i;						\
				seen_ext = TRUE;								\
			}											\
		} else if ('/' == *((PATH) + i))								\
			break;											\
	}													\
	assert((i >= 0) || !(ABSOLUTE)); /* On UNIX absolute paths must have '/'. */				\
	(PLEN)->p.pblk.b_dir = i + 1;										\
	(PLEN)->p.pblk.b_name = LENGTH - (PLEN)->p.pblk.b_dir - (PLEN)->p.pblk.b_ext;				\
}

/* Canonicalize the path by appropriately removing '.' and '..' path modifiers. Note that all* modifications are
 * performed on the passed string directly.
 */
#define CANONICALIZE_PATH(PATH)											\
{														\
	char		*src, *dst;										\
	char		cur_char;										\
	boolean_t	need_slash;										\
														\
	src = dst = (PATH);											\
	assert('/' == *src);											\
	need_slash = FALSE;											\
	while ('\0' != (cur_char = *src++))									\
	{													\
		if ('/' == cur_char)										\
		{	/* Current character is '/'. If it is the last one, do not append a trailing slash. */	\
			if ('\0' == (cur_char = *src++))							\
				break;										\
			if ('/' == cur_char)									\
			{	/* Current sequence is '//'. Restart the loop from the second slash. */		\
				src--;										\
				need_slash = TRUE;								\
			} else if ('.' == cur_char)								\
			{	/* Current sequence is '/.'. We need to examine a few potential scenarios. In	\
				 * particular, if we are at the last character, no need to append anything.	\
				 */										\
				if ('\0' == (cur_char = *src++))						\
					break;									\
				if ('/' == cur_char)								\
				{	/* Current sequence is '/./'. Restart the loop from the second '/'. */	\
					src--;									\
					need_slash = FALSE;							\
				} else if ('.' == cur_char)							\
				{	/* Current sequence is '/..'. If the next character is '/' or we are at	\
					 * the end of the line, snip off one directory from the tail, if found.	\
					 */									\
					cur_char = *src++;							\
					if (('\0' == cur_char) || ('/' == cur_char))				\
					{	/* Find an earlier '/'. Reset to '/' if not found. */		\
						while (--dst >= (PATH))						\
							if ('/' == *dst)					\
								break;						\
						if ((PATH) > dst)						\
						{								\
							need_slash = TRUE;					\
							dst = (PATH);						\
						} else								\
							need_slash = FALSE;					\
						src--;								\
					} else									\
					{	/* Current sequence is '/..<x>', where x is not '/' or '\0'. */	\
						need_slash = FALSE;						\
						*dst++ = '/';							\
						*dst++ = '.';							\
						*dst++ = '.';							\
						*dst++ = cur_char;						\
					}									\
				} else										\
				{	/* Current sequence is '/.<x>', where x is not '/' or '.' or '\0'. */	\
					need_slash = FALSE;							\
					*dst++ = '/';								\
					*dst++ = '.';								\
					*dst++ = cur_char;							\
				}										\
			} else											\
			{	/* Current sequence is '/<x>', where x is not '/' or '.' or '\0'. */		\
				need_slash = FALSE;								\
				*dst++ = '/';									\
				*dst++ = cur_char;								\
			}											\
		} else												\
		{	/* Current character is not '/', so write it. But prepend it with a '/' if we have	\
			 * previously indicated a need for one.							\
			 */											\
			if (need_slash)										\
				*dst++ = '/';									\
			need_slash = FALSE;									\
			*dst++ = cur_char;									\
		}												\
	}													\
	assert(dst >= (PATH));											\
	/* If we did not have anything to put in the canonicalized path, default to '/'. */			\
	if (dst == (PATH))											\
		*dst++ = '/';											\
	*dst = '\0';												\
}

/* Escape all '[' and ']' characters to prevent glob() from trying to match sets enclosed in them. */
#define ESCAPE_BRACKETS(ORIG_PATH, RES_PATH)									\
{														\
	char		*src, *dst;										\
	char		cur_char;										\
	boolean_t	has_slash;										\
														\
	src = ORIG_PATH;											\
	dst = RES_PATH;												\
	has_slash = FALSE;											\
	while ('\0' != (cur_char = *src++))									\
	{													\
		if ('\\' == cur_char)										\
			has_slash = !has_slash;									\
		else if (('[' == cur_char) || (']' == cur_char))						\
		{												\
			if (!has_slash)										\
				*dst++ = '\\';									\
			else											\
				has_slash = FALSE;								\
		} else if (has_slash)										\
			has_slash = FALSE;									\
		*dst++ = cur_char;										\
	}													\
	*dst = '\0';												\
}

int4 parse_file(mstr *file, parse_blk *pblk);

#endif /* PARSE_FILE_H_INCLUDED */