home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1996 February
/
VPR9602A.ISO
/
fwindows
/
tmedt090
/
toold101
/
xargs.c
< prev
Wrap
C/C++ Source or Header
|
1995-11-19
|
14KB
|
510 lines
#include <windows.h>
#include <io.h>
typedef LPSTR FAR *LPLPSTR;
LPLPSTR FAR PASCAL CreateArgs(LPSTR);
BOOL FAR PASCAL DeleteArgs(LPLPSTR);
#define SIZE 256
INT FAR PASCAL MakeArgument(HINSTANCE, LPSTR, LPSTR, LPINT, LPSTR, INT);
char **AllocWildArgument(int argc, char **argv);
int FreeWildArgument(char **wargs);
LPLPSTR FAR PASCAL CreateArgs(LPSTR lpszCmdParam)
{
int argc;
int aArgv[SIZE];
char *argv[SIZE];
char szReturn[SIZE*2];
char szPath[MAX_PATH];
char *pszFile;
char *pszPriod;
int i;
char **wargv = NULL;
/*------------------------*/
/* モジュール名を取得する */
/*------------------------*/
lstrcpy(szPath, lpszCmdParam);
pszFile = szPath;
pszPriod = strchr(pszFile, ' ');
if (pszPriod != NULL) *pszPriod = '\0';
/*----------------------------------------*/
/* 引数を作成する(ワイルドカード展開なし) */
/*----------------------------------------*/
argc = MakeArgument(NULL, pszFile, lpszCmdParam,
aArgv, szReturn, sizeof(szReturn));
for (i = 0; i <= argc; i++) {
argv[i] = szReturn + aArgv[i];
}
/*--------------------*/
/* ワイルドカード展開 */
/*--------------------*/
return AllocWildArgument(argc, argv);
}
BOOL FAR PASCAL DeleteArgs(LPLPSTR wargv)
{
return (FreeWildArgument(wargv) == 0) ? TRUE : FALSE;
}
char *cwStrrchr(char *s, int c)
{
unsigned char *p;
unsigned char *pr;
pr = NULL;
for (p = s; *p != '\0'; p++) {
/* for DBCS */
if (IsDBCSLeadByte(*p) == TRUE) {
p++;
if (*p == '\0') {
break;
}
continue;
}
if (*p == c) {
pr = p;
}
}
return pr;
}
/*--------------------------------------------*/
/* AllocWildArgument ワイルドカード展開を行う */
/*--------------------------------------------*/
char **AllocWildArgument(int argc, char **argv)
{
long lFind;
struct _finddata_t finddata;
int i;
char cStack;
char *pArgsNew;
char *pStr;
int nHeadLen;
int nBodyLen;
int nPos;
char **pArgv;
char *pArgs;
/*-------------------------------------------------------*/
/* 環境変数形式("arg0\0arg2\0arg3\0...argvx\0\0") に展開 */
/*-------------------------------------------------------*/
/*-------------------------------*/
/* 最初の引き数 (実行ファイル名) */
/*-------------------------------*/
nPos = 0;
nHeadLen = 0;
nBodyLen = strlen(argv[0]);
pArgsNew = malloc(nPos + nHeadLen + nBodyLen + 1);
if (pArgsNew == NULL) {
return NULL;
}
pArgs = pArgsNew;
strcpy(pArgs + nPos, argv[0]);
nPos += nHeadLen + nBodyLen + 1;
/*--------------------*/
/* ワイルドカード展開 */
/*--------------------*/
for (i = 1; i < argc; i++) {
/*--------------*/
/* ドライブ文字 */
/*--------------*/
if (lstrlen(argv[i]) == 2 && argv[i][1] == ':') {
nHeadLen = 0;
nBodyLen = strlen(argv[i]);
pArgsNew = realloc(pArgs, nPos + nHeadLen + nBodyLen + 1);
if (pArgsNew == NULL) {
free(pArgs);
return NULL;
}
pArgs = pArgsNew;
strcpy(pArgs + nPos, argv[i]);
nPos += nHeadLen + nBodyLen + 1;
continue;
}
finddata.attrib = _A_NORMAL;
lFind = _findfirst(argv[i], &finddata);
/*------------------------*/
/* ワイルドカード文字なし */
/*------------------------*/
if (lFind == -1 || cwStrrchr(argv[i], '*') == NULL &&
cwStrrchr(argv[1], '?') == NULL) {
nHeadLen = 0;
nBodyLen = strlen(argv[i]);
pArgsNew = realloc(pArgs, nPos + nHeadLen + nBodyLen + 1);
if (pArgsNew == NULL) {
free(pArgs);
return NULL;
}
pArgs = pArgsNew;
strcpy(pArgs + nPos, argv[i]);
nPos += nHeadLen + nBodyLen + 1;
continue;
}
/*------------------------*/
/* ワイルドカード文字あり */
/*------------------------*/
/*------------------------*/
/* ディレクトリ部分を分離 */
/*------------------------*/
pStr = cwStrrchr(argv[i], '\\');
if (pStr == NULL) {
pStr = cwStrrchr(argv[i], '/');
if (pStr == NULL) {
pStr = (argv[i][1] == ':') ? &argv[i][2] : &argv[i][0];
} else {
pStr++;
}
} else {
pStr++;
}
do {
if (lstrcmp(finddata.name, ".") == 0 ||
lstrcmp(finddata.name, "..") == 0) {
continue;
}
cStack = *pStr; *pStr = '\0';
/*--------------*/
/* 領域にコピー */
/*--------------*/
nHeadLen = strlen(argv[i]);
nBodyLen = strlen(finddata.name);
pArgsNew = realloc(pArgs, nPos + nHeadLen + nBodyLen + 1);
if (pArgsNew == NULL) {
free(pArgs);
return NULL;
}
pArgs = pArgsNew;
strcpy(pArgs + nPos, argv[i]);
strcat(pArgs + nPos, finddata.name);
nPos += nHeadLen + nBodyLen + 1;
*pStr = cStack;
} while (_findnext(lFind, &finddata) == 0);
_findclose(lFind);
}
/*-------------------------*/
/* 終端文字列を確保 ("\0") */
/*-------------------------*/
pArgs = realloc(pArgs, nPos + 1);
pArgs[nPos] = '\0';
/*--------------------------------*/
/* 環境変数形式から引数形式に変換 */
/*--------------------------------*/
for (i = 0, pStr = pArgs; *pStr != '\0'; i++, pStr += strlen(pStr) + 1);
pArgv = malloc((i + 1) * sizeof(char *));
if (pArgv == NULL) {
free(pArgs);
return NULL;
}
for (i = 0, pStr = pArgs; *pStr != '\0'; i++, pStr += strlen(pStr) + 1) {
pArgv[i] = pStr;
}
pArgv[i] = pStr;
return pArgv;
}
/*--------------------------------------------*/
/* ワイルドカード展開用に確保された領域を解放 */
/*--------------------------------------------*/
int FreeWildArgument(char **wargs)
{
if (wargs == NULL) {
return -1;
}
free(wargs[0]);
free(wargs);
return 0;
}
/*=============================================================*/
/*------------------------------------------------*/
/* 付録 << MakeArgument API >> */
/* コマンドラインの引き数を展開します。 */
/* ComWin からの引用です。日本語対応は不十分です。*/
/* "" で囲まれた文字列は一つのトークンです。 */
/* '^' をエスケープ文字として扱っています。 */
/*------------------------------------------------*/
/*------------------*/
/* 引き数を作成する */
/*------------------*/
static LPSTR SkipHat(LPSTR s)
{
s++;
if (*s != '\0') {
s++;
}
return s;
}
static LPSTR SkipSpace(LPSTR s)
{
while (*s != '\0') {
if (*s == ' ' || *s == '\t') {
s++;
} else {
break;
}
}
return s;
}
static LPSTR SearchSpace(LPSTR s)
{
while (*s != '\0') {
if (*s == ' ' || *s == '\t') {
break;
} else {
s++;
}
}
return s;
}
static int lstrcmpni(LPSTR s1, LPSTR s2, int nLength)
{
int i;
int c1, c2;
int cs1, cs2;
for (i = 0; i < nLength && *s1 != '\0' && *s2 != '\0'; i++, s1++, s2++) {
cs1 = (int)(unsigned char)*s1;
cs2 = (int)(unsigned char)*s2;
c1 = (cs1 < 'a') ? cs1 : cs1 - 'a' + 'A';
c2 = (cs2 < 'a') ? cs2 : cs2 - 'a' + 'A';
if (c1 != c2) {
return c2 - c1;
}
}
if (i == nLength) {
return 0;
}
return *s2 - *s1;
}
static LPSTR SearchDQuoto(LPSTR s)
{
s++;
while (*s != '\0') {
if (*s == '^') {
s = SkipHat(s);
} else if (*s == '\"') {
s++;
break;
} else {
s++;
}
}
return s;
}
static int GetLastChar(char *s)
{
int c;
unsigned char *p;
c = '\0';
for (p = s; *p != '\0'; p++) {
if (IsDBCSLeadByte(*p) == TRUE) {
c = '\0';
p++;
if (*p == '\0') {
break;
}
continue;
}
c = *p;
}
return c;
}
static BOOL CheckCutChar(int c)
{
switch (c) {
case '\0':
case ' ':
case '\t':
case '/':
case '\\':
case '.':
return TRUE;
default:
return FALSE;
}
}
static LPSTR ConvertHatChar(LPSTR lpStr, int nMode)
{
LPSTR lpSrc;
LPSTR lpDst;
int nSrc;
int nSrcNew;
int nSrcLen;
int nDst;
lpDst = lpStr;
nDst = 0;
for (lpSrc = lpStr; *lpSrc != '\0'; lpSrc += nSrcLen + 1) {
nSrcLen = lstrlen(lpSrc);
for (nSrc = 0; nSrc < nSrcLen; nSrc++) {
if (nMode == 1) {
if (lpSrc[nSrc] != '\"') {
lpDst[nDst] = lpSrc[nSrc]; nDst++;
continue;
}
nSrcNew = SearchDQuoto(&lpSrc[nSrc]) - lpSrc;
for (; nSrc < nSrcNew; nSrc++) {
if (lpSrc[nSrc] == '\"') {
continue;
}
if (lpSrc[nSrc] == '^') {
int nSrcNew2;
char cStack, cLast;
/* for non ASCII char set */
cStack = lpSrc[nSrc+1]; lpSrc[nSrc+1] = '\0';
cLast = GetLastChar(lpSrc);
lpSrc[nSrc+1] = cStack;
if (cLast != '^') {
lpDst[nDst] = lpSrc[nSrc]; nDst++;
continue;
}
nSrcNew2 = SkipHat(&lpSrc[nSrc]) - lpSrc;
for (nSrc++; nSrc < nSrcNew2; nSrc++) {
lpDst[nDst] = lpSrc[nSrc]; nDst++;
}
nSrc = nSrcNew2 - 1;
continue;
}
lpDst[nDst] = lpSrc[nSrc]; nDst++;
}
nSrc = nSrcNew - 1;
continue;
}
if (lpSrc[nSrc] == '\"') {
nSrcNew = SearchDQuoto(&lpSrc[nSrc]) - lpSrc;
for (; nSrc < nSrcNew; nSrc++) {
lpDst[nDst] = lpSrc[nSrc]; nDst++;
}
nSrc = nSrcNew - 1;
continue;
}
if (lpSrc[nSrc] == '^') {
char cStack, cLast;
/* for non ASCII char set */
cStack = lpSrc[nSrc+1]; lpSrc[nSrc+1] = '\0';
cLast = GetLastChar(lpSrc);
lpSrc[nSrc+1] = cStack;
if (cLast != '^') {
lpDst[nDst] = lpSrc[nSrc]; nDst++;
continue;
}
nSrcNew = SkipHat(&lpSrc[nSrc]) - lpSrc;
for (nSrc++; nSrc < nSrcNew; nSrc++) {
lpDst[nDst] = lpSrc[nSrc]; nDst++;
}
nSrc = nSrcNew - 1;
continue;
}
lpDst[nDst] = lpSrc[nSrc]; nDst++;
}
lpDst[nDst] = '\0'; nDst++;
}
lpDst[nDst] = '\0';
return lpDst;
}
static int GetArgument(LPSTR lpSrc, LPSTR lpReturn, int nSize)
{
LPSTR lpB;
LPSTR lpE;
LPSTR lpD;
lpD = lpReturn;
for (lpB = SkipSpace(lpSrc); *lpB != '\0'; lpB = SkipSpace(lpE)) {
lpE = (*lpB != '\"') ? SearchSpace(lpB) : SearchDQuoto(lpB);
if (lpReturn + nSize - 1 < lpD + (lpE - lpB)) {
break;
}
lstrcpyn(lpD, lpB, lpE - lpB + 1);
lpD += lpE - lpB; *lpD = '\0'; lpD++;
}
*lpD = '\0';
return 0;
}
int FAR PASCAL MakeArgument(HINSTANCE hInstance,
LPSTR lpCmd,
LPSTR lpParam,
LPINT lpArgv,
LPSTR lpRet,
int nSize)
{
LPSTR lpB;
LPSTR lpP;
LPSTR lpE;
LPSTR lpD;
int nArgc;
lpB = SkipSpace(lpCmd);
lpE = (*lpB != '\"') ? SearchSpace(lpB) : SearchDQuoto(lpB);
lpP = lpParam;
lpD = lpRet;
if (hInstance == NULL) {
lpP = SkipSpace(lpP);
if (lstrcmpni(lpB, lpP, lpE - lpB) == 0 &&
CheckCutChar(lpP[lpE - lpB]) == TRUE) {
if (lpRet + nSize - 1 < lpD + (lpE - lpB)) {
lpRet[0] = '\0';
lpArgv[0] = 0;
return 0;
}
lstrcpyn(lpD, lpB, lpE - lpB + 1);
lpP += lpE - lpB;
lpD += lpE - lpB; *lpD = '\0'; lpD++;
}
} else {
if (lpRet + nSize - 1 < lpD + (lpE - lpB)) {
lpRet[0] = '\0';
lpArgv[0] = 0;
return 0;
}
lstrcpyn(lpD, lpB, lpE - lpB + 1);
lpD += lpE - lpB; *lpD = '\0'; lpD++;
}
GetArgument(lpP, lpD, lpRet + nSize - lpD);
ConvertHatChar(lpRet, 1);
nArgc = 0;
for (lpD = lpRet; *lpD != '\0'; lpD += lstrlen(lpD) + 1) {
lpArgv[nArgc] = lpD - lpRet; nArgc++;
}
lpArgv[nArgc] = '\0';
return nArgc;
}
/*=============================================================*/