📄 pathlib.c
字号:
BOOL slashEnd = FALSE; /* Does destString end with a slash? */ if (len >= MAX_FILENAME_LENGTH) { errnoSet (S_ioLib_NAME_TOO_LONG); return (ERROR); } if ((len > 0) && (destString [len - 1] != '/') && (destString [len - 1] != '\\')) { /* if string contains part of a path name and it doesn't end with a '/' * or '\', then slash terminate it */ destString [len] = '/'; destString [len + 1] = EOS; slashEnd = TRUE; } /* * Added a test to make sure pp is non-NULL before checking * that *pp is not EOS. */ for (pp = nameArray; (pp != NULL) && (*pp != NULL) && (pp != nameArrayEnd); pp++) { if (**pp != EOS) { if (newlen = (len + strlen (*pp) + 1) > MAX_FILENAME_LENGTH) { errnoSet (S_ioLib_NAME_TOO_LONG); return (ERROR); } (void) strcat (destString, *pp); (void) strcat (destString, "/"); slashEnd = TRUE; len = newlen; } } /* final string should not end with '/' */ if (slashEnd) destString [strlen (destString) - 1] = EOS; return (OK); }/********************************************************************************* pathCat - concatenate directory path to filename** This routine constructs a valid filename from a directory path and a filename.* The resultant path name is put into <result>.** The following arcane rules are used to derive the concatenated result.** 1. if <fileName> begins with a device name, then <result> will just be* <fileName>.* 2. if <dirName> begins with a device name that does NOT start with a "/",* then that device name is first part of <result>.* 3. if <fileName> is a relative path name, i.e. does not start with* '/', '\\', '~', or '$', then <dirName> (less the device name of rule 2,* if any) is the appended to <result>. A '/' is appended to the result* unless <dirName> already ends with one.* 4. <fileName> is appended to <result>.** Thus, if the following are the only devices in the system:** dev:* /usr* /rt11/** Then the following results would be obtained:** dirName fileName result rule* ------- --------- ------------- ---------------------------* (any) yuba:blah yuba:blah fileName starts with device* (any) /usr/blah /usr/blah fileName starts with device* dev: blah dev:blah <dev><file>* dev: /blah dev:/blah <dev><file>* dev:foo blah dev:foo/blah <dev><dir>/<file>* dev:foo /blah dev:/blah <dev><file>* /usr blah /usr/blah </dir>/<file>* /usr /blah /blah <file>* /rt11/ blah /rt11/blah </dir/><file>* /rt11/ /blah /blah <file>** <dirName> and <fileName> should be less than MAX_FILENAME_LENGTH chars long.** RETURNS: OK** RATIONALE** These rules are intended to make pathnames work as in UNIX for devices* that start with "/", but also to allow DOS-like device prefixes and* rcp-like host prefixes, and also to retain compatibility with old* rt-11 conventions.* That these rules are so complex suggests that adopting a simpler,* more UNIX-like model would be better in the future.* For example, if device names were required to start with '/' and NOT* end in '/', then the following simple UNIX-like rules would suffice:** 1. if <fileName> starts with "/" (i.e. is an absolute pathname), then* the result is <filename>* 2. otherwise the result is <dirName>/<fileName>** NOMANUAL*/STATUS pathCat ( FAST char *dirName, /* directory path */ FAST char *fileName, /* filename to be added to end of path */ FAST char *result /* where to form concatenated name */ ) { char *pTail; if ((fileName == NULL) || (fileName[0] == EOS)) { strcpy (result, dirName); return (OK); } if ((dirName == NULL) || (dirName[0] == EOS)) { strcpy (result, fileName); return (OK); } /* if filename starts with a device name, result is just filename */ (void) iosDevFind (fileName, &pTail); if (pTail != fileName) { strcpy (result, fileName); return (OK); } /* if dirName starts with a device name that does NOT start with "/", * then prepend that device name */ *result = EOS; if (dirName[0] != '/') { (void) iosDevFind (dirName, &pTail); if (pTail != dirName) { strncat (result, dirName, pTail - dirName); dirName = pTail; } } /* if filename is relative path, prepend directory if any */ if ((index ("/\\~$", fileName [0]) == NULL) && (dirName[0] != EOS)) { strcatlim (result, dirName, PATH_MAX); if (dirName [strlen (dirName) - 1] != '/') strcatlim (result, "/", PATH_MAX); } /* concatenate filename */ strcatlim (result, fileName, PATH_MAX); return (OK); }/********************************************************************************* strcatlim - append characters of one string onto another up to limit** This routine appends characters from string <s2> to the end of string <s1>,* limiting the resulting length of <s1> to <limit> characters, not including* the EOS. The resulting <s1> will always be NULL terminated.* Thus <s1> must be big enough to hold <limit> + 1 characters.** INTERNAL* Perhaps should be in strLib.** RETURNS: A pointer to null-terminated <s1>.**/LOCAL char *strcatlim ( FAST char *s1, /* string to be appended to */ FAST char *s2, /* string to append to s1 */ int limit /* max number of chars in resulting s1, excluding EOS */ ) { int n1; int n2; n1 = strlen (s1); if (n1 < limit) { n2 = strlen (s2); n2 = min (n2, limit - n1); bcopy (s2, &s1 [n1], n2); s1 [n1 + n2] = EOS; } return (s1); }/********************************************************************************* pathLastNamePtr - return last name in a path name** This routine returns a pointer to the character after the last slash* ("/" or "\\") in the path name. Note that if the directory name ends* with a slash, the returned pointer will point to a null string.** RETURNS: A pointer to the last name in path.** NOMANUAL*/char *pathLastNamePtr ( char *pathName ) { char *p; if ((p = pathSlashRindex (pathName)) == NULL) return (pathName); else return ((char *) (p + 1)); }/********************************************************************************* pathLastName - return last name in a path name** This routine returns a pointer to the character after the last slash* ("/" or "\\") in the path name. Note that if the directory name ends* with a slash, the returned pointer will point to a null string.** This routine is provided in addition to pathLastNamePtr() just for* backward compatibility with 4.0.2. pathLastNamePtr() is the preferred* routine now.** RETURNS: pointer to last name in location pointed to by <pLastName>** NOMANUAL*/void pathLastName ( char *pathName, char **pLastName ) { *pLastName = pathLastNamePtr (pathName); }/********************************************************************************* pathSlashRindex - find last occurance of '/' or '\' in string** This routine searches a string for the last occurance of '/' or '\'.* It returns a pointer to the last slash character.** RETURNS:* pointer to last '/' or '\', or* NULL if no slashes in string*/LOCAL char *pathSlashRindex ( char *pString /* string to search */ ) { FAST char *pForward; /* ptr to forward slash */ FAST char *pBack; /* ptr to back slash */ pForward = rindex (pString, '/'); pBack = rindex (pString, '\\'); return (max (pForward, pBack)); }/********************************************************************************* pathSplit - split a path name into its directory and file parts** This routine splits a valid UNIX-style path name into its directory* and file parts by finding the last slash ("/" or "\\"). The results are* copied into <dirName> and <fileName>.** NOMANUAL*/void pathSplit ( FAST char *fullFileName, /* full file name being parsed */ FAST char *dirName, /* result, directory name */ char *fileName /* result, simple file name */ ) { FAST int nChars; if (fullFileName != NULL) { char *p = pathSlashRindex (fullFileName); if (p == NULL) { (void) strcpy (fileName, fullFileName); (void) strcpy (dirName, ""); } else { nChars = p - fullFileName; (void) strncpy (dirName, fullFileName, nChars); dirName [nChars] = EOS; (void) strcpy (fileName, ++p); } } else { (void) strcpy (fileName, ""); (void) strcpy (dirName, ""); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -