?? pname.c
字號:
/*** pname.c - form a "pretty" version of a user file name
*
* OS/2 v1.2 and later will allow filenames to retain the case
* when created while still being case insensitive for all operations.
* This allows the user to create more visually appealing file names.
*
* All runtime routines should, therefore, preserve the case that was
* input. Since the user may not have input in the case that the entries
* were created, we provide a service whereby a pathname is adjusted
* to be more visually appealing. The rules are:
*
* if (real mode)
* lowercase the sucker
* else
* if (version is <= 1.1)
* lowercase the sucker
* else
* if (filesystem is FAT)
* lowercase the sucker
* else
* for each component starting at the root, use DosFindFirst
* to retrieve the original case of the name.
*
* Modifications:
* 10-Oct-1989 mz First implementation
*
*/
#if defined (OS2)
#define INCL_ERRORS
#define INCL_DOSFILEMGR
#define INCL_DOSMODULEMGR
#include <os2.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "..\h\tools.h"
char *pname (char *pszName)
{
#if defined (DOS)
return strlwr (pszName);
#else
if (!IsMixedCaseSupported (pszName))
return strlwr (pszName);
/* The underlying file system supports mixed case. Iterate through
* the path doing find-firsts to elicit the correct case from the
* file system
*/
{
#if defined(OS2)
HDIR hdir;
FILEFINDBUF findbuf;
#elif defined(NT)
HANDLE hdir;
WIN32_FIND_DATA findbuf;
#endif
unsigned int cFound;
char *pszSrc, *pszDst, *pszEnd, chEnd;
/* skip drive and leading / if present */
pszDst = pszName;
if (pszDst[1] == ':')
pszDst += 2;
/* We skip to first filename component. If the path is UNC, then
* we skip over machine name and sharename and LC them.
*/
if (fPathChr (*pszDst)) {
pszDst++;
if (fPathChr (*pszDst)) {
pszDst = strbscan (pszDst + 1, "/\\");
if (*pszDst != '\0')
pszDst = strbscan (pszDst + 1, "/\\");
/* pszDst points to the slash following the share name or
* points to '\0' for mere computer or computer\share
*/
chEnd = *pszDst;
*pszDst = '\0';
strlwr (pszName);
if ((*pszDst++ = chEnd) == '\0')
return pszName;
}
}
/* If we are pointing at the root, just give up
*/
if (*pszDst == '\0')
return pszName;
/* pszDst points to first char of first component
*/
pszSrc = pszDst;
while (TRUE) {
/* Find and terminate next component after pszSrc
*/
pszEnd = strbscan (pszSrc, "/\\");
chEnd = *pszEnd;
*pszEnd = 0;
/* Pack next component up against pszDst
*/
strcpy (pszDst, pszSrc);
/* Use DosFindFirst to return "canonical" case-correct
* version of last component EXCEPT if meta chars present
*/
#if defined(OS2)
hdir = HDIR_CREATE;
#endif
cFound = 1;
if (*strbscan (pszDst, "*?") == 0 &&
strcmp (pszDst, ".") && strcmp (pszDst, "..") &&
#if defined(OS2)
DosFindFirst2 (pszName,
&hdir,
FILE_HIDDEN + FILE_SYSTEM + FILE_DIRECTORY,
&findbuf,
sizeof (findbuf),
&cFound,
FIL_STANDARD,
0L) == 0
#elif defined(NT)
( ( hdir = FindFirstFile( pszName, &findbuf ) ) != (HANDLE)-1 )
#endif
) {
/* The entry was found and is valid. Go and
* copy it from the returned buffer
*/
#if defined(OS2)
#define FOUNDNAME findbuf.achName
#elif defined(NT)
#define FOUNDNAME findbuf.cFileName
#endif
strcpy (pszDst, FOUNDNAME);
/* Release search handle
*/
#if defined(OS2)
#define CLOSEFIND DosFindClose
#elif defined(NT)
#define CLOSEFIND FindClose
#endif
CLOSEFIND (hdir);
}
else
/* Meta char present or search did not find file
* Just leave it alone
*/
;
/* pszName points to name being constructed
* pszDst points to correctly-formed last component
* chEnd contains character that terminated last component
* pszEnd is where chEnd was retrieved from
*/
/* Terminate newly found component
*/
pszDst += strlen (pszDst);
*pszDst++ = '\\';
/* If we were at end of string,
* then we're all done
*/
if (chEnd == '\0') {
pszDst[-1] = '\0';
break;
}
/* Set pszSrc to point to beginning of next component
* We can do this because we haven't seen a terminating NUL
*/
pszSrc = pszEnd + 1;
}
return pszName;
}
#endif
}
#if defined (OS2) || defined(NT)
/* IsMixedCaseSupported - determine if a file system supports mixed case
*
* We presume that all OS's prior to OS/2 1.2 or FAT filesystems
* do not support mixed case. It is up to the client to figure
* out what to do.
*
* We presume that non FAT filesystems on 1.2 and later DO support mixed
* case
*
* We do some caching to prevent redundant calls to the file systems.
*
* returns TRUE (MCA_SUPPORT) if it is supported
* FALSE (MCA_NOTSUPP) if unsupported
*
*/
#define MCA_UNINIT 123
#define MCA_SUPPORT TRUE
#define MCA_NOTSUPP FALSE
static USHORT mca[27] = { MCA_UNINIT, MCA_UNINIT, MCA_UNINIT,
MCA_UNINIT, MCA_UNINIT, MCA_UNINIT,
MCA_UNINIT, MCA_UNINIT, MCA_UNINIT,
MCA_UNINIT, MCA_UNINIT, MCA_UNINIT,
MCA_UNINIT, MCA_UNINIT, MCA_UNINIT,
MCA_UNINIT, MCA_UNINIT, MCA_UNINIT,
MCA_UNINIT, MCA_UNINIT, MCA_UNINIT,
MCA_UNINIT, MCA_UNINIT, MCA_UNINIT,
MCA_UNINIT, MCA_UNINIT, MCA_UNINIT };
USHORT (pascal far *pDosQPathInfo) (PSZ, USHORT, PBYTE, USHORT, ULONG);
USHORT static QueryMixedCaseSupport (char *psz)
{
#if defined(NT)
psz; //unreferenced
return MCA_NOTSUPP;
#elif defined(OS2)
UCHAR *pUpdPath;
FILESTATUS fsts;
USHORT erc;
/* If OS/2 before 1.2, presume no mixed case support
*/
if (_osmajor < 10 || (_osmajor == 10 && _osminor < 2))
return MCA_NOTSUPP;
/* Attach to v1.2 function
*/
if (pDosQPathInfo == NULL) {
HMODULE hmod;
if (DosGetModHandle ("DOSCALLS", &hmod) != 0)
return MCA_NOTSUPP;
if (DosGetProcAddr (hmod, "#98", (PPFN) &pDosQPathInfo) != 0) {
pDosQPathInfo = NULL;
return MCA_NOTSUPP;
}
}
pUpdPath = (*tools_alloc) (MAXPATHLEN);
if (pUpdPath == NULL)
return MCA_NOTSUPP;
/* Replace lowest path component with "." to force a directory
*/
upd (psz, ".", pUpdPath);
/* Retrieve timestamp info
*/
erc = (*pDosQPathInfo) (pUpdPath,
FIL_STANDARD,
(PBYTE) &fsts,
sizeof (fsts),
0L);
free (pUpdPath);
/* If no error and if there was a creation time on the dir
* then we presume the mixed case is supported
*/
if (erc == NO_ERROR && MAKETYPE (fsts.fdateCreation, USHORT) != 0)
return MCA_SUPPORT;
else
return MCA_NOTSUPP;
#endif
}
USHORT IsMixedCaseSupported (char *psz)
{
USHORT mcaSupp;
unsigned int uDrvOrd;
BOOL fUNC;
#if defined (OS2)
ULONG ulDrvMap;
#endif
fUNC = (fPathChr (psz[0]) && fPathChr (psz[1])) ||
(psz[0] != 0 && psz[1] == ':' &&
fPathChr (psz[2]) && fPathChr (psz[3]));
/* Obtain drive ordinal and return cached value if valid
*/
if (!fUNC) {
if (psz[0] != 0 && psz[1] == ':')
uDrvOrd = (psz[0] | 0x20) - 'a' + 1;
else {
#if defined (OS2)
DosQCurDisk (&uDrvOrd, &ulDrvMap);
#elif defined(NT)
char buf[5];
GetCurrentDirectory( 5, buf );
uDrvOrd = ( buf[0] | 0x20 ) - 'a' + 1;
#endif
}
if (mca[uDrvOrd] != MCA_UNINIT)
return mca[uDrvOrd];
}
/* Get support value
*/
mcaSupp = QueryMixedCaseSupport (psz);
if (!fUNC)
mca[uDrvOrd] = mcaSupp;
return mcaSupp;
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -