Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 1023 → Rev 1024

/svarcom/trunk/cmd/for.c
84,15 → 84,12
bzero(f, sizeof(*f));
strcpy(f->cmd, p->cmdline);
 
/* locate the %varname */
/* locate the %varname (single char) */
i = p->argoffset;
while (f->cmd[i] == ' ') i++;
if (f->cmd[i] != '%') goto INVALID_SYNTAX;
f->varname = i;
/* find the end of varname (space) */
while ((f->cmd[i] != ' ') && (f->cmd[i] != 0)) i++;
if (f->cmd[i] != ' ') goto INVALID_SYNTAX;
f->cmd[i++] = 0; /* terminate varname and move to next field */
if ((f->cmd[i] != '%') || (f->cmd[i+1] == ' ') || (f->cmd[i+2] != ' ')) goto INVALID_SYNTAX;
f->varname = f->cmd[i+1];
i += 3;
 
/* look (and skip) the "IN" part */
while (f->cmd[i] == ' ') i++;
104,7 → 101,7
if (f->cmd[i] != '(') goto INVALID_SYNTAX;
i++;
while (f->cmd[i] == ' ') i++;
f->curpat = i;
f->nextpat = i;
/* look for patterns end */
while ((f->cmd[i] != ')') && (f->cmd[i] != 0)) i++;
if (f->cmd[i] != ')') goto INVALID_SYNTAX;
/svarcom/trunk/command.c
762,7 → 762,88
}
 
 
/* process the ongoing forloop, returns 0 on success, non-zero otherwise (no
more things to process) */
static int forloop_process(char *res, struct forctx far *forloop) {
unsigned short i, t;
struct DTA *dta = (void *)0x80; /* default DTA at 80h in PSP */
 
TRYAGAIN:
 
/* dta_inited: FindFirst() or FindNext()? */
if (forloop->dta_inited == 0) {
 
/* copy next awaiting pattern to BUFFER */
for (i = 0;; i++) {
BUFFER[i] = forloop->cmd[forloop->nextpat + i];
/* end of patterns list */
if (BUFFER[i] == 0) break;
/* space found */
if (BUFFER[i] == ' ') {
BUFFER[i] = 0;
break;
}
}
 
if (i == 0) return(-1);
 
/* remember position of current pattern */
forloop->curpat = forloop->nextpat;
 
/* move nextpat forward to next pattern */
i += forloop->nextpat;
while (forloop->cmd[i] == ' ') i++;
forloop->nextpat = i;
 
/* FOR in MSDOS 6 includes hidden and system files, but not directories nor volumes */
if (findfirst(dta, BUFFER, DOS_ATTR_RO | DOS_ATTR_HID | DOS_ATTR_SYS | DOS_ATTR_ARC) != 0) {
goto TRYAGAIN;
}
forloop->dta_inited = 1;
} else { /* dta in progress */
 
/* copy forloop DTA to my local copy */
_fmemcpy(dta, &(forloop->dta), sizeof(*dta));
 
/* findnext() call */
if (findnext(dta) != 0) {
forloop->dta_inited = 0;
goto TRYAGAIN;
}
}
 
/* copy updated DTA to rmod */
_fmemcpy(&(forloop->dta), dta, sizeof(*dta));
 
/* fill res with command, replacing varname by actual filename */
/* full filename is to be built with path of curpat and fname from dta */
t = 0;
i = 0;
for (;;) {
if ((forloop->cmd[forloop->exec + t] == '%') && (forloop->cmd[forloop->exec + t + 1] == forloop->varname)) {
short lastbk = i;
char far *c = forloop->cmd + forloop->curpat;
for (;;) {
res[i] = *c;
c++;
if (res[i] == '\\') lastbk = i;
if ((res[i] == ' ') || (res[i] == 0)) break;
i++;
}
_fstrcpy(res + lastbk, dta->fname);
for (i = lastbk; res[i] != 0; i++);
t += 2;
} else {
res[i] = forloop->cmd[forloop->exec + t];
t++;
if (res[i++] == 0) break;
}
}
 
return(0);
}
 
 
int main(void) {
static struct config cfg;
static unsigned short far *rmod_envseg;
821,16 → 902,6
}
 
do {
/* am I inside a FOR loop? */
if (rmod->forloop) {
outputnl("FOR IS NOT IMPLEMENTED YET");
/* TODO dta_inited: FindFirst() or FindNext()? */
/* TODO read result */
/* TODO end of results? move to next pattern */
/* free used memory */
rmod_ffree(rmod->forloop);
rmod->forloop = NULL;
}
 
/* terminate previous command with a CR/LF if ECHO ON (but not during BAT processing) */
if ((rmod->flags & FLAG_ECHOFLAG) && (rmod->bat == NULL)) outputnl("");
846,6 → 917,23
/* (re)load translation strings if needed */
nls_langreload(BUFFER, *rmod_envseg);
 
/* am I inside a FOR loop? */
if (rmod->forloop) {
if (forloop_process(cmdlinebuf, rmod->forloop) != 0) {
rmod_ffree(rmod->forloop);
rmod->forloop = NULL;
} else {
/* output prompt and command on screen if echo on and command is not
* inhibiting it with the @ prefix */
if (rmod->flags & FLAG_ECHOFLAG) {
build_and_display_prompt(BUFFER, *rmod_envseg);
outputnl(cmdline);
}
/* jump to command processing */
goto EXEC_CMDLINE;
}
}
 
/* load awaiting command, if any (used to run piped commands) */
if (rmod->awaitingcmd[0] != 0) {
_fstrcpy(cmdline, rmod->awaitingcmd);
973,7 → 1061,7
 
/* repeat unless /C was asked - but always finish running an ongoing batch
* file (otherwise only first BAT command would be executed with /C) */
} while (((rmod->flags & FLAG_EXEC_AND_QUIT) == 0) || (rmod->bat != NULL));
} while (((rmod->flags & FLAG_EXEC_AND_QUIT) == 0) || (rmod->bat != NULL) || (rmod->forloop != NULL));
 
sayonara(rmod);
return(0);
/svarcom/trunk/history.txt
5,8 → 5,9
 
=== ver 2022.2 (xx.xx.xxxx) ==================================================
 
- added FOR support
- step-by-step execution of batch files (/Y)
- fixed parsing of /C and /K arguments that were leading to spurious warnings
- step-by-step execution of batch files (/Y)
- fixed %var% matching within batch files to be case-insensitive
 
 
/svarcom/trunk/rmodinit.h
48,10 → 48,11
/* for context structure used to track the execution of the ongoing FOR loop */
struct forctx {
char cmd[130]; /* copy of the original FOR command */
unsigned short varname; /* cmd offset of the replaceable variable name */
struct DTA dta; /* DTA for FindNext on current pattern */
unsigned short curpat; /* cmd offset of currently processed pattern */
unsigned short nextpat; /* cmd offset of next pattern to be processed */
unsigned short exec; /* cmd offset of the command to be executed */
struct DTA dta; /* DTA for FindNext on current pattern */
char varname; /* single char of variable name */
unsigned char dta_inited; /* 0=requires FindFirst 1=FindNext */
};
 
/svarcom/trunk/svarcom.txt
36,6 → 36,7
DIR - displays a list of files and subdirectories in a directory
ECHO - displays messages, or turns command-echoing on or off
EXIT - quits the command.com program (command interpreter)
FOR - runs a specified command for each file in a set of files
GOTO - directs batch processing to a labelled line in the batch program
IF - performs conditional processing in batch programs
LN - adds, deletes and displays global executable links