rev 623 - in trunk: . pr/test src

SVN User <[email protected]> Mon, 14 Jun 2004 16:29:49 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-14 16:29:45 -0400 (Mon, 14 Jun 2004)
New Revision: 623

Modified:
   trunk/STATUS.txt
   trunk/pr/test/test.pr
   trunk/src/builtins-file.c
Log:
added Dir.copy() and Dir.move()

Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt	2004-06-14 07:42:51 UTC (rev 622)
+++ trunk/STATUS.txt	2004-06-14 20:29:45 UTC (rev 623)
@@ -1,11 +1,6 @@
 
 ----------------------- TO-DO (highest priority first) ------------------------
 
---- check immutable bit for default param values
---- remove all clr_immutable calls
-
---- add vars_ flag to str.fmt() or implement taint bit
-
 --- Complete File/Dir objects
 		http://www.prothon.org/pipermail/prothon-user/2004-April/000955.html
 --- TextFile object
@@ -13,6 +8,13 @@
 --- support any object that supports file methods in stdxxx (duck std)
 		http://www.prothon.org/pipermail/prothon-user/2004-June/001769.html	
 
+--- implement 1xc3fe ?
+
+--- check immutable bit for default param values or make new default object each use
+--- remove all clr_immutable calls
+
+--- add vars_ flag to str.fmt() or implement taint bit and unTaint() method
+
 --- add \u0000 \U00000000 and \N{name} esc sequences
 
 --- unicode module - codecs

Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-06-14 07:42:51 UTC (rev 622)
+++ trunk/pr/test/test.pr	2004-06-14 20:29:45 UTC (rev 623)
@@ -1,5 +1,6 @@
 #!/usr/bin/env prothon
 
+/*
 d = Dir()
 print 'dir:',d, ' len:', len(d), d.path, d.name
 print
@@ -14,12 +15,8 @@
 	print "{0:-40.40} {1:-30.30}".fmt(files[i].path, files[i].name)
 print
 
-d = Dir('def')
-print d
-dd = d.rename('abc')
-print d, d.exists?(), dd, dd.exists?()
-
-print Dir('/prothon').size()
-
-
-print Dir(), Dir('../src'), Dir() == Dir('../src')
\ No newline at end of file
+d = Dir('abc')
+print d, d.exists?()
+d2 = d.copy(Dir('/def'))
+print d, d.exists?(), d2, d2.exists?()
+*/
\ No newline at end of file

Modified: trunk/src/builtins-file.c
===================================================================
--- trunk/src/builtins-file.c	2004-06-14 07:42:51 UTC (rev 622)
+++ trunk/src/builtins-file.c	2004-06-14 20:29:45 UTC (rev 623)
@@ -157,6 +157,83 @@
 	return dir_obj;
 }
 
+#define DLIST_COUNT		1
+#define DLIST_SIZE		2
+#define DLIST_FILENAMES 4
+#define DLIST_COPY		8
+
+obj_p dir_list( isp ist, obj_p self, int type, int dlist_action, 
+			    obj_p pattern, obj_p dest_dir, int uperms ) {
+	apr_finfo_t finfo;
+	apr_dir_t *dir;
+    apr_status_t aprerr; 
+	const char *dirpath, *destpath = NULL;
+	char *filepath, *filepath2;
+	pr_file_p filep;
+	obj_p uperms_obj = NULL, res = OBJ(NONE);
+	i64_t count = 0;
+	filep = self->data.ptr;
+	dirpath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
+	if (dest_dir) {
+		destpath = pr2c_strptr(ist, get_attr(ist, dest_dir, sym(ist, "path")));
+		uperms_obj = NEW_INT(uperms);
+	}
+	if (dlist_action == DLIST_FILENAMES) res = new_list_obj(ist, 10);
+	aprerr = apr_dir_open(&dir, dirpath, filep->pool);
+	IF_APR_ERR("opening directory") return NULL;
+	while (TRUE) {
+		aprerr = apr_dir_read(&finfo, APR_FINFO_DIRENT, dir);
+		if (aprerr == 720018) break;
+		IF_APR_ERR("reading directory") return NULL;
+		if (type == -1 || finfo.filetype == type) {
+			if (finfo.filetype == APR_REG || (strcmp(finfo.name, ".") && strcmp(finfo.name, ".."))) {
+				if (dlist_action & (DLIST_SIZE|DLIST_FILENAMES|DLIST_COPY)) {
+					aprerr = apr_filepath_merge( &filepath, dirpath, finfo.name, 
+												 APR_FILEPATH_TRUENAME, filep->pool );
+					IF_APR_ERR("Unable to calculate filepath") return NULL;
+				}
+				switch (dlist_action) {
+				case DLIST_COUNT: 
+					count++;  
+					break;
+				case DLIST_SIZE:
+					apr_stat(&finfo, filepath, APR_FINFO_SIZE, filep->pool);
+					count += finfo.size;
+					break;
+				case DLIST_FILENAMES:
+					list_append( ist, res, ( type == APR_REG ?
+								 new_file_obj(ist, NEW_STRING(filepath), NULL, NULL, 0, 0) : 
+								 new_dir_obj (ist, filepath) ) );
+					break;
+				case DLIST_COPY:
+					aprerr = apr_filepath_merge( &filepath2, destpath, finfo.name, 
+												APR_FILEPATH_TRUENAME, filep->pool );
+					IF_APR_ERR("Unable to calculate filepath(2)") return NULL;
+					if (finfo.filetype == APR_REG) {
+						aprerr = apr_file_copy(filepath, filepath2, uperms, filep->pool );
+						IF_APR_ERR("copying file") return NULL;
+					} else {
+						obj_p new_src_dir, new_dst_dir;
+						new_src_dir = new_dir_obj(ist, filepath);  if_exc_return NULL;
+						new_dst_dir = new_dir_obj(ist, filepath2); if_exc_return NULL;
+						call_func1(ist, new_dst_dir, sym(ist, "make"), uperms_obj); if_exc_return NULL;
+						call_func2(ist, new_src_dir, sym(ist, "copy"), new_dst_dir, uperms_obj); if_exc_return NULL;
+						del_unlock(new_src_dir);
+						del_unlock(new_dst_dir);
+					}
+                    break;
+				}
+			}
+		} else if (finfo.filetype != (type == APR_REG ? APR_DIR : APR_REG)) {
+			raise_exception( ist, OBJ(IO_EXC), "invalid file type (%d)", finfo.filetype);
+			return NULL;
+		}
+	}
+	apr_dir_close(dir);
+	if (dlist_action & (DLIST_COUNT|DLIST_SIZE)) res = NEW_INT(count);
+	return res;
+}
+
 //*************************** MODULE Dir **************************************
 
 MODULE_START(Dir)
@@ -220,7 +297,7 @@
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	aprerr = apr_dir_make_recursive(path, uperm, filep->pool);
 	IF_APR_ERR("Unable to make directory") return NULL;
-	return OBJ(NONE);
+	return self;
 }
 
 DEF(Dir, dir, NULL) {
@@ -258,102 +335,90 @@
 	else		   return OBJ(PR_TRUE);
 }
 
-#define DLIST_COUNT		1
-#define DLIST_SIZE		2
-#define DLIST_FILENAMES 4
-
-obj_p dir_list(isp ist, obj_p self, int type, int dlist_action, obj_p pattern) {
-	apr_finfo_t finfo;
-	apr_dir_t *dir;
-    apr_status_t aprerr; 
-	const char *dirpath;
-	char *filepath;
-	pr_file_p filep;
-	obj_p res = NULL;
-	i64_t count = 0;
-	filep = self->data.ptr;
-	dirpath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
-	if (dlist_action == DLIST_FILENAMES) res = new_list_obj(ist, 10);
-	aprerr = apr_dir_open(&dir, dirpath, filep->pool);
-	IF_APR_ERR("opening directory") return NULL;
-	while (TRUE) {
-		aprerr = apr_dir_read(&finfo, APR_FINFO_DIRENT, dir);
-		if (aprerr == 720018) break;
-		IF_APR_ERR("reading directory") return NULL;
-		if (type == -1 || finfo.filetype == type) {
-			obj_p new_obj;
-			if (finfo.filetype == APR_REG || (strcmp(finfo.name, ".") && strcmp(finfo.name, ".."))) {
-				if (dlist_action == DLIST_COUNT) count++;
-				else if (dlist_action == DLIST_SIZE) {
-					aprerr = apr_filepath_merge( &filepath, dirpath, finfo.name, 
-						                         APR_FILEPATH_TRUENAME, filep->pool );
-					IF_APR_ERR("Unable to calculate parent of directory") return NULL;
-					apr_stat(&finfo, filepath, APR_FINFO_SIZE, filep->pool);
-					count += finfo.size;
-				} else if (dlist_action == DLIST_FILENAMES) {
-					aprerr = apr_filepath_merge(&filepath, dirpath, finfo.name, APR_FILEPATH_TRUENAME, filep->pool);
-					IF_APR_ERR("Unable to calculate parent of directory") return NULL;
-					if (type == APR_REG)
-						new_obj = new_file_obj(ist, NEW_STRING(filepath), NULL, NULL, 0, 0);
-					else
-						new_obj = new_dir_obj(ist, filepath);
-					list_append(ist, res, new_obj);
-				}
-			}
-		} else if (finfo.filetype != (type == APR_REG ? APR_DIR : APR_REG)) {
-			raise_exception( ist, OBJ(IO_EXC), "invalid file type (%d)", finfo.filetype);
-			return NULL;
-		}
-	}
-	apr_dir_close(dir);
-	if (dlist_action & (DLIST_COUNT|DLIST_SIZE)) res = NEW_INT(count);
-	return res;
-}
-
 DEF(Dir, files, NULL) {
 	BIN_CONTENT_CHK(Dir);
-	return dir_list(ist, self, APR_REG, DLIST_FILENAMES, NULL);
+	return dir_list(ist, self, APR_REG, DLIST_FILENAMES, NULL, NULL, 0);
 }
 
 DEF(Dir, numFiles, NULL) {
 	BIN_CONTENT_CHK(Dir);
-	return dir_list(ist, self, APR_REG, DLIST_COUNT, NULL);
+	return dir_list(ist, self, APR_REG, DLIST_COUNT, NULL, NULL, 0);
 }
 
 DEF(Dir, dirs, NULL) {
 	BIN_CONTENT_CHK(Dir);
-	return dir_list(ist, self, APR_DIR, DLIST_FILENAMES, NULL);
+	return dir_list(ist, self, APR_DIR, DLIST_FILENAMES, NULL, NULL, 0);
 }
 
 DEF(Dir, numDirs, NULL) {
 	BIN_CONTENT_CHK(Dir);
-	return dir_list(ist, self, APR_DIR, DLIST_COUNT, NULL);
+	return dir_list(ist, self, APR_DIR, DLIST_COUNT, NULL, NULL, 0);
 }
 
 DEF(Dir, len_, NULL) {
 	BIN_CONTENT_CHK(Dir);
-	return dir_list(ist, self, -1, DLIST_COUNT, NULL);
+	return dir_list(ist, self, -1, DLIST_COUNT, NULL, NULL, 0);
 }
 
 DEF(Dir, size, NULL) {
 	BIN_CONTENT_CHK(Dir);
-	return dir_list(ist, self, APR_REG, DLIST_SIZE, NULL);
+	return dir_list(ist, self, APR_REG, DLIST_SIZE, NULL, NULL, 0);
 }
 
 DEF(Dir, rename, FPARM1(name, NULL)) {
 	apr_status_t aprerr;
-	char *name, *dirpath;
+	char *name, *dirpath, *p;
 	pr_file_p filep;
 	BIN_CONTENT_CHK(Dir);
 	STRING_PARAM(1, name);
 	filep = self->data.ptr;
 	dirpath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
+	for (p=name; *p; p++) 
+		if (*p == '/' || *p == '\\') {
+			raise_exception( ist, OBJ(VALUE_EXC), "slash chars not allowed in dir name: \"%s\"", name);
+			return NULL;
+		}
 	aprerr = apr_file_rename(dirpath, name, filep->pool);
 	IF_APR_ERR("renaming a directory") return NULL;
-
 	return new_dir_obj(ist, name);
 }
 
