File: zl_cmd_qlf.c

package info (click to toggle)
fis-gtm 6.3-007-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 36,284 kB
  • sloc: ansic: 328,861; asm: 5,182; csh: 5,102; sh: 1,918; awk: 291; makefile: 69; sed: 13
file content (208 lines) | stat: -rwxr-xr-x 7,596 bytes parent folder | download
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
/****************************************************************
 *								*
 * Copyright (c) 2001-2019 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_string.h"

#include "cmd_qlf.h"
#include "cli.h"
#include "cli_parse.h"
#include "parse_file.h"
#include "min_max.h"
#include "toktyp.h"		/* Needed for "valid_mname.h" */
#include "valid_mname.h"
#include "gtmmsg.h"

#define SET_OBJ(NAME, LEN)					\
MBSTART {							\
	memcpy(cmd_qlf.object_file.str.addr, NAME, LEN);	\
	cmd_qlf.object_file.str.addr[LEN] = 0;			\
	cmd_qlf.object_file.str.len = LEN;			\
	cmd_qlf.object_file.mvtype = MV_STR;			\
} MBEND

#define	COMMAND			"MUMPS "

GBLREF	char			cli_err_str[];
GBLREF	CLI_ENTRY		*cmd_ary, mumps_cmd_ary[];
GBLREF	command_qualifier	cmd_qlf, glb_cmd_qlf;
GBLREF	mident			routine_name, module_name, int_module_name;
GBLREF	unsigned char		object_file_name[], source_file_name[];
GBLREF	unsigned short		object_name_len, source_name_len;

STATICDEF uint4		save_qlf;

error_def(ERR_COMPILEQUALS);
error_def(ERR_FILEPARSE);
error_def(ERR_NOTMNAME);
error_def(ERR_WILDCARD);
error_def(ERR_ZLINKFILE);
error_def(ERR_ZLNOOBJECT);

