windows-nt/Source/XPSP1/NT/shell/tools/cleaninf/app.cpp
2020-09-26 16:20:57 +08:00

325 lines
7.7 KiB
C++

#include "priv.h"
HINSTANCE g_hinst;
#define APP_VERSION "Version 0.4"
// Don't link to shlwapi.dll so this is a stand-alone tool
/*----------------------------------------------------------
Purpose: If a path is contained in quotes then remove them.
*/
void
PathUnquoteSpaces(
LPTSTR lpsz)
{
int cch;
cch = lstrlen(lpsz);
// Are the first and last chars quotes?
if (lpsz[0] == TEXT('"') && lpsz[cch-1] == TEXT('"'))
{
// Yep, remove them.
lpsz[cch-1] = TEXT('\0');
hmemcpy(lpsz, lpsz+1, (cch-1) * SIZEOF(TCHAR));
}
}
#define CH_WHACK TEXT(FILENAME_SEPARATOR)
LPTSTR
PathFindExtension(
LPCTSTR pszPath)
{
LPCTSTR pszDot = NULL;
if (pszPath)
{
for (; *pszPath; pszPath = CharNext(pszPath))
{
switch (*pszPath) {
case TEXT('.'):
pszDot = pszPath; // remember the last dot
break;
case CH_WHACK:
case TEXT(' '): // extensions can't have spaces
pszDot = NULL; // forget last dot, it was in a directory
break;
}
}
}
// if we found the extension, return ptr to the dot, else
// ptr to end of the string (NULL extension) (cast->non const)
return pszDot ? (LPTSTR)pszDot : (LPTSTR)pszPath;
}
__inline BOOL ChrCmpA_inline(WORD w1, WORD wMatch)
{
/* Most of the time this won't match, so test it first for speed.
*/
if (LOBYTE(w1) == LOBYTE(wMatch))
{
if (IsDBCSLeadByte(LOBYTE(w1)))
{
return(w1 != wMatch);
}
return FALSE;
}
return TRUE;
}
LPSTR FAR PASCAL StrChrA(LPCSTR lpStart, WORD wMatch)
{
for ( ; *lpStart; lpStart = AnsiNext(lpStart))
{
if (!ChrCmpA_inline(*(UNALIGNED WORD FAR *)lpStart, wMatch))
return((LPSTR)lpStart);
}
return (NULL);
}
BOOL
StrTrim(
IN OUT LPSTR pszTrimMe,
IN LPCSTR pszTrimChars)
{
BOOL bRet = FALSE;
LPSTR psz;
LPSTR pszStartMeat;
LPSTR pszMark = NULL;
ASSERT(IS_VALID_STRING_PTRA(pszTrimMe, -1));
ASSERT(IS_VALID_STRING_PTRA(pszTrimChars, -1));
if (pszTrimMe)
{
/* Trim leading characters. */
psz = pszTrimMe;
while (*psz && StrChrA(pszTrimChars, *psz))
psz = CharNextA(psz);
pszStartMeat = psz;
/* Trim trailing characters. */
// (The old algorithm used to start from the end and go
// backwards, but that is piggy because DBCS version of
// CharPrev iterates from the beginning of the string
// on every call.)
while (*psz)
{
if (StrChrA(pszTrimChars, *psz))
{
pszMark = psz;
}
else
{
pszMark = NULL;
}
psz = CharNextA(psz);
}
// Any trailing characters to clip?
if (pszMark)
{
// Yes
*pszMark = '\0';
bRet = TRUE;
}
/* Relocate stripped string. */
if (pszStartMeat > pszTrimMe)
{
/* (+ 1) for null terminator. */
MoveMemory(pszTrimMe, pszStartMeat, CbFromCchA(lstrlenA(pszStartMeat) + 1));
bRet = TRUE;
}
else
ASSERT(pszStartMeat == pszTrimMe);
ASSERT(IS_VALID_STRING_PTRA(pszTrimMe, -1));
}
return bRet;
}
void PrintSyntax(void)
{
fprintf(stderr, "cleaninf.exe " APP_VERSION "\n\n"
"Cleans up an inf, html, or script file for public distribution or for packing\n"
"into a resource. Without any options, this removes all comments. This\n"
"tool recognizes .inf, .htm, .hta, .js and .htc files by default.\n\n"
"Syntax: cleaninf [-w] [-inf | -htm | -js | -htc] sourceFile destFile\n\n"
" -w Strip whitespace\n\n"
" These flags are mutually exclusive, and will treat the file\n"
" accordingly, regardless of extension:\n"
" -inf Treat file as a .inf file\n"
" -htm Treat file as a .htm file\n"
" -js Treat file as a .js file\n"
" -htc Treat file as a .htc file\n");
}
/*----------------------------------------------------------
Purpose: Worker function to do the work
*/
int
DoWork(int cArgs, char * rgszArgs[])
{
LPSTR psz;
LPSTR pszSrc = NULL;
LPSTR pszDest = NULL;
DWORD dwFlags = 0;
int i;
int nRet = 0;
// (The first arg is actually the exe. Skip that.)
for (i = 1; i < cArgs; i++)
{
psz = rgszArgs[i];
// Check for options
if ('/' == *psz || '-' == *psz)
{
psz++;
switch (*psz)
{
case '?':
// Help
PrintSyntax();
return 0;
case 'w':
dwFlags |= PFF_WHITESPACE;
break;
default:
if (0 == strncmp(psz, "inf", 3))
{
dwFlags |= PFF_INF;
}
else if (0 == strncmp(psz, "htm", 3))
{
dwFlags |= PFF_HTML;
}
else if (0 == strncmp(psz, "js", 2))
{
dwFlags |= PFF_JS;
}
else if (0 == strncmp(psz, "htc", 3))
{
dwFlags |= PFF_HTC;
}
else
{
// unknown
fprintf(stderr, "Invalid option -%c\n", *psz);
return -1;
}
break;
}
}
else if (!pszSrc)
pszSrc = rgszArgs[i];
else if (!pszDest)
pszDest = rgszArgs[i];
else
{
fprintf(stderr, "Ignoring invalid parameter - %s\n", rgszArgs[i]);
}
}
if (!pszSrc || !pszDest)
{
PrintSyntax();
return -2;
}
// Has the file type already been explicitly specified?
if ( !(dwFlags & (PFF_INF | PFF_HTML | PFF_JS | PFF_HTC)) )
{
// No; determine it based on the extension
LPTSTR pszExt = PathFindExtension(pszSrc);
if (pszExt)
{
if (0 == lstrcmpi(pszExt, ".htm") || 0 == lstrcmpi(pszExt, ".hta"))
dwFlags |= PFF_HTML;
else if (0 == lstrcmpi(pszExt, ".js"))
dwFlags |= PFF_JS;
else if (0 == lstrcmpi(pszExt, ".htc"))
dwFlags |= PFF_HTC;
}
}
// Open the files
PathUnquoteSpaces(pszSrc);
PathUnquoteSpaces(pszDest);
FILE * pfileSrc = fopen(pszSrc, "r");
if (NULL == pfileSrc)
{
fprintf(stderr, "\"%s\" could not be opened", pszSrc);
nRet = -3;
}
else
{
FILE * pfileDest = fopen(pszDest, "w");
if (NULL == pfileDest)
{
fprintf(stderr, "\"%s\" could not be created", pszDest);
nRet = -4;
}
else
{
CParseFile parsefile;
parsefile.Parse(pfileSrc, pfileDest, dwFlags);
fclose(pfileDest);
}
fclose(pfileSrc);
}
return nRet;
}
#ifdef UNIX
EXTERN_C
HINSTANCE MwMainwinInitLite(int argc, char *argv[], void* lParam);
EXTERN_C
HINSTANCE mainwin_init(int argc, char *argv[])
{
return MwMainwinInitLite(argc, argv, NULL);
}
#endif
int __cdecl main(int argc, char * argv[])
{
return DoWork(argc, argv);
}