// @ZBS { // *MODULE_OWNER_NAME zfilespec // } #ifndef ZFILESPEC_H #define ZFILESPEC_H // This is a handy little class to build and parse directory & filenames. // It is OS independent. If you feed it '\' under Unix, it will convert them // and vice versa. // // The "zFileSpecMake" function allows you to build up paths from components. // Specify each component like: makeFileSpec (FS_DIR, "\\", FS_DIR, workDir, FS_FILE, "oink.cpp"); // The tokens allow it to intelligently apply slashes. Simple filenames like "oink.cpp" will // get converted to ".\oink.cpp" to normalize it. // // The ZFileSpec class will parse a string. Its pretty heavy weight as it does this // parse each time you call a "get" member. #define ZFILESPEC_WORK_BUFFER_COUNT 10 #define ZFILESPEC_PATH 256 char *zFileSpecMake( int firstToken, ... ); #define FS_END (0) #define FS_DRIVE (-1) #define FS_DIR (-2) #define FS_FILE (-3) #define FS_EXT (-4) // The zFileSpecMake function constructs and normalizes a path based on the // tokens that you pass in. // You must always pass a token for each string. // If anything is wrong the function will return NULL // // >>>>>>>>>>>>>>> DON'T FORGET TO TERMINATE THE CHAIN WITH FS_END!!! <<<<<<<<<<<<< // // RULES // ------------------------------------------------------------------------ // The FS_DRIVE token will add the ':' if nec. unless the path starts with UNC \\ // The FS_DIR will add slashes before and after if nec. // The FS_FILE will not add anything // The FS_EXT will add a '.' if nec. // // Addition rules: // FS_DRIVE + FS_DRIVE -- ILLEGAL // FS_DRIVE + FS_DIR will always make the FS_DIR in root. (No default drive paths allowed for UNIX compatibility) // FS_DRIVE + FS_FILE will always make the FS_FILE in root. (No default drive paths allowed for UNIX compatibility) // FS_DIRVE + FS_EXT -- ILLEGAL // // FS_DIR + FS_DRIVE -- ILLEGAL // FS_DIR + FS_DIR will add slashes as necessary // FS_DIR + FS_FILE will add slash as necessary // FS_DIR + FS_EXT -- ILLEGAL // // FS_FILE + FS_DRIVE -- ILLEGAL // FS_FILE + FS_DIR -- ILLEGAL // FS_FILE + FS_FILE -- ILLEGAL // FS_FILE + FS_EXT as '.' as necessary // // FS_EXT + FS_DRIVE -- ILLEGAL // FS_EXT + FS_DIR -- ILLEGAL // FS_EXT + FS_FILE -- ILLEGAL // FS_EXT + FS_EXT as '.' as necessary class ZFileSpec { protected: static int workBuffer; static char workBuffers[ZFILESPEC_WORK_BUFFER_COUNT][ZFILESPEC_PATH]; char path[ZFILESPEC_PATH]; void *findHandle; int found; // This is used when there is a wild card search public: static char *getNextWorkBuffer(); ZFileSpec (char *string); void set (char *string); // Copies string into buffer, ready for parse calls below int isFound() { return found; } int findNext(); // These two are used when you pass in a wildcard. It expands // the wildcard and the isFound tells you if there is something // legal in the buffer. Call findNext() to retrieve the next. int getNumDirs(); // returns num dirs in a path. There's always at least one as // path get normalized from "oink.cpp" to ".\oink.cpp" char *getDrive(); // This will deal correctly with UNC names. For example: // "c:\biteme\oink.cpp" -> getDrive() -> "c:" // "\\horton\c\biteme\oink.cpp" -> getDrive() -> "\\horton\" // NOTE: The treatment of UNC machine names as a "drive" instead of using the // proper \ combination is intentional. This distinction should // not cause any problems. -TNB char *getDir(int n=-1); // If you pass in -1 then it will return the whole dir including the // last '\'. If you pass in >=0 then it returns that dir. // "\\horton\c\biteme\oink.cpp" -> getDir(-1) -> "c\biteme\" // "\\horton\c\biteme\oink.cpp" -> getDir(0) -> "c\" // "\\horton\c\biteme\oink.cpp" -> getDir(1) -> "biteme\" char *getFile(int withExtension = 1); // Returns the file with or without the extension (see below). // "\\horton\c\biteme\oink.cpp" -> getFile(0) -> "oink" // "\\horton\c\biteme\oink.cpp" -> getFile(1) -> "oink.cpp" // "\\horton\c\biteme\oink.cpp.lock" -> getFile(1) -> "oink.cpp.lock" // "oink.cpp.lock" -> getFile(0) -> "oink.cpp" *** NOTICE ME *** // "oink.cpp.lock" -> getFile(1) -> "oink.cpp.lock" char *getExt(); // Returns the LAST extension. // "oink.cpp.lock.ignore" -> getExt() -> ".ignore" char *get(int normal=1); // Returns the whole buffer (post normalization) int getTime(); int getSize(); void stripExt (int stripAll = 0); // removes the LAST extension // "oink.cpp.ignore" -> stripExt() -> "oink.cpp" // Will add other stripXXX as needed }; #endif