File: if.c

package info (click to toggle)
dosemu-freedos 1%3A0.0.b9r5a%2Betch.1-0etch1
  • links: PTS
  • area: contrib
  • in suites: etch
  • size: 19,744 kB
  • ctags: 23,279
  • sloc: ansic: 143,864; asm: 20,397; makefile: 3,868; perl: 1,106; yacc: 690; sh: 553; pascal: 297; xml: 150; cpp: 67
file content (162 lines) | stat: -rw-r--r-- 3,414 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
 *  IF.C - if command.
 *
 *  Comments:
 *
 * 16 Jul 1998 (Hans B Pufal)
 *   started.
 *
 * 16 Jul 1998 (John P Price)
 *   Seperated commands into individual files.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 1999/11/04 ska
 * + bugfix: if: case-insensitive compare  in "==" format
 * + bugfix: if: added support for quoted operands of "==" format
 * + add: if: detailed error messages
 * + bugfix: if: keyword "EXIST" misspelled
 *
 * 2000/07/05 Ron Cemer
 *	bugfix: renamed skipwd() -> skip_word() to prevent duplicate symbol
 */

#include "../config.h"

#include <assert.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../include/batch.h"
#include "../include/cmdline.h"
#include "../include/command.h"
#include "../err_fcts.h"

int cmd_if(char *param)
{

#define X_EXEC 1

	int x_flag = 0;       /* when set cause 'then' clause to be exec'ed */
	int negate = 0;       /* NOT keyword present */

	char *pp;

	/* First check if param string begins with word 'not' */
	assert(param);

	if(matchtok(param, "not"))
		negate = X_EXEC;            /* Remember 'NOT' */

	/* Check for 'exist' form */

	if(matchtok(param, "exist")) {
		struct ffblk f;

		if(!*param) {
			/* syntax error */
			error_if_exist();
			return 0;
		}

		pp = skip_word(param);
		*pp++ = '\0';

		if(FINDFIRST(param, &f, FA_NORMAL) == 0)
			x_flag = X_EXEC;
	}

	/* Check for 'errorlevel' form */

	else if(matchtok(param, "errorlevel")) {
		int n = 0;

#if 0
		if(!isdigit(*param)) {
			error_if_errorlevel();
			return 0;
		}

		pp = param;
		do  n = n * 10 + (*pp - '0');
		while (isdigit(*++pp));

		if(*pp && !isargdelim(*pp)) {
			error_if_errorlevel_number();
			return 0;
		}
#else
		/* Add this COMMAND bug as someone tries to use:
			IF ERRORLEVEL H<upper-case_letter>
			-or-
			IF ERRORLEVEL x<lower-case_letter>

			to match the errorlevel against drive letters.
			NOT supported by 4dos or WinNT.

			HA --> maps to errorlevel 1
			xa --> same

			HB & xb --> to 2
			a.s.o.
		*/

		if(!*param) {
			error_if_errorlevel();
			return 0;
		}
		pp = param;
		do  n = n * 10 + (*pp - '0');
		while(*++pp && !isargdelim(*pp));
		n &= 255;
		dprintf( ("IF: checking for ERRORLEVEL >= %u\n", n) );
#endif

		if(errorlevel >= n)
			x_flag = X_EXEC;
	}

	/* Check that '==' is present, syntax error if not */
	else {
		size_t len;
		char *r;      /* right operand */

		pp = skipqword(param, "==");

		if(*pp != '=' || pp[1] != '=') {
			error_syntax(0);
			return 0;
		}

		*pp = '\0';     /* param[] points to the left operand */

		/* skip over the '==' and subsquent spaces and
			assign the end of the right operator to pp */
		pp = skipqword(r = ltrimcl(pp + 2), 0);

		/*	now: param := beginning of the left operand
			r := beginning of the right operand
			pp := end of right operand
		*/

		rtrimcl(param);      /* ensure that spurious whitespaces are ignored */
		len = strlen(param);

		if((pp - r) == len
		 && memcmp(param, r, len) == 0) /* strings differ */
			x_flag = X_EXEC;
	}

	if(x_flag ^ negate)		/* perform the command */
		if(!*(pp = ltrimcl(pp)))
			error_if_command();
		else
			parsecommandline(pp, FALSE);

	return 0;
}