⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 batch.c

📁 一个dos操作系统DRDOS的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -