📄 batch.c
字号:
case '\r': /* carriage return */
if(*batch_ptr() != '\n') /* skip line feed */
batch->offset--; /* if present */
break;
case '"': /* Support Quoted strings */
quote = !quote; /* in batch files. */
goto save_it;
case PIPE_CHAR: /* Handle Piped Output */
if(goto_flg || quote) /* Ignore this character if */
goto save_it; /* we are searching for a */
/* Label or Quote. */
line[i] = '\0';
c = *deblank(line); /* normal case we just */
if ((c !='\0') && (c != ':') && following_command()) {
c = '\r'; /* simulate a CR and set */
pipe_out = YES; /* Pipe Output flag. */
} else if (c == ':') { /* if it's a label */
for(;(c != '\r') && (c != 0x1A); c = *batch_ptr())
if (c == 0x1A) /* eat rest of the line */
batch->eof = YES;
if(*batch_ptr() != '\n')/* skip line feed */
batch->offset--; /* if present */
c = '\r';
} else { /* if it's a syntax error */
swallow_line(line); /* discard the rest of line */
i = 0; /* start again with new line */
}
break;
case '%': /* The following code checks to see if the */
/* string starting at line[env_start-1] is */
/* define in the environment if it is then */
/* its definition replaces it in the input */
/* line. Otherwise no change is made. */
if(env_start) {
env_start--;
line[i] = '\0'; /* Terminate Input */
strcpy(env_str, line+env_start);/* Copy the String */
strupr(env_str); /* and force string */
bp = (BYTE *)heap(); /* into Uppercase */
i = env_start;
env_start = NULL;
strcat(env_str,"=");
if (env_scan(env_str,bp)) {
if (novell_extension(env_str,bp)) break;
}
while(*bp && i < MAX_LINE-1)
line[i++] = *bp++;
break;
}
c = *batch_ptr();
if (c == '\r') {
batch->offset--; /* rewind to point to '\r' */
break; /* then break to normal code */
}
if (c < '0' || c > '9') { /* if not a parameter */
if(c != '%') /* or a '%' character */
env_start = i+1; /* save its start address in */
goto save_it; /* the string and wait for */
} /* the terminating '%' */
n = c - '0' + batch->batshift; /* get parameter # 0-9 and */
/* add in SHIFT offset */
s = batch->batcmd;
while(n-- && strlen(s)) /* skip all other parameters */
s += strlen(s)+1; /* before the one we want */
if((strlen(s) + i) >= MAX_LINE) /* Break if Greater than MAX_LINE*/
break;
strcpy (line + i, s); /* get the substitution */
i += strlen (s); /* add in its size */
break;
case 0x1a:
end_of_file:
batch->eof = YES; /* We have come to the end */
c = '\r'; /* of the batch file so set */
break; /* flag and mark end of line*/
default:
save_it:
if (i < MAX_LINE)
line[i++] = c;
if (dbcs_lead(c)) {
if ((c = *batch_ptr()) >= ' ' && i < MAX_LINE)
line[i++] = c;
}
}
} while (c != '\r'); /* repeat until CR */
line[i] = '\0'; /* Terminate the line and */
if(batch->eof)
return;
#if 0 /* not DOS compatible */
if(*batch_ptr() == 0x1A) /* Check if the next this */
batch->eof = YES; /* the end of the file if */
else /* YES then set the flag */
batch->offset--; /* force the character to */
#endif /* be re-read next time */
return; /* return to the caller */
}
MLOCAL BOOLEAN following_command()
/* return true if we have a possible command on the rest of the line */
{
LONG old_offset;
BOOLEAN res = FALSE;
BYTE *s;
old_offset = batch->offset; /* save batch offset */
while (TRUE) {
s = batch_ptr(); /* look ahead at batch file */
if (*s == '\r' || *s == 0x1a || (!dbcs_lead(*s) && *s == PIPE_CHAR))
break;
if (!is_blank(s)) {
res = TRUE; /* possible command if we */
break; /* hit non whitespace char */
}
if (dbcs_lead(*s)) {
s = batch_ptr();
if (*s == '\r' || *s == 0x1a)
break;
}
}
batch->offset = old_offset; /* restore batch offset */
return res;
}
MLOCAL VOID swallow_line(s)
BYTE *s;
/* there is a syntax error on this line - swallow it and say so */
{
BYTE c;
prompt(); /* possibly echo the prompt */
if (echoflg) /* echo to screen if wanted */
printf("%s%c",s,PIPE_CHAR);
do {
c = *batch_ptr();
if (c == 0x1a) {
c = '\r'; /* pretend to be end of line*/
batch->eof = YES; /* We have come to the end */
break; /* flag and mark end of line*/
}
if (echoflg) /* echo to screen if wanted */
putc(c);
} while (c != '\r');
if (echoflg)
putc('\n');
if (*batch_ptr() != '\n') /* skip line feed */
batch->offset--; /* if present */
eprintf(MSG_SYNTAX); /* report syntax error */
}
/*
* In order to improve performance of the batch file processing
* the Batch file is read in blocks of BATCH_BUF characters.
* and the routine BATCH_CHAR then returns a pointer to a character
* from the buffer (filling the buffer if required).
*/
MLOCAL BYTE *batch_ptr()
{
BYTE FAR *buf;
UWORD bufsize;
UWORD i;
if(batch->eof)
return(batch_eof);
if (batch->offset < batch_off ||
batch->offset >= (batch_off + (LONG) (batch_cnt - 1))) {
batch_off = batch->offset;
ms_x_lseek (batch->stream, batch->offset, 0);
batch_cnt = far_read(batch->stream, gp_far_buff, sizeof(batch_buf));
if(batch_cnt <= 0) {
batch->eof = YES;
return(batch_eof);
}
for (i=0; i<sizeof(batch_buf); i++) batch_buf[i] = gp_far_buff[i];
}
return(&batch_buf[(UWORD) (batch->offset++ - batch_off)]);
}
/*.pa*/
/*
* BATCH FILE COMMANDS
* ===================
*
* The following commands are used almost entirely in BATCH files and
* have little or no meaning outside that environment.
*/
GLOBAL VOID CDECL cmd_shift ()
{
batch->batshift++; /* Increment the Shift Offset */
}
MLOCAL WORD label_ignore_char(s)
BYTE *s;
{
if (*s == '=') return(1);
if (*s == ';') return(1);
if (*s == ',') return(1);
if (*s == ' ') return(1);
return(0);
}
/*
* Extract the first a valid characters from the label and then
* zero terminate the resulting string.
*/
MLOCAL BYTE * make_label(label)
BYTE *label;
{
REG BYTE *bp;
UWORD i;
label = deblank(label); /* remove leading white space */
while (label_ignore_char(label))
label = skip_char(label);
bp = label;
while (is_filechar(bp)) /* skip over valid chars */
bp = skip_char(bp);
*bp = '\0'; /* make label zero terminated */
return label;
}
GLOBAL VOID CDECL cmd_goto (label) /* goto label in batch file */
REG BYTE *label;
{
UWORD i;
BYTE *bp, s[MAX_LINE+2]; /* Allocate buffer for Batch Input */
if (!batchflg) /* if not in batch mode */
return; /* this command is ignored */
if(*label == ':') /* Ignore any leading ':' */
label++;
label = make_label(label); /* Convert to Label Format */
batch->offset = 0L; /* rewind the batch file */
batch->eof = NO; /* So it cannot be EOF */
if(!batch_open()) /* Check the Batch file is open */
return; /* and stop if the function fails. */
while(!batch->eof) { /* while not end of file read next */
batch_read(s, YES); /* line and return the next command */
bp = deblank(s);
if((*bp == ':') && !strnicmp(make_label(bp+1),label, 8))
return;
}
batch_end(); /* Stop any further batch file */
crlfflg = YES; /* processing and print the error */
eprintf(MSG_LABEL, label);
}
GLOBAL VOID CDECL cmd_gosub (label) /* gosub label in batch file */
REG BYTE *label;
{
UWORD i;
BYTE *bp, s[MAX_LINE+2]; /* Allocate buffer for Batch Input */
if (!batchflg) /* if not in batch mode */
return; /* this command is ignored */
if (batch->ret_offset[3] != 0L) {
batch_end();
crlfflg = YES;
eprintf(MSG_GOSUB);
return;
}
if(*label == ':') /* Ignore any leading ':' */
label++;
label = make_label(label); /* Convert to Label Format */
i = 0;
while (batch->ret_offset[i] != 0L) i++;
batch->ret_offset[i] = batch->offset;
batch->offset = 0L; /* rewind the batch file */
batch->eof = NO; /* So it cannot be EOF */
if(!batch_open()) /* Check the Batch file is open */
return; /* and stop if the function fails. */
while(!batch->eof) { /* while not end of file read next */
batch_read(s, YES); /* line and return the next command */
bp = deblank(s);
if((*bp == ':') && !strnicmp(make_label(bp+1),label, 8))
return;
}
batch_end(); /* Stop any further batch file */
crlfflg = YES; /* processing and print the error */
eprintf(MSG_LABEL, label);
}
GLOBAL VOID CDECL cmd_return()
{
UWORD i;
if (!batchflg) return;
if (batch->ret_offset[0] == 0L) {
batch_end();
crlfflg = YES;
eprintf(MSG_RETURN);
return;
}
i = 0;
while ((batch->ret_offset[i] != 0L)&&(i<4)) i++;
batch->offset = batch->ret_offset[i-1];
batch->ret_offset[i-1] = 0L;
}
#if SWITCH_ENABLED
GLOBAL VOID CDECL cmd_switch(list)
REG BYTE *list;
{
BYTE *list_start;
BYTE *label;
WORD i,j;
BYTE c;
if (!batchflg) return;
list_start = list;
switch_retry:
list = list_start;
i = psp_poke(STDIN,1);
#if defined(CDOSTMP)
c =(BYTE) bdos(C_RAWIO, 0xFD); /* Get a character from console */
if ((c==0) ||(dbcs_lead(c)))
bdos(C_RAWIO, 0xFD); /* skip second byte in DBCS pair */
#else
c = (BYTE) msdos(MS_C_RAWIN, 0);/* Get a character from console */
if ((c==0) || (dbcs_lead(c)))
msdos(MS_C_RAWIN, 0); /* skip second byte in DBCS pair */
#endif
psp_poke(STDIN,i);
if (c==0x03) int_break(); /* check for CTRL-C */
if (c==0x0d) c = '1'; /* return gives default of 1 */
i = (WORD) (c - '1');
if (i<0 || i>8) goto switch_retry; /* ignore invalid keys */
j = 0;
while (j<i) {
while (*list != ',' && *list != 0) list++;
if (*list == 0) goto switch_retry;
j++;
list++;
list = deblank(list);
}
label = list;
while (*list != ',' && *list != 0) list++;
*list = 0;
cmd_gosub(label);
}
#endif
/*.pa*/
/*
* The IF command supports the following syntax:-
*
* IF [NOT] string1 == string2 COMMAND
* IF [NOT] ERRORLEVEL n COMMAND
* IF [NOT] EXIST filename COMMAND
/*RG-02-
* IF [NOT] USERID n COMMAND
* IF [NOT] LOGINNAME string COMMAND
* IF [NOT] GROUPNAME string COMMAND
* IF [NOT] KEY ["string"] char COMMAND
*
*/
#if defined(CDOSTMP) || defined(CDOS)
MLOCAL BYTE *if_opt[] = {"exist", "direxist", "errorlevel", "key", "userid", "loginname", "groupname", NULL };
#else
MLOCAL BYTE *if_opt[] = {"exist", "direxist", "errorlevel", NULL };
#endif
/*RG-02-end*/
MLOCAL UWORD if_index(cmd)
BYTE **cmd;
{
UWORD i, j;
for(i = 0; if_opt[i]; i++) { /* Scan Through the option */
j = strlen(if_opt[i]); /* list and return the index */
/* of the matching option */
if(strnicmp(*cmd, if_opt[i], j)) /* and update the string */
continue; /* pointer. */
*cmd = deblank(*cmd+j);
while(*(*cmd) == '=') /* Remove any "=" string */
(*cmd)++; /* present in the command */
*cmd = deblank(*cmd); /* Used by many install files*/
break;
}
return i;
}
#define OP_EQ 0
#define OP_NE 1
#define OP_LE 2
#define OP_LT 3
#define OP_GE 4
#define OP_GT 5
MLOCAL WORD get_operator(op)
BYTE *op;
{
if (op[0] == '=') return(OP_EQ);
if (op[0] == '!' && op[1] == '=') return(OP_NE);
if (op[0] == '<') {
if (op[1] == '>') return(OP_NE);
if (op[1] == '=') return(OP_LE);
return(OP_LT);
}
if (op[0] == '>') {
if (op[1] == '=') return(OP_GE);
return(OP_GT);
}
return(-1);
}
MLOCAL LONG get_decimal(s)
BYTE *s;
{
LONG total = 0;
if (*s == '#') s++;
while (*s>='0' && *s<='9') {
total *= 10;
total += (LONG) (*s-'0');
s++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -