home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Win32 Under the API
/
ProgrammingWin32UnderTheApiPatVillani.iso
/
Chapter9
/
cmd32
/
Scan.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-11
|
6KB
|
318 lines
/****************************************************************/
/* */
/* scan.c */
/* */
/* command.com lexical support */
/* */
/* Copyright (c) 2000 */
/* Pasquale J. Villani */
/* All Rights Reserved */
/* */
/* This file is part of CMD32. */
/* */
/* CMD32 is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version. */
/* */
/* CMD32 is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
/* the GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public */
/* License along with CMD32; see the file COPYING. If not, */
/* write to the Free Software Foundation, 675 Mass Ave, */
/* Cambridge, MA 02139, USA. */
/****************************************************************/
/* $Logfile$ */
/* $Log$
* $EndLog$ */
#ifdef VERSION_STRINGS
static char *RcsId = "$Header$";
#endif
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "globals.h"
/* #include "proto.h" */
BYTE *skipwh(BYTE *s);
INT tonum(INT c)
{
INT i;
for(i = 0; i < 9; i++)
{
if(c == "0123456789"[i])
return i;
}
return 0;
}
void expand(BYTE *d, BYTE *s)
{
INT idx, bufidx;
BYTE buffer[MAX_CMDLINE];
*d = '\0';
while(*s)
{
if(*s == '%' && isdigit(s[1]))
{
idx = tonum(*++s);
idx = (idx == 0 ? 0 : idx + shift_offset);
strcpy(d, posparam[idx]);
d += strlen(posparam[idx]);
while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t' || *s == '%'))
++s;
}
else if(*s == '%' && *(s + 1) == '%')
{
/* swallow one % save the other */
*d++ = *s++;
s++;
}
else if(*s == '%')
{
/* get passed the % */
++s;
/* buffer until next %, see if string between the */
/* is an environment variable */
/* if lp iswhite its not an env var, if its % */
/* then look in env and substitute if found */
bufidx = 0;
while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t' || *s == '%'))
{
buffer[bufidx++] = *s++;
buffer[bufidx] = '\0';
}
if(*s != '%')
{
/* can't be env variable so add to cmd line */
*d++ = '%';
strcpy(d, buffer);
d += strlen(buffer);
}
else
{
/* lookup and substitiue */
/* get passed ending % */
strcpy(d, getenv(buffer));
d += strlen(getenv(buffer));
s++;
}
}
else
{
*d++ = *s++;
*d = '\0';
}
}
}
void expandspl(BYTE *s, BYTE *d, INT var, BYTE *sub)
{
while(*s)
{
if(*s == '%' && s[1] == var)
{
strcpy(d, sub);
d += strlen(sub);
while(*s == '%')
++s;
while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t' || *s == '%'))
++s;
}
if((*s == '%' && s[1] != var)
|| (*s == '%' && s[1] == '%' && s[2] != var))
{
++s; /* Throw away leading % */
*d++ = *s++;
*d = '\0';
}
else
{
*d++ = *s++;
*d = '\0';
}
}
}
BYTE *scan(BYTE *s, BYTE *d)
{
s = skipwh(s);
if(batch_FLAG && *s == '%' && isdigit(s[1]))
{
strcpy(d, posparam[tonum(s[1])]);
s += 2;
return s;
}
while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t'))
*d++ = *s++;
*d = '\0';
return s;
}
BYTE *scanspl(BYTE *s, BYTE *d, INT c)
{
s = skipwh(s);
while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t' || *s == '%' || *s == c))
*d++ = *s++;
*d = '\0';
return s;
}
BYTE *skipwh(BYTE *s)
{
while(*s && (*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t'))
++s;
return s;
}
BYTE *scan_seperator(BYTE *s, BYTE *d)
{
s = skipwh(s);
if(*s)
*d++ = *s++;
*d = '\0';
return s;
}
/*
* [d:][path]name
*
* d: = [A-Za-z]':'
*
* path = ".\" |
* "..\" |
* ".\" string |
* "..\" string |
* "\" |
* '\' string |
* string '\' |
*/
BYTE *scan_name(BYTE *pszSrc, BYTE *pszDrive, BYTE *pszPath, BYTE *pszName)
{
BYTE *pszEnd, *pszRoot = "\\";
/* Initialize the destinations with "", just in case we don't do */
/* anything with them */
if(pszDrive)
{
*pszDrive = '\0';
}
if(pszPath)
{
*pszPath = '\0';
}
if(pszName)
{
*pszName = '\0';
}
/* Check for a drive specifier and strip it off if there */
if(isalpha(*pszSrc) && (*(pszSrc + 1) == ':'))
{
if(pszDrive)
{
*pszDrive++ = *pszSrc;
}
++pszSrc;
++pszSrc;
}
/* There's a special case of only root. Test for it and copy it to the path */
/* variable */
if((*pszSrc == '\\') && (!pszSrc[1] || isspace(pszSrc[1])))
{
if(pszPath)
{
strcpy(pszPath, pszRoot);
}
/* There can't be a name following, so initialize it to null string */
if(pszName)
{
*pszName = '\0';
}
return ++pszSrc;
}
/* Look for the last path separator and use it to decide if we have */
/* path or not */
if(((pszEnd = strrchr(pszSrc, '\\')) != NULL) && (pszEnd >= pszSrc))
{
/* Is it root? */
if(pszSrc == pszEnd)
{
if(pszPath)
{
strcpy(pszPath, pszRoot);
++pszSrc;
}
}
else
{
while(*pszSrc && (pszSrc < pszEnd))
{
if(pszPath)
{
*pszPath++ = *pszSrc;
*pszPath = '\0';
}
++pszSrc;
}
}
}
/*
* If we're here, we're either at a '\' character or we only have a pattern
* alone. So we want to figure out if there's a name following or not
*/
if(*pszSrc == '\\')
{
++pszSrc;
}
if(pszName)
{
*pszName = '\0';
}
while(*pszSrc && !isspace(*pszSrc))
{
if(pszName)
{
*pszName++ = *pszSrc;
*pszName = '\0';
}
++pszSrc;
}
/* Done. Return where we ended so that we scan further, if necessary. */
return pszSrc;
}