summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--hieroglyph/hgfile.c63
-rw-r--r--hieroglyph/hgfile.h1
-rw-r--r--hieroglyph/hgtypes.h1
-rw-r--r--hieroglyph/operator.c38
-rw-r--r--hieroglyph/version.h.in2
-rw-r--r--src/hgspy.c7
7 files changed, 98 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index e9eb9e8..395f1de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2006-07-18 Akira TAGOH <at@gclab.org>
+ * hieroglyph/operator.c (_hg_operator_op_closefile): implemented.
+
+ * hieroglyph/hgfile.c (_hg_file_object_real_free): use
+ hg_file_object_close instead of handling a close process directly.
+ (hg_file_object_close): new function.
+
+ * src/hgspy.c (_hgspy_file_close_cb): new function.
+
* hieroglyph/operator.c (_hg_operator_op_bytesavailable): implemented.
(_hg_operator_op_ceiling): implemented.
diff --git a/hieroglyph/hgfile.c b/hieroglyph/hgfile.c
index f115bb8..512d359 100644
--- a/hieroglyph/hgfile.c
+++ b/hieroglyph/hgfile.c
@@ -98,25 +98,9 @@ _hg_file_object_real_free(gpointer data)
{
HgFileObject *file = data;
- switch (HG_FILE_GET_FILE_TYPE (file)) {
- case HG_FILE_TYPE_FILE:
- if (file->is.file.is_mmap)
- munmap(file->is.file.mmap.buffer, file->is.file.mmap.bufsize);
- if (file->is.file.fd != -1)
- close(file->is.file.fd);
- break;
- case HG_FILE_TYPE_BUFFER:
- case HG_FILE_TYPE_STDIN:
- case HG_FILE_TYPE_STDOUT:
- case HG_FILE_TYPE_STDERR:
- case HG_FILE_TYPE_STATEMENT_EDIT:
- case HG_FILE_TYPE_LINE_EDIT:
- case HG_FILE_TYPE_BUFFER_WITH_CALLBACK:
- break;
- default:
- g_warning("Unknown file type %d was given to be freed.", HG_FILE_GET_FILE_TYPE (file));
- break;
- }
+ if (hg_file_object_is_writable(file))
+ hg_file_object_flush(file);
+ hg_file_object_close(file);
}
static void
@@ -855,7 +839,46 @@ hg_file_object_seek(HgFileObject *object,
return retval;
}
-
+
+void
+hg_file_object_close(HgFileObject *object)
+{
+ g_return_if_fail (object != NULL);
+
+ object->ungetc = 0;
+ object->is_eof = TRUE;
+ switch (HG_FILE_GET_FILE_TYPE (object)) {
+ case HG_FILE_TYPE_FILE:
+ if (object->is.file.is_mmap) {
+ munmap(object->is.file.mmap.buffer, object->is.file.mmap.bufsize);
+ object->is.file.is_mmap = FALSE;
+ }
+ if (object->is.file.fd != -1) {
+ close(object->is.file.fd);
+ object->is.file.fd = -1;
+ }
+ break;
+ case HG_FILE_TYPE_STDIN:
+ case HG_FILE_TYPE_STDOUT:
+ case HG_FILE_TYPE_STDERR:
+ /* just ignore for them */
+ break;
+ case HG_FILE_TYPE_BUFFER:
+ case HG_FILE_TYPE_STATEMENT_EDIT:
+ case HG_FILE_TYPE_LINE_EDIT:
+ object->is.buf.pos = 0;
+ object->is.buf.bufsize = 0;
+ break;
+ case HG_FILE_TYPE_BUFFER_WITH_CALLBACK:
+ object->is.callback.vtable->close(object->is.callback.user_data);
+ break;
+ default:
+ g_warning("Unknown file type %d was given to be closed.",
+ HG_FILE_GET_FILE_TYPE (object));
+ break;
+ }
+}
+
gboolean
hg_file_object_is_readable(HgFileObject *object)
{
diff --git a/hieroglyph/hgfile.h b/hieroglyph/hgfile.h
index af32617..9017a32 100644
--- a/hieroglyph/hgfile.h
+++ b/hieroglyph/hgfile.h
@@ -64,6 +64,7 @@ gboolean hg_file_object_flush (HgFileObject *object);
gssize hg_file_object_seek (HgFileObject *object,
gssize offset,
HgFilePosType whence);
+void hg_file_object_close (HgFileObject *object);
gboolean hg_file_object_is_readable(HgFileObject *object);
gboolean hg_file_object_is_writable(HgFileObject *object);
void hg_file_object_printf (HgFileObject *object,
diff --git a/hieroglyph/hgtypes.h b/hieroglyph/hgtypes.h
index dcfa518..4d47df7 100644
--- a/hieroglyph/hgtypes.h
+++ b/hieroglyph/hgtypes.h
@@ -340,6 +340,7 @@ struct _HieroGlyphFileObjectCallback {
gssize (* seek) (gpointer user_data,
gssize offset,
HgFilePosType whence);
+ void (* close) (gpointer user_data);
gboolean (* is_eof) (gpointer user_data);
void (* clear_eof) (gpointer uesr_data);
gint (* get_error_code) (gpointer user_data);
diff --git a/hieroglyph/operator.c b/hieroglyph/operator.c
index c153bf3..6adb809 100644
--- a/hieroglyph/operator.c
+++ b/hieroglyph/operator.c
@@ -1356,7 +1356,43 @@ G_STMT_START
} G_STMT_END;
DEFUNC_OP_END
-DEFUNC_UNIMPLEMENTED_OP (closefile);
+DEFUNC_OP (closefile)
+G_STMT_START
+{
+ HgStack *ostack = hg_vm_get_ostack(vm);
+ guint depth = hg_stack_depth(ostack);
+ HgValueNode *n;
+ HgFileObject *file;
+
+ while (1) {
+ if (depth < 1) {
+ _hg_operator_set_error(vm, op, VM_e_stackunderflow);
+ break;
+ }
+ n = hg_stack_index(ostack, 0);
+ if (!HG_IS_VALUE_FILE (n)) {
+ _hg_operator_set_error(vm, op, VM_e_typecheck);
+ break;
+ }
+ if (!hg_object_is_readable((HgObject *)n)) {
+ _hg_operator_set_error(vm, op, VM_e_invalidaccess);
+ break;
+ }
+ file = HG_VALUE_GET_FILE (n);
+ if (hg_file_object_is_writable(file)) {
+ if (!hg_object_is_writable((HgObject *)file)) {
+ _hg_operator_set_error(vm, op, VM_e_invalidaccess);
+ break;
+ }
+ hg_file_object_flush(file);
+ }
+ hg_file_object_close(file);
+ hg_stack_pop(ostack);
+ retval = TRUE;
+ break;
+ }
+} G_STMT_END;
+DEFUNC_OP_END
DEFUNC_OP (closepath)
G_STMT_START
diff --git a/hieroglyph/version.h.in b/hieroglyph/version.h.in
index f3b948a..d35afe2 100644
--- a/hieroglyph/version.h.in
+++ b/hieroglyph/version.h.in
@@ -29,7 +29,7 @@
G_BEGIN_DECLS
#define HIEROGLYPH_VERSION "@VERSION@"
-#define HIEROGLYPH_UUID "ef650702-f80d-4940-b548-1621efe52188"
+#define HIEROGLYPH_UUID "91e93c07-15b6-449e-b36e-4ee0a443ac56"
const char *__hg_rcsid G_GNUC_UNUSED = "$Rev$";
diff --git a/src/hgspy.c b/src/hgspy.c
index bec5f29..6ef3a98 100644
--- a/src/hgspy.c
+++ b/src/hgspy.c
@@ -242,6 +242,12 @@ _hgspy_file_seek_cb(gpointer user_data,
return -1;
}
+static void
+_hgspy_file_close_cb(gpointer user_data)
+{
+ g_print("FIXME: close.\n");
+}
+
static gboolean
_hgspy_file_is_eof_cb(gpointer user_data)
{
@@ -274,6 +280,7 @@ _hgspy_vm_thread(gpointer data)
.getc = _hgspy_file_getc_cb,
.flush = _hgspy_file_flush_cb,
.seek = _hgspy_file_seek_cb,
+ .close = _hgspy_file_close_cb,
.is_eof = _hgspy_file_is_eof_cb,
.clear_eof = _hgspy_file_clear_eof_cb,
.get_error_code = _hgspy_file_get_error_code_cb,