325 lines
7.7 KiB
C++
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);
|
||
|
}
|
||
|
|