Added Wine command-line interpreter.
[wine/wine-kai.git] / programs / wcmd / batch.c
blobcba1c3ec0f0358e49318aa7d61514040d824c50d
1 /*
2 * WCMD - Wine-compatible command line interface - batch interface.
4 * (C) 1999 D A Pickles
6 */
9 #include "wcmd.h"
11 void WCMD_batch_command (HANDLE h, char *command);
12 char *WCMD_parameter (char *s, int n);
13 BOOL WCMD_go_to (HANDLE h, char *label);
15 extern HANDLE STDin, STDout;
16 extern char nyi[];
17 extern char newline[];
18 extern char version_string[];
19 extern int echo_mode;
20 extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
24 /****************************************************************************
25 * WCMD_batch
27 * Open and execute a batch file.
28 * On entry *command includes the complete command line beginning with the name
29 * of the batch file (if a CALL command was entered the CALL has been removed).
30 * *file is the name of the file, which might not exist and may not have the
31 * .BAT suffix on.
33 * We need to handle recursion correctly, since one batch program might call another.
36 void WCMD_batch (char *file, char *command) {
38 HANDLE h;
39 char string[MAX_PATH];
40 int n;
42 strcpy (string, file);
43 CharLower (string);
44 if (strstr (string, ".bat") == NULL) strcat (string, ".bat");
45 h = CreateFile (string, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
46 if (h == INVALID_HANDLE_VALUE) {
47 WCMD_output ("File %s not found\n", string);
48 return;
52 * Work through the file line by line. Specific batch commands are processed here,
53 * the rest are handled by the main command processor.
56 while (WCMD_fgets (string, sizeof(string), h)) {
57 n = strlen (string);
58 if (string[n-1] == '\n') string[n-1] = '\0';
59 if (string[n-2] == '\r') string[n-2] = '\0'; /* Under Windoze we get CRLF! */
60 WCMD_batch_command (h, string);
62 CloseHandle (h);
65 /****************************************************************************
66 * WCMD_batch_command
68 * Execute one line from a batch file.
71 void WCMD_batch_command (HANDLE h, char *command) {
73 DWORD status;
74 char cmd[1024];
76 if (echo_mode && (command[0] != '@')) WCMD_output ("%s", command);
77 status = ExpandEnvironmentStrings (command, cmd, sizeof(cmd));
78 if (!status) {
79 WCMD_print_error ();
80 return;
82 WCMD_process_command (cmd);
85 /****************************************************************************
86 * WCMD_go_to
88 * Batch file jump instruction. Not the most efficient algorithm ;-)
89 * Returns FALSE if the specified label cannot be found - the file pointer is
90 * then at EOF.
93 BOOL WCMD_go_to (HANDLE h, char *label) {
95 char string[MAX_PATH];
97 SetFilePointer (h, 0, NULL, FILE_BEGIN);
98 while (WCMD_fgets (string, sizeof(string), h)) {
99 if ((string[0] == ':') && (strcmp (&string[1], label) == 0)) return TRUE;
101 return FALSE;
104 /*******************************************************************
105 * WCMD_parameter - extract a parameter from a command line.
107 * Returns the 'n'th space-delimited parameter on the command line.
108 * Parameter is in static storage overwritten on the next call.
109 * Parameters in quotes are handled.
112 char *WCMD_parameter (char *s, int n) {
114 int i = -1;
115 static char param[MAX_PATH];
116 char *p;
118 p = param;
119 while (TRUE) {
120 switch (*s) {
121 case ' ':
122 s++;
123 break;
124 case '"':
125 s++;
126 while ((*s != '\0') && (*s != '"')) {
127 *p++ = *s++;
129 if (i == n) {
130 *p = '\0';
131 return param;
133 else {
134 param[0] = '\0';
135 i++;
137 if (*s == '"') s++;
138 break;
139 case '\0':
140 return param;
141 default:
142 while ((*s != '\0') && (*s != ' ')) {
143 *p++ = *s++;
145 if (i == n) {
146 *p = '\0';
147 return param;
149 else {
150 param[0] = '\0';
151 i++;
157 /****************************************************************************
158 * WCMD_fgets
160 * Get one line from a batch file. We can't use the native f* functions because
161 * of the filename syntax differences between DOS and Unix.
164 char *WCMD_fgets (char *s, int n, HANDLE h) {
166 DWORD bytes;
167 BOOL status;
168 char *p;
170 p = s;
171 do {
172 status = ReadFile (h, s, 1, &bytes, NULL);
173 if ((status == 0) || (bytes == 0)) return NULL;
174 if (*s == '\n') bytes = 0;
175 *++s = '\0';
176 n--;
177 } while ((bytes == 1) && (n > 1));
178 return p;