enhanced qse_fs_cpfileXXX() a bit.
added qse_mergepathdup() and related functions
This commit is contained in:
		| @ -68,6 +68,8 @@ libqsecmn_la_SOURCES = \ | ||||
| 	opt.c \ | ||||
| 	path-base.c \ | ||||
| 	path-canon.c \ | ||||
| 	path-core.c \ | ||||
| 	path-merge.c \ | ||||
| 	pio.c \ | ||||
| 	pma.c \ | ||||
| 	rbt.c \ | ||||
|  | ||||
| @ -110,16 +110,16 @@ am__libqsecmn_la_SOURCES_DIST = alg-base64.c alg-rand.c alg-search.c \ | ||||
| 	fma.c fmt-intmax.c fmt-out.c fs.c fs-delete.c fs-err.c \ | ||||
| 	fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c mb8.c \ | ||||
| 	mbwc.c mbwc-str.c mem.c mux.c nwad.c nwad-skad.c nwif.c \ | ||||
| 	nwif-cfg.c nwio.c oht.c opt.c path-base.c path-canon.c pio.c \ | ||||
| 	pma.c rbt.c rex.c sck.c sio.c sll.c slmb.c str-beg.c str-cat.c \ | ||||
| 	str-chr.c str-cnv.c str-cmp.c str-cpy.c str-del.c str-dup.c \ | ||||
| 	str-dyn.c str-end.c str-excl.c str-fcpy.c str-fmt.c \ | ||||
| 	str-fnmat.c str-incl.c str-join.c str-len.c str-pac.c \ | ||||
| 	str-pbrk.c str-put.c str-rev.c str-rot.c str-set.c str-spl.c \ | ||||
| 	str-spn.c str-str.c str-subst.c str-tok.c str-trm.c str-word.c \ | ||||
| 	task.c time.c tio.c tmr.c tre.c tre-ast.c tre-compile.c \ | ||||
| 	tre-match-bt.c tre-match-pa.c tre-parse.c tre-stack.c uri.c \ | ||||
| 	utf8.c xma.c uni.c cp949.c cp950.c | ||||
| 	nwif-cfg.c nwio.c oht.c opt.c path-base.c path-canon.c \ | ||||
| 	path-core.c path-merge.c pio.c pma.c rbt.c rex.c sck.c sio.c \ | ||||
| 	sll.c slmb.c str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c \ | ||||
| 	str-cpy.c str-del.c str-dup.c str-dyn.c str-end.c str-excl.c \ | ||||
| 	str-fcpy.c str-fmt.c str-fnmat.c str-incl.c str-join.c \ | ||||
| 	str-len.c str-pac.c str-pbrk.c str-put.c str-rev.c str-rot.c \ | ||||
| 	str-set.c str-spl.c str-spn.c str-str.c str-subst.c str-tok.c \ | ||||
| 	str-trm.c str-word.c task.c time.c tio.c tmr.c tre.c tre-ast.c \ | ||||
| 	tre-compile.c tre-match-bt.c tre-match-pa.c tre-parse.c \ | ||||
| 	tre-stack.c uri.c utf8.c xma.c uni.c cp949.c cp950.c | ||||
| @ENABLE_BUNDLED_UNICODE_TRUE@am__objects_1 = uni.lo | ||||
| @ENABLE_XCMGRS_TRUE@am__objects_2 = cp949.lo cp950.lo | ||||
| am_libqsecmn_la_OBJECTS = alg-base64.lo alg-rand.lo alg-search.lo \ | ||||
| @ -128,17 +128,17 @@ am_libqsecmn_la_OBJECTS = alg-base64.lo alg-rand.lo alg-search.lo \ | ||||
| 	fs-delete.lo fs-err.lo fs-make.lo fs-move.lo glob.lo hton.lo \ | ||||
| 	ipad.lo lda.lo main.lo mb8.lo mbwc.lo mbwc-str.lo mem.lo \ | ||||
| 	mux.lo nwad.lo nwad-skad.lo nwif.lo nwif-cfg.lo nwio.lo oht.lo \ | ||||
| 	opt.lo path-base.lo path-canon.lo pio.lo pma.lo rbt.lo rex.lo \ | ||||
| 	sck.lo sio.lo sll.lo slmb.lo str-beg.lo str-cat.lo str-chr.lo \ | ||||
| 	str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo str-dup.lo \ | ||||
| 	str-dyn.lo str-end.lo str-excl.lo str-fcpy.lo str-fmt.lo \ | ||||
| 	str-fnmat.lo str-incl.lo str-join.lo str-len.lo str-pac.lo \ | ||||
| 	str-pbrk.lo str-put.lo str-rev.lo str-rot.lo str-set.lo \ | ||||
| 	str-spl.lo str-spn.lo str-str.lo str-subst.lo str-tok.lo \ | ||||
| 	str-trm.lo str-word.lo task.lo time.lo tio.lo tmr.lo tre.lo \ | ||||
| 	tre-ast.lo tre-compile.lo tre-match-bt.lo tre-match-pa.lo \ | ||||
| 	tre-parse.lo tre-stack.lo uri.lo utf8.lo xma.lo \ | ||||
| 	$(am__objects_1) $(am__objects_2) | ||||
| 	opt.lo path-base.lo path-canon.lo path-core.lo path-merge.lo \ | ||||
| 	pio.lo pma.lo rbt.lo rex.lo sck.lo sio.lo sll.lo slmb.lo \ | ||||
| 	str-beg.lo str-cat.lo str-chr.lo str-cnv.lo str-cmp.lo \ | ||||
| 	str-cpy.lo str-del.lo str-dup.lo str-dyn.lo str-end.lo \ | ||||
| 	str-excl.lo str-fcpy.lo str-fmt.lo str-fnmat.lo str-incl.lo \ | ||||
| 	str-join.lo str-len.lo str-pac.lo str-pbrk.lo str-put.lo \ | ||||
| 	str-rev.lo str-rot.lo str-set.lo str-spl.lo str-spn.lo \ | ||||
| 	str-str.lo str-subst.lo str-tok.lo str-trm.lo str-word.lo \ | ||||
| 	task.lo time.lo tio.lo tmr.lo tre.lo tre-ast.lo tre-compile.lo \ | ||||
| 	tre-match-bt.lo tre-match-pa.lo tre-parse.lo tre-stack.lo \ | ||||
| 	uri.lo utf8.lo xma.lo $(am__objects_1) $(am__objects_2) | ||||
| libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS) | ||||
| AM_V_lt = $(am__v_lt_@AM_V@) | ||||
| am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) | ||||
| @ -417,16 +417,16 @@ libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \ | ||||
| 	fmt-intmax.c fmt-out.c fs.c fs-delete.c fs-err.c fs-make.c \ | ||||
| 	fs-move.c glob.c hton.c ipad.c lda.c main.c mb8.c mbwc.c \ | ||||
| 	mbwc-str.c mem.c mux.c nwad.c nwad-skad.c nwif.c nwif-cfg.c \ | ||||
| 	nwio.c oht.c opt.c path-base.c path-canon.c pio.c pma.c rbt.c \ | ||||
| 	rex.c sck.c sio.c sll.c slmb.c str-beg.c str-cat.c str-chr.c \ | ||||
| 	str-cnv.c str-cmp.c str-cpy.c str-del.c str-dup.c str-dyn.c \ | ||||
| 	str-end.c str-excl.c str-fcpy.c str-fmt.c str-fnmat.c \ | ||||
| 	str-incl.c str-join.c str-len.c str-pac.c str-pbrk.c str-put.c \ | ||||
| 	str-rev.c str-rot.c str-set.c str-spl.c str-spn.c str-str.c \ | ||||
| 	str-subst.c str-tok.c str-trm.c str-word.c task.c time.c tio.c \ | ||||
| 	tmr.c tre.c tre-ast.c tre-compile.c tre-match-bt.c \ | ||||
| 	tre-match-pa.c tre-parse.c tre-stack.c uri.c utf8.c xma.c \ | ||||
| 	$(am__append_1) $(am__append_2) | ||||
| 	nwio.c oht.c opt.c path-base.c path-canon.c path-core.c \ | ||||
| 	path-merge.c pio.c pma.c rbt.c rex.c sck.c sio.c sll.c slmb.c \ | ||||
| 	str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c str-cpy.c \ | ||||
| 	str-del.c str-dup.c str-dyn.c str-end.c str-excl.c str-fcpy.c \ | ||||
| 	str-fmt.c str-fnmat.c str-incl.c str-join.c str-len.c \ | ||||
| 	str-pac.c str-pbrk.c str-put.c str-rev.c str-rot.c str-set.c \ | ||||
| 	str-spl.c str-spn.c str-str.c str-subst.c str-tok.c str-trm.c \ | ||||
| 	str-word.c task.c time.c tio.c tmr.c tre.c tre-ast.c \ | ||||
| 	tre-compile.c tre-match-bt.c tre-match-pa.c tre-parse.c \ | ||||
| 	tre-stack.c uri.c utf8.c xma.c $(am__append_1) $(am__append_2) | ||||
| libqsecmn_la_LDFLAGS = -version-info 1:0:0 -no-undefined | ||||
| libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS) | ||||
| @ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \ | ||||
| @ -554,6 +554,8 @@ distclean-compile: | ||||
| @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@ | ||||
| @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path-base.Plo@am__quote@ | ||||
| @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path-canon.Plo@am__quote@ | ||||
| @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path-core.Plo@am__quote@ | ||||
| @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path-merge.Plo@am__quote@ | ||||
| @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Plo@am__quote@ | ||||
| @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pma.Plo@am__quote@ | ||||
| @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbt.Plo@am__quote@ | ||||
|  | ||||
| @ -75,7 +75,10 @@ typedef struct fop_t fop_t; | ||||
|  | ||||
|  | ||||
| /* internal flags. it must not overlap with qse_fs_cpfile_flag_t enumerators */ | ||||
| #define CPFILE_DST_ATTR (1 << 30) | ||||
| #define CPFILE_DST_ATTR (1 << 27) | ||||
| #define CPFILE_DST_PATH_DUP (1 << 28) | ||||
| #define CPFILE_DST_FSPATH_DUP (1 << 29) | ||||
| #define CPFILE_DST_FSPATH_MERGED (1 << 30) | ||||
|  | ||||
| struct cpfile_t | ||||
| { | ||||
| @ -479,15 +482,60 @@ static int move_file_in_fs (qse_fs_t* fs, const qse_fs_char_t* oldpath, const qs | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static int merge_dstdir_and_file (qse_fs_t* fs, cpfile_t* cpfile) | ||||
| { | ||||
| 	qse_fs_char_t* fstmp; | ||||
|  | ||||
| 	/* if the destination is directory, copy the base name of the source | ||||
| 	 * and append it to the end of the destination, targetting at an entry | ||||
| 	 * in the directory */ | ||||
| 	QSE_ASSERT (cpfile->dst_attr.isdir); | ||||
|  | ||||
| 	if (cpfile->dst_path) | ||||
| 	{ | ||||
| 		qse_char_t* tmp; | ||||
|  | ||||
| 		tmp = qse_mergepathdup (cpfile->dst_path, qse_basename (cpfile->src_path), fs->mmgr); | ||||
| 		if (!tmp)  | ||||
| 		{ | ||||
| 			fs->errnum = QSE_FS_ENOMEM; | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		if (cpfile->flags & CPFILE_DST_PATH_DUP)  | ||||
| 			QSE_MMGR_FREE (fs->mmgr, cpfile->dst_path); | ||||
|  | ||||
| 		cpfile->dst_path = tmp; | ||||
| 		cpfile->flags |= CPFILE_DST_PATH_DUP; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	fstmp = merge_fspath_dup (cpfile->dst_fspath, get_fspath_base (cpfile->src_fspath), fs->mmgr); | ||||
| 	if (!fstmp) | ||||
| 	{ | ||||
| 		fs->errnum = QSE_FS_ENOMEM; | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (cpfile->flags & CPFILE_DST_FSPATH_DUP)  | ||||
| 		QSE_MMGR_FREE (fs->mmgr, cpfile->dst_fspath); | ||||
| 	cpfile->dst_fspath = fstmp; | ||||
| 	cpfile->flags |= CPFILE_DST_FSPATH_DUP; | ||||
|  | ||||
| 	if (qse_fs_getattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) >= 0)  | ||||
| 	{ | ||||
| 		cpfile->flags |= CPFILE_DST_ATTR; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		cpfile->flags &= ~CPFILE_DST_ATTR; | ||||
| 	} | ||||
|  | ||||
| 	cpfile->flags |= CPFILE_DST_FSPATH_MERGED; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -699,8 +747,7 @@ static int copy_file (qse_fs_t* fs, cpfile_t* cpfile) | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* TODO: check if it's itself */ | ||||
|  | ||||
| 	copy_file: | ||||
| 		if (cpfile->flags & CPFILE_DST_ATTR)  | ||||
| 		{ | ||||
| 			if (cpfile->src_attr.ino == cpfile->dst_attr.ino &&  | ||||
| @ -711,11 +758,22 @@ static int copy_file (qse_fs_t* fs, cpfile_t* cpfile) | ||||
| 				return -1; | ||||
| 			} | ||||
|  | ||||
| 			if (cpfile->dst_attr.isdir) | ||||
| 			if (!(cpfile->flags & QSE_FS_CPFILE_NOTGTDIR) &&  | ||||
| 			    cpfile->dst_attr.isdir) | ||||
| 			{ | ||||
| 				/* copy it to directory */ | ||||
| 				//return copy_file_into_dir (fs, cpfile); | ||||
| 				 | ||||
| 				if (cpfile->flags & CPFILE_DST_FSPATH_MERGED) | ||||
| 				{ | ||||
| 					/* merge_dstdir_and_file() has been called already. | ||||
| 					 * no more getting into a subdirectory */ | ||||
| 					fs->errnum = QSE_FS_EISDIR; | ||||
| 					return -1; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					/* arrange to copy a file into a directory */ | ||||
| 					if (merge_dstdir_and_file (fs, cpfile) <= -1) return -1; | ||||
| 					goto copy_file; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			if (!(cpfile->flags & QSE_FS_CPFILE_REPLACE)) | ||||
| @ -731,7 +789,6 @@ static int copy_file (qse_fs_t* fs, cpfile_t* cpfile) | ||||
| 			return copy_file_in_fs (fs, cpfile); | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		/* source is a directory. is a recursive copy allowed? */ | ||||
| 		fs->errnum = QSE_FS_ENOIMPL; | ||||
| 		return -1; | ||||
| @ -750,6 +807,7 @@ int qse_fs_cpfilembs (qse_fs_t* fs, const qse_mchar_t* srcpath, const qse_mchar_ | ||||
| 	cpfile.src_fspath = (qse_fs_char_t*)qse_fs_makefspathformbs (fs, srcpath); | ||||
| 	cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_makefspathformbs (fs, dstpath); | ||||
| 	if (!cpfile.src_fspath || !cpfile.dst_fspath) goto oops; | ||||
| 	if (cpfile.dst_fspath != dstpath) cpfile.flags |= CPFILE_DST_FSPATH_DUP; | ||||
|  | ||||
| 	if (qse_fs_getattr (fs, cpfile.src_fspath, &cpfile.src_attr) <= -1) goto oops; | ||||
| 	if (qse_fs_getattr (fs, cpfile.dst_fspath, &cpfile.dst_attr) >= 0) cpfile.flags |= CPFILE_DST_ATTR; | ||||
| @ -778,6 +836,7 @@ int qse_fs_cpfilewcs (qse_fs_t* fs, const qse_wchar_t* srcpath, const qse_wchar_ | ||||
| 	cpfile.src_fspath = (qse_fs_char_t*)qse_fs_makefspathforwcs (fs, srcpath); | ||||
| 	cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_makefspathforwcs (fs, dstpath); | ||||
| 	if (!cpfile.src_fspath || !cpfile.dst_fspath) goto oops; | ||||
| 	if (cpfile.dst_fspath != dstpath) cpfile.flags |= CPFILE_DST_FSPATH_DUP; | ||||
|  | ||||
| 	if (qse_fs_getattr (fs, cpfile.src_fspath, &cpfile.src_attr) <= -1) goto oops; | ||||
| 	if (qse_fs_getattr (fs, cpfile.dst_fspath, &cpfile.dst_attr) >= 0) cpfile.flags |= CPFILE_DST_ATTR; | ||||
|  | ||||
| @ -75,12 +75,16 @@ | ||||
|  | ||||
| #if defined(QSE_FS_CHAR_IS_MCHAR) | ||||
| #	define canon_fspath(path,canon,flags) qse_canonmbspath(path,canon,flags) | ||||
| #	define get_fspath_core(fspath) qse_getmbspathcore(fspath) | ||||
| #	define merge_fspath_dup(dir,file,mmgr) qse_mergembspathdup(dir,file,mmgr) | ||||
| #	define get_fspath_core(fspath) qse_mbspathcore(fspath) | ||||
| #	define get_fspath_base(fspath) qse_mbsbasename(fspath) | ||||
| #	define IS_FSPATHSEP(x) QSE_ISPATHMBSEP(x) | ||||
| #	define QSE_FS_T(x) QSE_MT(x) | ||||
| #else | ||||
| #	define canon_fspath(fspath,canon,flags) qse_canonwcspath(fspath,canon,flags) | ||||
| #	define get_fspath_core(fspath) qse_getwcspathcore(fspath) | ||||
| #	define merge_fspath_dup(dir,file,mmgr) qse_mergewcspathdup(dir,file,mmgr) | ||||
| #	define get_fspath_core(fspath) qse_wcspathcore(fspath) | ||||
| #	define get_fspath_base(fspath) qse_wcsbasename(fspath) | ||||
| #	define IS_FSPATHSEP(x) QSE_ISPATHWCSEP(x) | ||||
| #	define QSE_FS_T(x) QSE_WT(x) | ||||
| #endif | ||||
|  | ||||
| @ -34,24 +34,13 @@ | ||||
| /*  MBS IMPLEMENTATION                                                */ | ||||
| /* ------------------------------------------------------------------ */ | ||||
|  | ||||
| #define IS_MSEP(c) QSE_ISPATHMBSEP(c) | ||||
|  | ||||
| #define IS_MNIL(c) ((c) == QSE_MT('\0')) | ||||
| #define IS_MSEP_OR_MNIL(c) (IS_MSEP(c) || IS_MNIL(c)) | ||||
|  | ||||
| #define IS_MDRIVE(s) \ | ||||
| 	(((s[0] >= QSE_MT('A') && s[0] <= QSE_MT('Z')) || \ | ||||
| 	  (s[0] >= QSE_MT('a') && s[0] <= QSE_MT('z'))) && \ | ||||
| 	 s[1] == QSE_MT(':')) | ||||
|  | ||||
|  | ||||
| int qse_ismbsabspath (const qse_mchar_t* path) | ||||
| { | ||||
| 	if (IS_MSEP(path[0])) return 1; | ||||
| 	if (QSE_ISPATHMBSEP(path[0])) return 1; | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	/* a drive like c:tmp is absolute in positioning the drive. | ||||
| 	 * but the path within the drive is kind of relative */ | ||||
| 	if (IS_MDRIVE(path)) return 1; | ||||
| 	if (QSE_ISPATHMBDRIVE(path)) return 1; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| @ -59,7 +48,7 @@ int qse_ismbsabspath (const qse_mchar_t* path) | ||||
| int qse_ismbsdrivepath (const qse_mchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_MDRIVE(path)) return 1; | ||||
| 	if (QSE_ISPATHMBDRIVE(path)) return 1; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| @ -67,7 +56,7 @@ int qse_ismbsdrivepath (const qse_mchar_t* path) | ||||
| int qse_ismbsdriveabspath (const qse_mchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_MDRIVE(path) && IS_MSEP(path[2])) return 1; | ||||
| 	if (QSE_ISPATHMBDRIVE(path) && QSE_ISPATHMBSEP(path[2])) return 1; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| @ -75,29 +64,11 @@ int qse_ismbsdriveabspath (const qse_mchar_t* path) | ||||
| int qse_ismbsdrivecurpath (const qse_mchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_MDRIVE(path) && path[2] == QSE_MT('\0')) return 1; | ||||
| 	if (QSE_ISPATHMBDRIVE(path) && path[2] == QSE_MT('\0')) return 1; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| qse_mchar_t* qse_getmbspathcore (const qse_mchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_MDRIVE(path)) return (qse_mchar_t*)path + 2; | ||||
| 	#if defined(_WIN32) | ||||
| 	else if (IS_MSEP(*path) && IS_MSEP(*(path + 1)) && !IS_MSEP_OR_MNIL(*(path + 2))) | ||||
| 	{ | ||||
| 		/* UNC Path */ | ||||
| 		path += 2; | ||||
| 		do { path++; } while (!IS_MSEP_OR_MNIL(*path)); | ||||
| 		if (IS_MSEP(*path)) return (qse_mchar_t*)path; | ||||
| 	} | ||||
| 	#endif | ||||
| /* TOOD: \\server\XXX \\.\XXX \\?\XXX \\?\UNC\server\XXX */ | ||||
| 	 | ||||
| #endif | ||||
| 	return (qse_mchar_t*)path; | ||||
| } | ||||
|  | ||||
| qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int flags) | ||||
| { | ||||
| @ -121,31 +92,31 @@ qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int fl | ||||
| 	dst = canon; | ||||
|  | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_MDRIVE(ptr)) | ||||
| 	if (QSE_ISPATHMBDRIVE(ptr)) | ||||
| 	{ | ||||
| 		/* handle drive letter */ | ||||
| 		*dst++ = *ptr++; /* drive letter */ | ||||
| 		*dst++ = *ptr++; /* colon */ | ||||
|  | ||||
| 		is_drive = 1; | ||||
| 		if (IS_MSEP(*ptr))  | ||||
| 		if (QSE_ISPATHMBSEP(*ptr))  | ||||
| 		{ | ||||
| 			*dst++ = *ptr++; /* root directory */ | ||||
| 			has_root = 1; | ||||
| 		} | ||||
| 	} | ||||
| 	else if (IS_MSEP(*ptr))  | ||||
| 	else if (QSE_ISPATHMBSEP(*ptr))  | ||||
| 	{ | ||||
| 		*dst++ = *ptr++; /* root directory */ | ||||
| 		has_root = 1; | ||||
|  | ||||
| 	#if defined(_WIN32) | ||||
| 		/* handle UNC path for Windows */ | ||||
| 		if (IS_MSEP(*ptr))  | ||||
| 		if (QSE_ISPATHMBSEP(*ptr))  | ||||
| 		{ | ||||
| 			*dst++ = *ptr++; | ||||
|  | ||||
| 			if (IS_MSEP_OR_MNIL(*ptr)) | ||||
| 			if (QSE_ISPATHMBSEPORNIL(*ptr)) | ||||
| 			{ | ||||
| 				/* if there is another separator after \\, | ||||
| 				 * it's not an UNC path. */ | ||||
| @ -154,14 +125,14 @@ qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int fl | ||||
| 			else | ||||
| 			{ | ||||
| 				/* if it starts with \\, process host name */ | ||||
| 				do { *dst++ = *ptr++; } while (!IS_MSEP_OR_MNIL(*ptr)); | ||||
| 				if (IS_MSEP(*ptr)) *dst++ = *ptr++; | ||||
| 				do { *dst++ = *ptr++; } while (!QSE_ISPATHMBSEPORNIL(*ptr)); | ||||
| 				if (QSE_ISPATHMBSEP(*ptr)) *dst++ = *ptr++; | ||||
| 			} | ||||
| 		} | ||||
| 	#endif | ||||
| 	} | ||||
| #else | ||||
| 	if (IS_MSEP(*ptr))  | ||||
| 	if (QSE_ISPATHMBSEP(*ptr))  | ||||
| 	{ | ||||
| 		*dst++ = *ptr++; /* root directory */ | ||||
| 		has_root = 1; | ||||
| @ -178,14 +149,14 @@ qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int fl | ||||
| 		qse_size_t seglen; | ||||
|  | ||||
| 		/* skip duplicate separators */ | ||||
| 		while (IS_MSEP(*ptr)) ptr++; | ||||
| 		while (QSE_ISPATHMBSEP(*ptr)) ptr++; | ||||
|  | ||||
| 		/* end of path reached */ | ||||
| 		if (*ptr == QSE_MT('\0')) break; | ||||
|  | ||||
| 		/* find the next segment */ | ||||
| 		seg = ptr; | ||||
| 		while (!IS_MSEP_OR_MNIL(*ptr)) ptr++; | ||||
| 		while (!QSE_ISPATHMBSEPORNIL(*ptr)) ptr++; | ||||
| 		seglen = ptr - seg; | ||||
|  | ||||
| 		/* handle the segment */ | ||||
| @ -210,7 +181,7 @@ qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int fl | ||||
| 				while (tmp > non_root_start) | ||||
| 				{ | ||||
| 					tmp--; | ||||
| 					if (IS_MSEP(*tmp))  | ||||
| 					if (QSE_ISPATHMBSEP(*tmp))  | ||||
| 					{ | ||||
| 						tmp++; /* position it next to the separator */ | ||||
| 						break;  | ||||
| @ -271,7 +242,7 @@ qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int fl | ||||
| 		{ | ||||
| 		normal: | ||||
| 			while (seg < ptr) *dst++ = *seg++; | ||||
| 			if (IS_MSEP(*ptr))  | ||||
| 			if (QSE_ISPATHMBSEP(*ptr))  | ||||
| 			{ | ||||
| 				/* this segment ended with a separator */ | ||||
| 				*dst++ = *seg++; /* copy the separator */ | ||||
| @ -281,8 +252,8 @@ qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int fl | ||||
| 	} | ||||
| 	while (1); | ||||
|  | ||||
| 	if (dst > non_root_start && IS_MSEP(dst[-1]) &&  | ||||
| 	    ((flags & QSE_CANONPATH_DROPTRAILINGSEP) || !IS_MSEP(ptr[-1])))  | ||||
| 	if (dst > non_root_start && QSE_ISPATHMBSEP(dst[-1]) &&  | ||||
| 	    ((flags & QSE_CANONPATH_DROPTRAILINGSEP) || !QSE_ISPATHMBSEP(ptr[-1])))  | ||||
| 	{ | ||||
| 		/* if the canoncal path composed so far ends with a separator | ||||
| 		 * and the original path didn't end with the separator, delete | ||||
| @ -292,9 +263,9 @@ qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int fl | ||||
| 		 *   dst > non_root_start: | ||||
| 		 *     there is at least 1 character after the root directory  | ||||
| 		 *     part. | ||||
| 		 *   IS_MSEP(dst[-1]): | ||||
| 		 *   QSE_ISPATHMBSEP(dst[-1]): | ||||
| 		 *     the canonical path ends with a separator. | ||||
| 		 *   IS_MSEP(ptr[-1]): | ||||
| 		 *   QSE_ISPATHMBSEP(ptr[-1]): | ||||
| 		 *     the origial path ends with a separator. | ||||
| 		 */ | ||||
| 		dst[-1] = QSE_MT('\0'); | ||||
| @ -341,17 +312,17 @@ qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int fl | ||||
| 			 * the double slahses indicate a directory obviously */ | ||||
| 			if (canon[canon_len-3] == QSE_MT('.') && | ||||
| 			    canon[canon_len-2] == QSE_MT('.') && | ||||
| 			    IS_MSEP(canon[canon_len-1])) | ||||
| 			    QSE_ISPATHMBSEP(canon[canon_len-1])) | ||||
| 			{ | ||||
| 				canon[--canon_len] = QSE_MT('\0'); | ||||
| 			} | ||||
| 		} | ||||
| 		else if (canon_len > adj_base_len) | ||||
| 		{ | ||||
| 			if (IS_MSEP(canon[canon_len-4]) && | ||||
| 			if (QSE_ISPATHMBSEP(canon[canon_len-4]) && | ||||
| 			    canon[canon_len-3] == QSE_MT('.') && | ||||
| 			    canon[canon_len-2] == QSE_MT('.') && | ||||
| 			    IS_MSEP(canon[canon_len-1])) | ||||
| 			    QSE_ISPATHMBSEP(canon[canon_len-1])) | ||||
| 			{ | ||||
| 				canon[--canon_len] = QSE_MT('\0'); | ||||
| 			} | ||||
| @ -365,27 +336,14 @@ qse_size_t qse_canonmbspath (const qse_mchar_t* path, qse_mchar_t* canon, int fl | ||||
| /* ------------------------------------------------------------------ */ | ||||
| /*  WCS IMPLEMENTATION                                                */ | ||||
| /* ------------------------------------------------------------------ */ | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| #	define IS_WSEP(c) ((c) == QSE_WT('/') || (c) == QSE_WT('\\')) | ||||
| #else | ||||
| #	define IS_WSEP(c) ((c) == QSE_WT('/')) | ||||
| #endif | ||||
|  | ||||
| #define IS_WNIL(c) ((c) == QSE_WT('\0')) | ||||
| #define IS_WSEP_OR_WNIL(c) (IS_WSEP(c) || IS_WNIL(c)) | ||||
|  | ||||
| #define IS_WDRIVE(s) \ | ||||
| 	(((s[0] >= QSE_WT('A') && s[0] <= QSE_WT('Z')) || \ | ||||
| 	  (s[0] >= QSE_WT('a') && s[0] <= QSE_WT('z'))) && \ | ||||
| 	 s[1] == QSE_WT(':')) | ||||
|  | ||||
| int qse_iswcsabspath (const qse_wchar_t* path) | ||||
| { | ||||
| 	if (IS_WSEP(path[0])) return 1; | ||||
| 	if (QSE_ISPATHWCSEP(path[0])) return 1; | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	/* a drive like c:tmp is absolute in positioning the drive. | ||||
| 	 * but the path within the drive is kind of relative */ | ||||
| 	if (IS_WDRIVE(path)) return 1; | ||||
| 	if (QSE_ISPATHWCDRIVE(path)) return 1; | ||||
| #endif | ||||
|      return 0; | ||||
| } | ||||
| @ -393,7 +351,7 @@ int qse_iswcsabspath (const qse_wchar_t* path) | ||||
| int qse_iswcsdrivepath (const qse_wchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_WDRIVE(path)) return 1; | ||||
| 	if (QSE_ISPATHWCDRIVE(path)) return 1; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| @ -401,7 +359,7 @@ int qse_iswcsdrivepath (const qse_wchar_t* path) | ||||
| int qse_iswcsdriveabspath (const qse_wchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_WDRIVE(path) && IS_WSEP(path[2])) return 1; | ||||
| 	if (QSE_ISPATHWCDRIVE(path) && QSE_ISPATHWCSEP(path[2])) return 1; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| @ -409,28 +367,11 @@ int qse_iswcsdriveabspath (const qse_wchar_t* path) | ||||
| int qse_iswcsdrivecurpath (const qse_wchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_WDRIVE(path) && path[2] == QSE_WT('\0')) return 1; | ||||
| 	if (QSE_ISPATHWCDRIVE(path) && path[2] == QSE_WT('\0')) return 1; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| qse_wchar_t* qse_getwcspathcore (const qse_wchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_WDRIVE(path)) return (qse_wchar_t*)path + 2; | ||||
| 	#if defined(_WIN32) | ||||
| 	else if (IS_WSEP(*path) && IS_WSEP(*(path + 1)) && !IS_WSEP_OR_WNIL(*(path + 2))) | ||||
| 	{ | ||||
| 		/* UNC Path */ | ||||
| 		path += 2; | ||||
| 		do { path++; } while (!IS_WSEP_OR_WNIL(*path)); | ||||
| 		if (IS_WSEP(*path)) return (qse_wchar_t*)path; | ||||
| 	} | ||||
| 	#endif | ||||
| #endif | ||||
| 	return (qse_wchar_t*)path; | ||||
| } | ||||
|  | ||||
| qse_size_t qse_canonwcspath (const qse_wchar_t* path, qse_wchar_t* canon, int flags) | ||||
| { | ||||
| 	const qse_wchar_t* ptr; | ||||
| @ -453,31 +394,31 @@ qse_size_t qse_canonwcspath (const qse_wchar_t* path, qse_wchar_t* canon, int fl | ||||
| 	dst = canon; | ||||
|  | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (IS_WDRIVE(ptr)) | ||||
| 	if (QSE_ISPATHWCDRIVE(ptr)) | ||||
| 	{ | ||||
| 		/* handle drive letter */ | ||||
| 		*dst++ = *ptr++; /* drive letter */ | ||||
| 		*dst++ = *ptr++; /* colon */ | ||||
|  | ||||
| 		is_drive = 1; | ||||
| 		if (IS_WSEP(*ptr))  | ||||
| 		if (QSE_ISPATHWCSEP(*ptr))  | ||||
| 		{ | ||||
| 			*dst++ = *ptr++; /* root directory */ | ||||
| 			has_root = 1; | ||||
| 		} | ||||
| 	} | ||||
| 	else if (IS_WSEP(*ptr))  | ||||
| 	else if (QSE_ISPATHWCSEP(*ptr))  | ||||
| 	{ | ||||
| 		*dst++ = *ptr++; /* root directory */ | ||||
| 		has_root = 1; | ||||
|  | ||||
| 	#if defined(_WIN32) | ||||
| 		/* handle UNC path for Windows */ | ||||
| 		if (IS_WSEP(*ptr))  | ||||
| 		if (QSE_ISPATHWCSEP(*ptr))  | ||||
| 		{ | ||||
| 			*dst++ = *ptr++; | ||||
|  | ||||
| 			if (IS_WSEP_OR_WNIL(*ptr)) | ||||
| 			if (QSE_ISPATHWCSEPORNIL(*ptr)) | ||||
| 			{ | ||||
| 				/* if there is another separator after \\, | ||||
| 				 * it's not an UNC path. */ | ||||
| @ -486,14 +427,14 @@ qse_size_t qse_canonwcspath (const qse_wchar_t* path, qse_wchar_t* canon, int fl | ||||
| 			else | ||||
| 			{ | ||||
| 				/* if it starts with \\, process host name */ | ||||
| 				do { *dst++ = *ptr++; } while (!IS_WSEP_OR_WNIL(*ptr)); | ||||
| 				if (IS_WSEP(*ptr)) *dst++ = *ptr++; | ||||
| 				do { *dst++ = *ptr++; } while (!QSE_ISPATHWCSEPORNIL(*ptr)); | ||||
| 				if (QSE_ISPATHWCSEP(*ptr)) *dst++ = *ptr++; | ||||
| 			} | ||||
| 		} | ||||
| 	#endif | ||||
| 	} | ||||
| #else | ||||
| 	if (IS_WSEP(*ptr))  | ||||
| 	if (QSE_ISPATHWCSEP(*ptr))  | ||||
| 	{ | ||||
| 		*dst++ = *ptr++; /* root directory */ | ||||
| 		has_root = 1; | ||||
| @ -510,14 +451,14 @@ qse_size_t qse_canonwcspath (const qse_wchar_t* path, qse_wchar_t* canon, int fl | ||||
| 		qse_size_t seglen; | ||||
|  | ||||
| 		/* skip duplicate separators */ | ||||
| 		while (IS_WSEP(*ptr)) ptr++; | ||||
| 		while (QSE_ISPATHWCSEP(*ptr)) ptr++; | ||||
|  | ||||
| 		/* end of path reached */ | ||||
| 		if (*ptr == QSE_WT('\0')) break; | ||||
|  | ||||
| 		/* find the next segment */ | ||||
| 		seg = ptr; | ||||
| 		while (!IS_WSEP_OR_WNIL(*ptr)) ptr++; | ||||
| 		while (!QSE_ISPATHWCSEPORNIL(*ptr)) ptr++; | ||||
| 		seglen = ptr - seg; | ||||
|  | ||||
| 		/* handle the segment */ | ||||
| @ -542,7 +483,7 @@ qse_size_t qse_canonwcspath (const qse_wchar_t* path, qse_wchar_t* canon, int fl | ||||
| 				while (tmp > non_root_start) | ||||
| 				{ | ||||
| 					tmp--; | ||||
| 					if (IS_WSEP(*tmp))  | ||||
| 					if (QSE_ISPATHWCSEP(*tmp))  | ||||
| 					{ | ||||
| 						tmp++; /* position it next to the separator */ | ||||
| 						break;  | ||||
| @ -603,7 +544,7 @@ qse_size_t qse_canonwcspath (const qse_wchar_t* path, qse_wchar_t* canon, int fl | ||||
| 		{ | ||||
| 		normal: | ||||
| 			while (seg < ptr) *dst++ = *seg++; | ||||
| 			if (IS_WSEP(*ptr))  | ||||
| 			if (QSE_ISPATHWCSEP(*ptr))  | ||||
| 			{ | ||||
| 				/* this segment ended with a separator */ | ||||
| 				*dst++ = *seg++; /* copy the separator */ | ||||
| @ -613,8 +554,8 @@ qse_size_t qse_canonwcspath (const qse_wchar_t* path, qse_wchar_t* canon, int fl | ||||
| 	} | ||||
| 	while (1); | ||||
|  | ||||
| 	if (dst > non_root_start && IS_WSEP(dst[-1]) &&  | ||||
| 	    ((flags & QSE_CANONPATH_DROPTRAILINGSEP) || !IS_WSEP(ptr[-1])))  | ||||
| 	if (dst > non_root_start && QSE_ISPATHWCSEP(dst[-1]) &&  | ||||
| 	    ((flags & QSE_CANONPATH_DROPTRAILINGSEP) || !QSE_ISPATHWCSEP(ptr[-1])))  | ||||
| 	{ | ||||
| 		/* if the canoncal path composed so far ends with a separator | ||||
| 		 * and the original path didn't end with the separator, delete | ||||
| @ -624,9 +565,9 @@ qse_size_t qse_canonwcspath (const qse_wchar_t* path, qse_wchar_t* canon, int fl | ||||
| 		 *   dst > non_root_start: | ||||
| 		 *     there is at least 1 character after the root directory  | ||||
| 		 *     part. | ||||
| 		 *   IS_WSEP(dst[-1]): | ||||
| 		 *   QSE_ISPATHWCSEP(dst[-1]): | ||||
| 		 *     the canonical path ends with a separator. | ||||
| 		 *   IS_WSEP(ptr[-1]): | ||||
| 		 *   QSE_ISPATHWCSEP(ptr[-1]): | ||||
| 		 *     the origial path ends with a separator. | ||||
| 		 */ | ||||
| 		dst[-1] = QSE_WT('\0'); | ||||
| @ -673,17 +614,17 @@ qse_size_t qse_canonwcspath (const qse_wchar_t* path, qse_wchar_t* canon, int fl | ||||
| 			 * the double slahses indicate a directory obviously */ | ||||
| 			if (canon[canon_len-3] == QSE_WT('.') && | ||||
| 			    canon[canon_len-2] == QSE_WT('.') && | ||||
| 			    IS_WSEP(canon[canon_len-1])) | ||||
| 			    QSE_ISPATHWCSEP(canon[canon_len-1])) | ||||
| 			{ | ||||
| 				canon[--canon_len] = QSE_WT('\0'); | ||||
| 			} | ||||
| 		} | ||||
| 		else if (canon_len > adj_base_len) | ||||
| 		{ | ||||
| 			if (IS_WSEP(canon[canon_len-4]) && | ||||
| 			if (QSE_ISPATHWCSEP(canon[canon_len-4]) && | ||||
| 			    canon[canon_len-3] == QSE_WT('.') && | ||||
| 			    canon[canon_len-2] == QSE_WT('.') && | ||||
| 			    IS_WSEP(canon[canon_len-1])) | ||||
| 			    QSE_ISPATHWCSEP(canon[canon_len-1])) | ||||
| 			{ | ||||
| 				canon[--canon_len] = QSE_WT('\0'); | ||||
| 			} | ||||
|  | ||||
							
								
								
									
										66
									
								
								qse/lib/cmn/path-core.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								qse/lib/cmn/path-core.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | ||||
| /* | ||||
|  * $Id$ | ||||
|  * | ||||
|     Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved. | ||||
|  | ||||
|     Redistribution and use in source and binary forms, with or without | ||||
|     modification, are permitted provided that the following conditions | ||||
|     are met: | ||||
|     1. Redistributions of source code must retain the above copyright | ||||
|        notice, this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright | ||||
|        notice, this list of conditions and the following disclaimer in the | ||||
|        documentation and/or other materials provided with the distribution. | ||||
|  | ||||
|     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||||
|     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||
|     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||
|     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
|     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||
|     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
|     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
|     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
|     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <qse/cmn/path.h> | ||||
|  | ||||
|  | ||||
| qse_mchar_t* qse_mbspathcore (const qse_mchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (QSE_ISPATHMBDRIVE(path)) return (qse_mchar_t*)path + 2; | ||||
| 	#if defined(_WIN32) | ||||
| 	else if (QSE_ISPATHMBSEP(*path) && QSE_ISPATHMBSEP(*(path + 1)) && !QSE_ISPATHMBSEPORNIL(*(path + 2))) | ||||
| 	{ | ||||
| 		/* UNC Path */ | ||||
| 		path += 2; | ||||
| 		do { path++; } while (!QSE_ISPATHMBSEPORNIL(*path)); | ||||
| 		if (QSE_ISPATHMBSEP(*path)) return (qse_mchar_t*)path; | ||||
| 	} | ||||
| 	#endif | ||||
| /* TOOD: \\server\XXX \\.\XXX \\?\XXX \\?\UNC\server\XXX */ | ||||
| 	 | ||||
| #endif | ||||
| 	return (qse_mchar_t*)path; | ||||
| } | ||||
|  | ||||
| qse_wchar_t* qse_wcspathcore (const qse_wchar_t* path) | ||||
| { | ||||
| #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 	if (QSE_ISPATHWCDRIVE(path)) return (qse_wchar_t*)path + 2; | ||||
| 	#if defined(_WIN32) | ||||
| 	else if (QSE_ISPATHWCSEP(*path) && QSE_ISPATHWCSEP(*(path + 1)) && !QSE_ISPATHWCSEPORNIL(*(path + 2))) | ||||
| 	{ | ||||
| 		/* UNC Path */ | ||||
| 		path += 2; | ||||
| 		do { path++; } while (!QSE_ISPATHWCSEPORNIL(*path)); | ||||
| 		if (QSE_ISPATHWCSEP(*path)) return (qse_wchar_t*)path; | ||||
| 	} | ||||
| 	#endif | ||||
| /* TOOD: \\server\XXX \\.\XXX \\?\XXX \\?\UNC\server\XXX */ | ||||
| #endif | ||||
| 	return (qse_wchar_t*)path; | ||||
| } | ||||
|  | ||||
							
								
								
									
										104
									
								
								qse/lib/cmn/path-merge.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								qse/lib/cmn/path-merge.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | ||||
| /* | ||||
|  * $Id | ||||
|  * | ||||
|     Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved. | ||||
|  | ||||
|     Redistribution and use in source and binary forms, with or without | ||||
|     modification, are permitted provided that the following conditions | ||||
|     are met: | ||||
|     1. Redistributions of source code must retain the above copyright | ||||
|        notice, this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright | ||||
|        notice, this list of conditions and the following disclaimer in the | ||||
|        documentation and/or other materials provided with the distribution. | ||||
|  | ||||
|     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||||
|     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||
|     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||
|     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
|     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||
|     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
|     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
|     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
|     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <qse/cmn/path.h> | ||||
| #include <qse/cmn/str.h> | ||||
|  | ||||
| qse_mchar_t* qse_mergembspathdup (const qse_mchar_t* dir, const qse_mchar_t* file, qse_mmgr_t* mmgr) | ||||
| { | ||||
| 	const qse_mchar_t* seg[4]; | ||||
| 	qse_mchar_t tmp[2]; | ||||
| 	int idx = 0; | ||||
|  | ||||
| 	if (*dir != QSE_MT('\0')) | ||||
| 	{ | ||||
| 		seg[idx++] = dir; | ||||
|  | ||||
| 	#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 		while (!QSE_ISPATHMBSEPORNIL(*dir)) dir++; | ||||
| 		if (QSE_ISPATHMBSEP(*dir)) tmp[0] = *dir; | ||||
| 		else | ||||
| 		{ | ||||
| 			while (!QSE_ISPATHMBSEPORNIL(*file)) file++; | ||||
| 			if (QSE_ISPATHMBSEP(*file)) tmp[0] = *file; | ||||
| 			else tmp[0] = QSE_MT('\\'); | ||||
| 		} | ||||
| 	#else | ||||
| 		tmp[0] = QSE_MT('/'); | ||||
| 		tmp[1] = QSE_MT('\0'); | ||||
| 	#endif | ||||
|  | ||||
| 		while (*dir != QSE_MT('\0')) dir++; | ||||
|  | ||||
| 		if (!QSE_ISPATHMBSEP(*(dir - 1)) && !QSE_ISPATHMBSEP(*file)) | ||||
| 		{ | ||||
| 			seg[idx++] = tmp; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	seg[idx++] = file; | ||||
| 	seg[idx++] = QSE_NULL; | ||||
|  | ||||
| 	return qse_mbsadup (seg, QSE_NULL, mmgr); | ||||
| } | ||||
|  | ||||
| qse_wchar_t* qse_mergewcspathdup (const qse_wchar_t* dir, const qse_wchar_t* file, qse_mmgr_t* mmgr) | ||||
| { | ||||
| 	const qse_wchar_t* seg[4]; | ||||
| 	qse_wchar_t tmp[2]; | ||||
| 	int idx = 0; | ||||
|  | ||||
| 	if (*dir != QSE_WT('\0')) | ||||
| 	{ | ||||
| 		seg[idx++] = dir; | ||||
|  | ||||
| 	#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) | ||||
| 		while (!QSE_ISPATHWCSEPORNIL(*dir)) dir++; | ||||
| 		if (QSE_ISPATHWCSEP(*dir)) tmp[0] = *dir; | ||||
| 		else | ||||
| 		{ | ||||
| 			while (!QSE_ISPATHWCSEPORNIL(*file)) file++; | ||||
| 			if (QSE_ISPATHWCSEP(*file)) tmp[0] = *file; | ||||
| 			else tmp[0] = QSE_WT('\\'); | ||||
| 		} | ||||
| 	#else | ||||
| 		tmp[0] = QSE_WT('/'); | ||||
| 		tmp[1] = QSE_WT('\0'); | ||||
| 	#endif | ||||
|  | ||||
| 		while (*dir != QSE_WT('\0')) dir++; | ||||
|  | ||||
| 		if (!QSE_ISPATHWCSEP(*(dir - 1)) && !QSE_ISPATHWCSEP(*file)) | ||||
| 		{ | ||||
| 			seg[idx++] = tmp; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	seg[idx++] = file; | ||||
| 	seg[idx++] = QSE_NULL; | ||||
|  | ||||
| 	return qse_wcsadup (seg, QSE_NULL, mmgr); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user