+DEF(Dir, move, FPARM1(dir, NULL)) {
+	apr_status_t aprerr;
+	char *dirpath1, *dirpath2;
+	pr_file_p filep;
+	BIN_CONTENT_CHK(Dir);
+	CHECK_TYPE_EXC(parms[1], Dir_OBJ, Directory);
+	filep = self->data.ptr;
+	dirpath1 = pr2c_strptr(ist, get_attr(ist,     self, sym(ist, "path")));
+	dirpath2 = pr2c_strptr(ist, get_attr(ist, parms[1], sym(ist, "path")));
+	aprerr = apr_file_rename(dirpath1, dirpath2, filep->pool);
+	IF_APR_ERR("moving a directory") return NULL;
+	return parms[1];
+}
+
+DEF(Dir, copy, FPARM2(dir, NULL, uperms, NEW_INT(0x600))) {
+	apr_status_t aprerr;
+	i32_t uperms;
+	char* path;
+	pr_file_p filep;
+	BIN_CONTENT_CHK(Dir);
+	CHECK_TYPE_EXC(parms[1], Dir_OBJ, Directory);
+	INT_32_PARAM(2, uperms);
+	filep = self->data.ptr;
+	path = pr2c_strptr(ist, get_attr(ist, parms[1], sym(ist, "path")));
+	aprerr = apr_dir_make_recursive(path, uperms, filep->pool);
+	IF_APR_ERR("Unable to make directory") return NULL;
+	dir_list(ist, self, -1, DLIST_COPY, NULL, parms[1], uperms);
+	return parms[1];
+}
+/*
+DEF(Dir, delete, NULL) {
+	BIN_CONTENT_CHK(Dir);
+	dir_list(ist, self, -1, DLIST_COPY, NULL, parms[1], uperms);
+	return self;
+}
+*/
 DEF(Dir, eq__QUES, FORM_RPARAM) {
 	obj_p self_path, other_path;
 	BIN_CONTENT_CHK(Dir);
@@ -991,6 +1056,8 @@
 	MODULE_ADD_SYM(Dir, len_);
 	MODULE_ADD_SYM(Dir, size);
 	MODULE_ADD_SYM(Dir, rename);
+	MODULE_ADD_SYM(Dir, move);
+	MODULE_ADD_SYM(Dir, copy);
 	MODULE_ADD_SYM(Dir, eq__QUES);
 	MODULE_ADD_SYM(Dir, objList_);