void zl_cmd_qlf(mstr *quals, command_qualifier *qualif, char *srcstr, unsigned short *srclen, boolean_t last)
{
	char		cbuf[MAX_LINE], inputf[MAX_FN_LEN + 1];
	CLI_ENTRY	*save_cmd_ary;
	int		ci, parse_ret, status;
	mident		file;
	mstr		fstr;
	parse_blk	pblk;
	short		object_name_mvtype;
	unsigned short	clen = 0;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if (quals->len + SIZEOF(COMMAND) > MAX_LINE)
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_COMPILEQUALS, 2, quals->len, quals->addr);
	MEMCPY_LIT(cbuf, COMMAND);
	memcpy(cbuf + SIZEOF(COMMAND) - 1, quals->addr, quals->len);
	cbuf[SIZEOF(COMMAND) - 1 + quals->len] = 0;
	/* The caller of this function could have their own command parsing tables Nevertheless, we need to parse the string as if
	 * it was a MUMPS compilation command. So we switch temporarily to the MUMPS parsing table "mumps_cmd_ary". Note that the
	 * only rts_errors possible between save and restore of the cmd_ary are in compile_source_file and those are internally
	 * handled by source_ch which will transfer control back to us (right after the the call to compile_source_file below)
	 * and hence proper restoring of cmd_ary is guaranteed even in case of errors.
	 */
	save_cmd_ary = cmd_ary;
	cmd_ary = &mumps_cmd_ary[0];
	cli_str_setup((uint4)(SIZEOF(COMMAND) + quals->len), cbuf);
	parse_ret = parse_cmd();
	if (parse_ret)
	{
		if (last & save_qlf)
			glb_cmd_qlf.qlf = save_qlf;
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) parse_ret, 2, LEN_AND_STR(cli_err_str));
	}
	object_name_mvtype = qualif->object_file.mvtype;
	get_cmd_qlf(qualif);
	qualif->object_file.mvtype |= object_name_mvtype;
	cmd_ary = save_cmd_ary;							/* restore cmd_ary */
	if (last && (!module_name.len || !*srclen))
	{	/* if we're calling this twice the first time would be without a real "INFILE" */
		if (!*srclen)
		{
			*srclen = MAX_FN_LEN;
			status = cli_get_str("INFILE", srcstr, srclen);
			assert(status);
		}
		assert(*srclen);
		memset(&pblk, 0, SIZEOF(pblk));
		pblk.buff_size = MAX_FN_LEN;
		pblk.buffer = inputf;
		pblk.fop = F_SYNTAXO;
		fstr.addr = srcstr;
		fstr.len = *srclen;
		status = parse_file(&fstr, &pblk);
		if (!(status & 1))
		{
			if (save_qlf)
				glb_cmd_qlf.qlf = save_qlf;
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_FILEPARSE, 2, *srclen, srcstr, status);
		}
		assert(pblk.b_name);
		file.addr = pblk.l_name;
		file.len = pblk.b_name;
		if ((0 == pblk.b_ext) && ( MAX_FN_LEN >= (*srclen + SIZEOF(DOTM))))
		{
			memcpy(&pblk.l_name[pblk.b_name], DOTM, SIZEOF(DOTM));
			pblk.b_ext = (SIZEOF(DOTM) - 1);
		}
		source_name_len = pblk.b_dir + pblk.b_name + pblk.b_ext;
		source_name_len = MIN(source_name_len, MAX_FN_LEN);
		memcpy(source_file_name, pblk.buffer, source_name_len);
		source_file_name[source_name_len] = 0;
		memcpy(srcstr, source_file_name, source_name_len);
		srcstr[source_name_len] = 0;
		*srclen = source_name_len;
		if (!module_name.len && !(CQ_NAMEOFRTN & cmd_qlf.qlf) && !(CLI_PRESENT == cli_present("OBJECT")))
		{
			memcpy(routine_name.addr, file.addr, file.len);
			clen = routine_name.len = MIN(file.len, MAX_MIDENT_LEN);
			object_name_len = clen;
			memcpy(object_file_name, pblk.l_name, object_name_len);
			SET_OBJ(object_file_name, object_name_len);
		}

	}
	assert(!last || *srclen);
	/* routine_name is the internal name of the routine (with any leading '%' translated to '_') which by default is the
	 * unpathed name of the source file. An -OBJECT qualif (without a NAMEOFOFRTN) makes routine_name from the name of the
	 * object (which trigger compilation uses). A NAMEOFOFRTN qualifier (which trigger compilation uses) overrides the others.
	 * int_module_name is the external symbol (without the % translation) that gets exposed (in the GTM context)
	 */
	if (CLI_PRESENT == cli_present("OBJECT"))
	{
		assert((cmd_qlf.object_file.str.len) && (MAX_FN_LEN >= cmd_qlf.object_file.str.len)
			&& (cmd_qlf.object_file.str.addr));
		object_name_len = MAX_FN_LEN;
		cli_get_str("OBJECT", (char *)object_file_name, &object_name_len);
		cmd_qlf.object_file.mvtype = MV_STR;
		if (!(CQ_NAMEOFRTN & cmd_qlf.qlf))
		{
			for (ci = object_name_len - 1; ci && ('/' != object_file_name[ci]); ci--)
				;       /* scan back from end for rtn name & triggerness */
			ci += ci ? 1 : 0;
			clen = object_name_len - ci;
			if (('o' != object_file_name[ci + --clen])
					|| ('.' != object_file_name[ci + --clen]))
				clen = object_name_len - ci;
			clen = MIN(clen, MAX_MIDENT_LEN);
			memcpy(routine_name.addr, &object_file_name[ci], clen);
			SET_OBJ(object_file_name, object_name_len);
		}
	}
	assert(!last || *srclen);
	if (CQ_NAMEOFRTN & cmd_qlf.qlf)
	{       /* Routine name specified - name wins over object */
		clen = MAX_MIDENT_LEN;
		cli_get_str("NAMEOFRTN", routine_name.addr, &clen);
		assert(MAX_MIDENT_LEN >= clen);
		cmd_qlf.qlf &= ~CQ_NAMEOFRTN;   /* Can only be used for first module in list */
		if (CLI_PRESENT != cli_present("OBJECT"))
		{
			memcpy(object_file_name, routine_name.addr, clen);
			SET_OBJ(object_file_name, clen);
		}
	}
	assert(!last || *srclen);
	if (clen)
	{
		memcpy(module_name.addr, routine_name.addr, clen);
		if ('_' == *routine_name.addr)
			routine_name.addr[0] = '%';
		routine_name.len = clen;
		if (last && !(pblk.fnb & F_WILD) && !TREF(trigger_compile_and_link) && !valid_mname(&routine_name))
		{
			if (save_qlf)
				glb_cmd_qlf.qlf = save_qlf;
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_NOTMNAME, 2, RTS_ERROR_MSTR(&routine_name), ERR_ZLNOOBJECT);
		}
		module_name.len = int_module_name.len = clen;
		memcpy(int_module_name.addr, routine_name.addr, clen);
	} else
		assert(!last || int_module_name.len);
	assert(!last || *srclen);
	if (!last)
	{
		save_qlf = glb_cmd_qlf.qlf;
		glb_cmd_qlf.qlf = cmd_qlf.qlf;
#		ifdef DEBUG
		if (!cmd_qlf.list_file.str.len && (CLI_PRESENT == cli_present("LIST")))
			cmd_qlf.list_file.str.len = MAX_FN_LEN;
		if (!cmd_qlf.ceprep_file.str.len && (CLI_PRESENT == cli_present("CE_PREPROCESS")))
			cmd_qlf.ceprep_file.str.len = MAX_FN_LEN;
#		endif
	} else if (save_qlf)
		glb_cmd_qlf.qlf = save_qlf;
	return;
}