rev 622 - in trunk: pr/test src

SVN User <[email protected]> Mon, 14 Jun 2004 03:42:54 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-14 03:42:51 -0400 (Mon, 14 Jun 2004)
New Revision: 622

Modified:
   trunk/pr/test/test.pr
   trunk/src/builtins-file.c
Log:
all but 2 or 3 of the Dir methods are implemented

Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-06-13 22:51:31 UTC (rev 621)
+++ trunk/pr/test/test.pr	2004-06-14 07:42:51 UTC (rev 622)
@@ -1,5 +1,25 @@
 #!/usr/bin/env prothon
 
-d = Dir('.')
-dd = d.dir()
-print d, dd
\ No newline at end of file
+d = Dir()
+print 'dir:',d, ' len:', len(d), d.path, d.name
+print
+print '--- dirs ---'
+dirs = d.dirs()
+for i in d.numDirs():
+	print "{0:-40.40} {1:-30.30}".fmt(dirs[i].path, dirs[i].name)
+print
+print '--- files ---'
+files = d.files()
+for i in d.numFiles():
+	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

Modified: trunk/src/builtins-file.c
===================================================================
--- trunk/src/builtins-file.c	2004-06-13 22:51:31 UTC (rev 621)
+++ trunk/src/builtins-file.c	2004-06-14 07:42:51 UTC (rev 622)
@@ -88,6 +88,8 @@
     apr_status_t aprerr;
 	apr_pool_t *subpool = NULL;
 	pr_file_p filep;
+	char* temp, *p2, *p1, *p0, *p, *dirpath;
+	obj_p new_obj;
 
 	if (fp) 
 		subpool = apr_file_pool_get(fp);
@@ -95,7 +97,26 @@
 		aprerr = apr_pool_create(&subpool, get_pr_head_pool());
 		IF_APR_ERR("out of memory in set_file_obj_data()") return;
 	}
-	set_attr(ist, file_obj, sym(ist, "name"), filename);
+	temp = pr2c_strptr(ist, filename);
+	p0 = temp;
+	p2 = p0 + strlen(p0); 
+	if (*(p2-1) == '/') {
+		aprerr = apr_filepath_merge( &dirpath, NULL, temp, 
+                                     APR_FILEPATH_TRUENAME, subpool );
+		IF_APR_ERR("error in filepath_merge") return;
+#ifdef WIN32
+	for(p=dirpath; *p; p++) *p = tolower(*p);
+#endif
+		set_attr(ist, file_obj, sym(ist, "path"), NEW_STRING(dirpath));
+		p0 = dirpath;
+		p2 = p0 + strlen(p0) - 1;
+	} else
+		set_attr(ist, file_obj, sym(ist, "path"), filename);
+	for (p1=p2-1; p1 >= p0 && *p1 != '/'; p1--);
+	if (*p1 != '/') new_obj = NEW_STRING("");
+	else new_obj = NEW_STRINGN(p1+1, p2-p1-1);
+	set_attr(ist, file_obj, sym(ist, "name"), new_obj);
+
 	if (mode)
 		set_attr(ist, file_obj, sym(ist, "mode"), mode);
 
@@ -124,11 +145,15 @@
 }
 
 //*************************** new_dir_obj *************************************
-static obj_p new_dir_obj(isp ist, obj_p path) {
-	obj_p dir_obj;
-	dir_obj = NEW_OBJ(Dir_OBJ);
+static obj_p new_dir_obj(isp ist, char* path) {
+	obj_p dir_obj = NEW_OBJ(Dir_OBJ);
+	char* temp = pr_malloc(strlen(path)+2);
+	strcpy(temp, path);
+	if (temp[strlen(temp)-1] != '/') strcat(temp, "/");
+	set_file_obj_data(ist, dir_obj, NEW_STRING(temp), NULL, NULL, 0, APR_READ);
 	SET_TYPE_IF_EXC(Dir_OBJ, dir_obj, DATA_TYPE_DATAPTR) return NULL;
-	set_file_obj_data(ist, dir_obj, path, NULL, NULL, 0, APR_READ);
+	set_immutable(dir_obj);
+	pr_free(temp);
 	return dir_obj;
 }
 
@@ -144,34 +169,20 @@
 }
 
 DEF(Dir, init_, FPARM1(path, NEW_STRING("."))) {
-    apr_status_t aprerr; 
-    apr_finfo_t finfo;
-	pr_file_p filep;
-	char *path;
-	const char *newpath;
-
+	char *path, *temp;
 	BIN_EMPTY_CHK();
 	STRING_PARAM(1, path);
 	read_unlock(ist, self);
+	temp = pr_malloc(strlen(path)+2);
+	strcpy(temp, path);
+	if (temp[strlen(temp)-1] != '/') strcat(temp, "/");
+	set_file_obj_data(ist, self, NEW_STRING(temp), NULL, NULL, 0, APR_READ);
 	SET_TYPE_IF_EXC(Dir_OBJ, self, DATA_TYPE_DATAPTR) {
 		read_lock(ist, self);  return NULL;
 	}
-	set_file_obj_data(ist, self, parms[1], NULL, NULL, 0, APR_READ);
-	filep = self->data.ptr;
-	aprerr = apr_stat(&finfo, path, APR_FINFO_NAME|APR_FINFO_ICASE, filep->pool);
-	if (finfo.valid & (APR_FINFO_NAME|APR_FINFO_ICASE)) {
-		if (finfo.filetype != APR_DIR) {
-			raise_exception( ist, OBJ(IO_EXC), "invalid directory type (%d)", 
-				             finfo.filetype );
-			return NULL;
-		}
-		newpath = finfo.fname;
-		if (!newpath) newpath = finfo.name;
-		if (newpath)
-			set_attr(ist, self, sym(ist, "name"), NEW_STRING((char*)newpath));
-		set_attr(ist, self, sym(ist, "exists"), OBJ(PR_TRUE));
-	}
 	read_lock(ist, self);
+	set_immutable(self);
+	pr_free(temp);
 	return OBJ(NONE);
 }
 
@@ -180,12 +191,24 @@
 DEF(Dir, str_, NULL) {
 	char buf[300], *path;
 	BIN_STR_CHK(Dir);
-	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "name")));
+	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	apr_snprintf(buf, sizeof(buf), "<Dir:'%s'>", path);
 	pr_free(path);
 	return NEW_STRING(buf);
 }
 
+DEF(Dir, exists_QUES, NULL) {
+	apr_finfo_t finfo;
+	char* path;
+	pr_file_p filep;
+	BIN_CONTENT_CHK(Dir);
+	filep = self->data.ptr;
+	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
+	apr_stat(&finfo, path, APR_FINFO_MIN, filep->pool);
+	if (finfo.filetype == APR_DIR)  return OBJ(PR_TRUE);
+	else                            return OBJ(PR_FALSE);
+}
+
 DEF(Dir, make, FPARM1(uperm, NEW_INT(APR_UREAD|APR_UWRITE|APR_UEXECUTE))) {
     apr_status_t aprerr; 
 	char* path;
@@ -194,24 +217,152 @@
 	BIN_CONTENT_CHK(Dir);
 	INT_32_PARAM(1, uperm);
 	filep = self->data.ptr;
-	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "name")));
-	aprerr = apr_dir_make(path, uperm, filep->pool);
+	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);
 }
 
 DEF(Dir, dir, NULL) {
-    apr_status_t aprerr; 
-	char *path, *respath;
+    apr_status_t aprerr;
+	const char *rootpath, *filepath;
+	char *temp, *tempp, *respath;
 	pr_file_p filep;
 	BIN_CONTENT_CHK(Dir);
 	filep = self->data.ptr;
-	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "name")));
-	aprerr = apr_filepath_merge(&respath, path, "..", 0, filep->pool);
+	filepath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
+	tempp = temp = pr_malloc(strlen(filepath)+1);
+	strcpy(temp, filepath);
+	aprerr = apr_filepath_root(&rootpath, &temp, APR_FILEPATH_TRUENAME, filep->pool);
+	IF_APR_ERR("calculating root path") return NULL;
+	if (!(*temp)) {
+		raise_exception( ist, OBJ(IO_EXC), "directory is root and has no parent");
+		return NULL;
+	}
+	pr_free(tempp);
+	aprerr = apr_filepath_merge(&respath, filepath, "..", APR_FILEPATH_TRUENAME, filep->pool);
 	IF_APR_ERR("Unable to calculate parent of directory") return NULL;
-	return new_dir_obj(ist, NEW_STRING(respath));
+	return new_dir_obj(ist, respath);
 }
 
+DEF(Dir, isRoot_QUES, NULL) {
+    apr_status_t aprerr; 
+	const char *rootpath, *filepath;
+	pr_file_p filep;
+	BIN_CONTENT_CHK(Dir);
+	filep = self->data.ptr;
+	filepath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
+	aprerr = apr_filepath_root(&rootpath, &filepath, APR_FILEPATH_TRUENAME, filep->pool);
+	IF_APR_ERR("calculating root path") return NULL;
+	if (*filepath) return OBJ(PR_FALSE);
+	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);
+}
+
+DEF(Dir, numFiles, NULL) {
+	BIN_CONTENT_CHK(Dir);
+	return dir_list(ist, self, APR_REG, DLIST_COUNT, NULL);
+}
+
+DEF(Dir, dirs, NULL) {
+	BIN_CONTENT_CHK(Dir);
+	return dir_list(ist, self, APR_DIR, DLIST_FILENAMES, NULL);
+}
+
+DEF(Dir, numDirs, NULL) {
+	BIN_CONTENT_CHK(Dir);
+	return dir_list(ist, self, APR_DIR, DLIST_COUNT, NULL);
+}
+
+DEF(Dir, len_, NULL) {
+	BIN_CONTENT_CHK(Dir);
+	return dir_list(ist, self, -1, DLIST_COUNT, NULL);
+}
+
+DEF(Dir, size, NULL) {
+	BIN_CONTENT_CHK(Dir);
+	return dir_list(ist, self, APR_REG, DLIST_SIZE, NULL);
+}
+
+DEF(Dir, rename, FPARM1(name, NULL)) {
+	apr_status_t aprerr;
+	char *name, *dirpath;
+	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")));
+	aprerr = apr_file_rename(dirpath, name, filep->pool);
+	IF_APR_ERR("renaming a directory") return NULL;
+
+	return new_dir_obj(ist, name);
+}
+
+DEF(Dir, eq__QUES, FORM_RPARAM) {
+	obj_p self_path, other_path;
+	BIN_CONTENT_CHK(Dir);
+	CHECK_TYPE_EXC(parms[1], Dir_OBJ, Directory);
+	self_path  = get_attr(ist,     self, sym(ist, "path"));
+	other_path = get_attr(ist, parms[1], sym(ist, "path"));
+	return call_func1(ist, self_path, SYM(EQ__QUES), other_path);
+}
+
 DEF(Dir, objList_, FORM_RPARAM) {
 	return parms[1];
 }
@@ -288,8 +439,13 @@
 	return OBJ(NONE);
 }
 
-DEF(File, objList_, FORM_RPARAM) {
-	return parms[1];
+DEF(File, str_, NULL) {
+	char buf[300], *path;
+	BIN_STR_CHK(File);
+	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
+	apr_snprintf(buf, sizeof(buf), "<File:'%s'>", path);
+	pr_free(path);
+	return NEW_STRING(buf);
 }
 
 DEF(File, close, NULL) {
@@ -812,6 +968,10 @@
 	return new_file_obj(ist, file, mode, fp, MIN_BUFSIZE, flags);
 }
 
+DEF(File, objList_, FORM_RPARAM) {
+	return parms[1];
+}
+
 MAIN_MODULE_INIT(File) {
 	apr_pool_t *std_pool;
 	apr_status_t aprerr;
@@ -820,12 +980,23 @@
 	MODULE_SUB_INIT(Dir);
 	MODULE_ADD_SYM(Dir, init_);
 	MODULE_ADD_SYM(Dir, str_);
+	MODULE_ADD_SYM(Dir, exists_QUES);
 	MODULE_ADD_SYM(Dir, make);
 	MODULE_ADD_SYM(Dir, dir);
+	MODULE_ADD_SYM(Dir, isRoot_QUES);
+	MODULE_ADD_SYM(Dir, files);
+	MODULE_ADD_SYM(Dir, dirs);
+	MODULE_ADD_SYM(Dir, numFiles);
+	MODULE_ADD_SYM(Dir, numDirs);
+	MODULE_ADD_SYM(Dir, len_);
+	MODULE_ADD_SYM(Dir, size);
+	MODULE_ADD_SYM(Dir, rename);
+	MODULE_ADD_SYM(Dir, eq__QUES);
 	MODULE_ADD_SYM(Dir, objList_);
 
 	MODULE_SUB_INIT(File);
 	MODULE_ADD_SYM(File, init_);
+	MODULE_ADD_SYM(File, str_);
 	MODULE_ADD_SYM(File, read);
 	MODULE_ADD_SYM(File, readLine);
 	MODULE_ADD_SYM(File, readLines);