Esempio n. 1
0
int _RTLENTRY _EXPFUNC _tfnsplit(const _TCHAR *pathP, _TCHAR *driveP, _TCHAR *dirP,
                         _TCHAR *nameP, _TCHAR *extP)
{
        register _TCHAR   *pB;
        register int    Wrk;
        int     Ret;

        _TCHAR buf[ MAXPATH+2 ];

        /*
          Set all string to default value zero
        */
        Ret = 0;
        if (driveP)
                *driveP = 0;
        if (dirP)
                *dirP = 0;
        if (nameP)
                *nameP = 0;
        if (extP)
                *extP = 0;

        /*
          Copy filename into template up to MAXPATH characters
        */
        pB = buf;
        if ((Wrk = _tcslen(pathP)) > MAXPATH)
                Wrk = MAXPATH;
        *pB++ = 0;
        _tcsncpy(pB, pathP, Wrk);
        *(pB += Wrk) = 0;

        /*
          Split the filename and fill corresponding nonzero pointers
        */
        Wrk = 0;
        for (; ; ) {
#if defined(_MBCS) && !defined(_UNICODE)
                if (_mbsbtype(buf+1, (pB-1) - (buf+1)) == _MBC_TRAIL) {
                        pB -= 2;
                        continue;
                }
#endif
                switch (*--pB) {
                case _TEXT('.')  :
                        if (!Wrk && (*(pB+1) == _TEXT('\0')))
#if defined(_MBCS) && !defined(_UNICODE)
                                Wrk = DotFound(buf+1, pB);
#else
                                Wrk = DotFound(pB);
#endif
                        if ((!Wrk) && ((Ret & EXTENSION) == 0)) {
                                Ret |= EXTENSION;
                                CopyIt(extP, pB, MAXEXT - 1);
                                *pB = 0;
                        }
                        continue;
                case _TEXT(':')  :
                        if (pB != &buf[2])
                                continue;
                case _TEXT('\0') :
                        if (Wrk) {
                                if (*++pB)
                                        Ret |= DIRECTORY;
                                CopyIt(dirP, pB, MAXDIR - 1);
                                *pB-- = 0;
                                break;
                        }
                case _TEXT('/')  :
                case _TEXT('\\') :
                        if (!Wrk) {
                                Wrk++;
                                if (*++pB)
                                        Ret |= FILENAME;
                                CopyIt(nameP, pB, MAXFILE - 1);
                                *pB-- = 0;
                                if (*pB == 0 || (*pB == _TEXT(':') && pB == &buf[2]))
                                        break;
                        }
                        continue;
                case _TEXT('*')  :
                case _TEXT('?')  :
                        if (!Wrk)
                                Ret |= WILDCARDS;
                default :
                        continue;
                }
                break;
        }
        if (*pB == _TEXT(':')) {
                if (buf[1])
                        Ret |= DRIVE;
                CopyIt(driveP, &buf[1], MAXDRIVE - 1);
        }

        return (Ret);
}
Esempio n. 2
0
        // FNSplit differs from fnsplit in that it can split the path without
        // splitting a DBCS character whose trail byte can have the value of
        // 0x5C that also represents '\\' in the ASCII set.
        Int16u FNSplit(const char * pathP, 
                       char       * driveP,
                       char       * dirP, 
                       char       * nameP, 
                       char       * extP)
        {
            register char   * pB;
            register Int16u Wrk;
            Int16u Ret;
            char buf[MAXPATH + 2];

            //Set all string to default value zero
            Ret = 0;
            if (driveP)
                *driveP = 0;
            if (dirP)
                *dirP = 0;
            if (nameP)
                *nameP = 0;
            if (extP)
                *extP = 0;

            // Copy filename into template up to MAXPATH characters
            pB = buf;
            while (*pathP == ' ')
                pathP++;

            if ((Wrk = lstrlen(pathP)) > MAXPATH)
                Wrk = MAXPATH;
            pB [0] = 0;  // put a stopper at string beginning
            _tcsnccpy(pB + 1, pathP, Wrk);
            pB [++Wrk] = '\0';

            // forward-scan pathname and record occurences of '/', '\\', or '.'
            TokenIndexList * slashList = 0,
                           * bkSlashList = 0,
                           * dotList = 0;

            RegisterTokens (slashList, pB, '/');
            RegisterTokens (bkSlashList, pB, '\\');
            RegisterTokens (dotList, pB, '.');
    
            //Split the filename and fill corresponding nonzero pointers
            Int16s index = Wrk;
            Wrk = 0; // from this point on, Wrk serves as a Boolean flag
                     // indicating whether a directory is detected
            for ( ; ; )
            {
                --index;
                switch (pB [index])
                {
                    case '.'  :
                        if (!IsAsciiToken (dotList, index))
                            continue;

                        if (!Wrk && (pB [index + 1] == '\0'))
                            Wrk = IsDirDot(slashList, bkSlashList, pB, index);

                        if ((!Wrk) && ((Ret & EXTENSION) == 0))
                        {
                            Ret |= EXTENSION;
                            CopyIt (extP, pB + index, MAXEXT - 1);
                            pB [index] = 0;
                        }
                        continue;

                    case ':'  :
                        if (index != 2) // i.e., if not second char
                            continue;

                    case '\0' :
                        if (Wrk) // directory exists
                        {
                            if (pB [index + 1])
                                Ret |= DIRECTORY;
                            CopyIt(dirP, pB + index + 1, MAXDIR - 1);
                            pB [index + 1] = 0;
    
                            Int16u dirL = lstrlen (dirP);
                            if (dirL == 0)
                                break;

                            switch (dirP [dirL - 1])
                            {
                                case '\\':
                                    if (IsAsciiToken (bkSlashList, index + dirL))
                                        break;

                                case '/':
                                    if (IsAsciiToken (slashList, index + dirL))
                                        break;

                                default: // add trailing slash
                                    dirP [dirL] = '\\';
                                    dirP [dirL + 1] = '\0';
                            }
                            break;
                        }

                    case '/'  :
                    case '\\' :
                        if (!Wrk && (pB [index] == '\0' ||
                            IsAsciiToken (pB [index] == '/' ? slashList : bkSlashList, index)))
                        {
                            Wrk++;
                            if (pB [index + 1])
                                Ret |= FILENAME;
                            CopyIt(nameP, pB + index + 1, MAXFILE - 1);
                            pB [index + 1] = 0;
                            if (pB [index] == 0 ||
                                (pB [index] == ':' && index == 2))
                            break;
                        }
                        continue;

                    case '*'  :
                    case '?'  :
                        if (!Wrk)
                            Ret |= WILDCARDS;
                    default :
                        continue;
                } // switch
                break;
            } // for

            if (pB [2] == ':')
            {
                if (pB [0])
                    Ret |= DRIVE;
                CopyIt(driveP, &pB [1], MAXDRIVE - 1);
            }   

            DeleteIndexList (slashList);
            DeleteIndexList (bkSlashList);
            DeleteIndexList (dotList);

            return (Ret);
        }