Category : C Source Code
Archive   : WILD_C.ZIP
Filename : WILD.C

 
Output of file : WILD.C contained in archive : WILD_C.ZIP
/*
| Extended command line processing for Turbo C
|
| (C)CopyRight Yuval Rakavy Israel 1987 All Rights Reserved.
|
| This file contains wildcard expansion for Turbo-C.
|
| for example: *.c will match all file names ending with .c
| \*\*.c will match all files in any directory directly below the
| root directory that end with .c
|
| To add wild-card expandsion to your program, just link the object
| produced from this file with your program.
|
| It is recomended to name the objects as:
|
| avt - Tiny module, avs - Small module etc.
|
| Any comments will be welcomed.
|
*/
#include
#include
#include
#include
#include
#include
#include

/* There are global from Turbo-C startup */
extern int __argc; /* Arg count */
extern char **__argv; /* Pointer to argument pointers vector */
extern unsigned _envseg; /* paragraph address of the enviornment */
extern int _envLng; /* Length of enviornment string */

int __argl; /* Total size of argument storage buffer */
char *__argloc; /* location of the argument storage buffer */

typedef char boolean;
#define TRUE 1
#define FALSE 0

static struct ffblk FileInfo;
static boolean CountArgs; /* TRUE in first pass, FALSE in the second */
static char *ArgLoc;
static int ArgIndex;

static Error(char *s) {
write(2, s, strlen(s));
write(2, "\n", 1);
_exit(1);
}

static NoMatchError(char far *ArgBegin) {
char Tmp[40], i;

for(i = 0; i < 40 && *ArgBegin > ' '; i++)
Tmp[i] = *ArgBegin++;
Tmp[i] = '\0';
strcat(Tmp, ": no match");
Error(Tmp);
}

/*
| ParseCommandLine:
|
| This procedure parses the command line as passed from DOS.
| This routine is called twice, in the first pass, the size and the
| number of arguments is calculated. In the second pass the arguments
| are copied to the allocated storage.
*/
static ParseCommandLine(void) {
int Delim;
char far *Cmd = (char far *)MK_FP(_psp, 0x80);
char far *LastWildCardArg = NULL, far *ArgBegining;
int CommandLength = (int)*Cmd++;
int Length;
char ArgBuffer[128], *Arg;
extern void ExpandWildCards(char *Pattern);
extern void AddArg(boolean Match, char *Arg);
extern boolean HasWildCards(char *Name);
boolean WildCardArg = FALSE;
int FirstWildCardIndex = 0;

for(Length = 0; Length < CommandLength; ) {

for(; Length < CommandLength && (*Cmd == ' ' || *Cmd == '\t');
Length++)
Cmd++;

if(Length >= CommandLength || *Cmd < ' ')
break;

/* Quoted argument */
if(*Cmd == '\'' || *Cmd == '"') {
if(CountArgs && WildCardArg && FirstWildCardIndex == __argc)
NoMatchError(LastWildCardArg);
WildCardArg = FALSE;

Delim = *Cmd++;
Length++;

for(Arg = ArgBuffer; Length < CommandLength &&
*Cmd != Delim; Cmd++, Length++)
*Arg++ = *Cmd;

*Arg = 0;

if(Length >= CommandLength)
Error("Unterminated quoted argument");

Cmd++;
Length++;

AddArg(FALSE, ArgBuffer);
}
else {
ArgBegining = Cmd;
for(Arg = ArgBuffer; Length < CommandLength &&
*Cmd != ' ' && *Cmd != '\t'; Cmd++, Length++)
*Arg++ = *Cmd;
*Arg = 0;

if(HasWildCards(ArgBuffer)) {
if(!WildCardArg)
FirstWildCardIndex = __argc;
WildCardArg = TRUE;
LastWildCardArg = ArgBegining;
ExpandWildCards(ArgBuffer);
}
else {
if(CountArgs && WildCardArg && FirstWildCardIndex == __argc)
NoMatchError(LastWildCardArg);
WildCardArg = FALSE;
AddArg(FALSE, ArgBuffer);
}
}
}

if(CountArgs && WildCardArg && FirstWildCardIndex == __argc)
NoMatchError(LastWildCardArg);
}

static boolean HasWildCards(char *Name) {
for(; *Name; Name++)
if(*Name == '*' || *Name == '?')
return TRUE;
return FALSE;
}

/*
| FindFile:
|
| Initiate directory search for files matching Template if Template is
| not NULL, or continue the previous search if Template is NULL.
*/
static FindFile(char *Template) {
int Result;

if(Template)
return findfirst(Template, &FileInfo, FA_RDONLY|FA_DIREC);
else
return findnext(&FileInfo);
}

static void *GetMemory(unsigned Amount) {
void *p;

if((p = malloc(Amount)) == NULL)
Error("Argument expansion: Out of memory");
return p;
}

static char *NewCopy(char *String) {
char *p = (char *)GetMemory(strlen(String)+1);

strcpy(p, String);
return p;
}

static char *BuildPathName(char *Buf, char *Path, char *Tail) {
strcpy(Buf, Path);
strcat(Buf, "\\");
strcat(Buf, Tail);
return Buf;
}

/*
| Get attribute of a given file
|
| The function returns -1 in case of error
*/
static getmod(char *Name) {
union REGS r;

r.x.dx = (int)Name;
r.h.al = 0;
r.h.ah = 0x43;
intdos(&r, &r);
if(r.x.cflag)
return(-1);
else
return(r.x.cx);
}

static void SortArgs(int First, int Last) {
int i;
char *Temp;

/* Use simple selection sort */
for(; First < Last; First++) {
for(i = First+1; i < Last; i++) {
if(strcmp(__argv[First], __argv[i]) > 0) {
Temp = __argv[First];
__argv[First] = __argv[i];
__argv[i] = Temp;
}
}
}
}

/*
| AddArg: Add an arguments.
|
| On the first pass, the size of the argument is accumlated. In the second
| pass the argument is actually copied to the storage buffer
*/
static void AddArg(boolean Match, char *ArgName) {
char ArgBuffer[64], *b, *a;
static int StartMatch;
static boolean PrevMatch = FALSE;

if(Match) {
a = ArgName;
b = ArgBuffer;

if(a[1] == ':') {
*b++ = *a++;
*b++ = *a++;
}

if(a[0] == '.' && a[1] == '\\')
a += 2;
for(; *a; a++)
*b++ = *a;
*b = 0;
strlwr(ArgBuffer);
ArgName = ArgBuffer;
}

if(CountArgs) {
__argc++;
__argl += strlen(ArgName) + 1; /* One for the '\0' */
}
else {

if(ArgName != NULL) {
__argv[ArgIndex++] = ArgLoc;
/* Copy the argument */
for(a = ArgName; *a; a++)
*ArgLoc++ = *a;
*ArgLoc++ = '\0';
}
else
__argv[ArgIndex++] = NULL;


if(PrevMatch != Match) {
if(Match)
StartMatch = ArgIndex-1; /* First location on match */
else
SortArgs(StartMatch, ArgIndex-1);
}

PrevMatch = Match;
}
}

static DoMatch(char **Prefixes, char *Pattern) {
char *Pat, **NewPrefix, *Name;
boolean NoMoreDirectories;
int Nprefix, i, NewIndex, a;
static char NewPrefixBuf[64], *OnePrefix[2];

for(Pat = Pattern; *Pat && *Pat != '\\' && *Pat != '/'; Pat++)
;

NoMoreDirectories = (*Pat == '\0') ? TRUE : FALSE;
*Pat++ = '\0';

if(!NoMoreDirectories) {
/* If not last level count the number of new prefixes */

for(i = 0; Prefixes[i] != NULL; i++) {
BuildPathName(NewPrefixBuf, Prefixes[i], Pattern);

if(!HasWildCards(Pattern)) {
if((a = getmod(NewPrefixBuf)) >= 0 && (a & FA_DIREC)) {
OnePrefix[0] = NewCopy(NewPrefixBuf);
OnePrefix[1] = NULL;
DoMatch(OnePrefix, Pat);
free(OnePrefix[0]);
}
}
else {
Name = BuildPathName(NewPrefixBuf, Prefixes[i], Pattern);

Nprefix = 0;

while(FindFile(Name) >= 0) {
BuildPathName(NewPrefixBuf,Prefixes[i], FileInfo.ff_name);
if((getmod(NewPrefixBuf) & FA_DIREC) &&
FileInfo.ff_name[0] != '.')
Nprefix++;
Name = NULL;
}

Name = BuildPathName(NewPrefixBuf, Prefixes[i], Pattern);

if(Nprefix > 0) {
NewPrefix=(char **)GetMemory(sizeof(char *) *(Nprefix+1));
Name = NewPrefixBuf;
NewIndex = 0;

while(FindFile(Name) >= 0) {
BuildPathName(NewPrefixBuf, Prefixes[i],
FileInfo.ff_name);
if((getmod(NewPrefixBuf) & FA_DIREC) &&
FileInfo.ff_name[0] != '.')
NewPrefix[NewIndex++] = NewCopy(NewPrefixBuf);
Name = NULL;
}

NewPrefix[NewIndex++] = NULL;
DoMatch(NewPrefix, Pat);

for(NewIndex = 0; NewPrefix[NewIndex] != NULL; NewIndex++)
free(NewPrefix[NewIndex]);
free(NewPrefix);
}
}
}
}
else {
/* Last level */
for(i = 0; Prefixes[i] != NULL; i++) {
BuildPathName(NewPrefixBuf, Prefixes[i], Pattern);

if(!HasWildCards(Pattern) && getmod(NewPrefixBuf) >= 0)
AddArg(TRUE, NewPrefixBuf);
else {
Name = BuildPathName(NewPrefixBuf, Prefixes[i], Pattern);

while(FindFile(Name) >= 0) {
AddArg(TRUE, BuildPathName(NewPrefixBuf, Prefixes[i],
FileInfo.ff_name));
Name = NULL;
}
}
}
}
}

static void ExpandWildCards(char *Pattern) {
char *OnePrefix[2], Prefix[5], *p = Prefix;

if(Pattern[1] == ':') {
*p++ = *Pattern++;
*p++ = *Pattern++;
}
if(*Pattern != '/' && *Pattern != '\\')
*p++ = '.';
else
Pattern++;
*p = '\0';

OnePrefix[0] = Prefix;
OnePrefix[1] = NULL;
DoMatch(OnePrefix, Pattern);
}

static FindArg0length() {
char far *p;
int i;

if(_osmajor < 3)
return 2;
else {
p = (char far *)MK_FP(_envseg, _envLng+2);
for(i = 0; i < 100 && *p; p++)
i++;
if(i == 100)
Error("Bad arg0");
return i+1;
}
}

static CopyArg0() {
char far *p = (char far *)MK_FP(_envseg, _envLng+2);
int i;

if(_osmajor < 3)
*ArgLoc++ = 'C';
else {
for(; *p; p++)
*ArgLoc++ = *p;
}
*ArgLoc++ = '\0';
}

_setargv(void) {
CountArgs = TRUE;
__argl = FindArg0length();
__argc = 1;
ParseCommandLine();

__argv = (char **)GetMemory(sizeof(char *) * (__argc+2));
ArgLoc = __argloc = (char *)GetMemory(__argl);
ArgIndex = 0;

__argv[ArgIndex++] = ArgLoc;
CopyArg0();
strlwr(__argv[0]);

CountArgs = FALSE;
ParseCommandLine();
AddArg(FALSE, NULL);
}


  3 Responses to “Category : C Source Code
Archive   : WILD_C.ZIP
Filename : WILD.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/