summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--hieroglyph/operator.c95
-rw-r--r--hieroglyph/version.h.in2
-rw-r--r--tests/ps/currentfile.ps4
4 files changed, 102 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 395f1de..2b1d014 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,10 @@
2006-07-18 Akira TAGOH <at@gclab.org>
+ * tests/ps/currentfile.ps: new file.
+
* hieroglyph/operator.c (_hg_operator_op_closefile): implemented.
+ (_hg_operator_op_currentfile): implemented.
+ (_hg_operator_op_readline): implemented.
* hieroglyph/hgfile.c (_hg_file_object_real_free): use
hg_file_object_close instead of handling a close process directly.
diff --git a/hieroglyph/operator.c b/hieroglyph/operator.c
index 6adb809..eb5387d 100644
--- a/hieroglyph/operator.c
+++ b/hieroglyph/operator.c
@@ -1849,7 +1849,34 @@ G_STMT_START
} G_STMT_END;
DEFUNC_OP_END
-DEFUNC_UNIMPLEMENTED_OP (currentfile);
+DEFUNC_OP (currentfile)
+G_STMT_START
+{
+ HgStack *ostack = hg_vm_get_ostack(vm);
+ HgStack *estack = hg_vm_get_estack(vm);
+ guint edepth = hg_stack_depth(estack), i;
+ HgValueNode *n;
+ HgFileObject *file = NULL;
+ HgMemPool *pool = hg_vm_get_current_pool(vm);
+
+ for (i = 0; i < edepth; i++) {
+ n = hg_stack_index(estack, i);
+ if (HG_IS_VALUE_FILE (n)) {
+ file = HG_VALUE_GET_FILE (n);
+ break;
+ }
+ }
+ if (file == NULL) {
+ /* make an invalid file object */
+ file = hg_file_object_new(pool, HG_FILE_TYPE_BUFFER, HG_FILE_MODE_READ, "%invalid", "", 0);
+ }
+ HG_VALUE_MAKE_FILE (n, file);
+ retval = hg_stack_push(ostack, n);
+ if (!retval)
+ _hg_operator_set_error(vm, op, VM_e_stackoverflow);
+} G_STMT_END;
+DEFUNC_OP_END
+
DEFUNC_UNIMPLEMENTED_OP (currentflat);
DEFUNC_UNIMPLEMENTED_OP (currentfont);
DEFUNC_UNIMPLEMENTED_OP (currentgray);
@@ -4620,7 +4647,71 @@ G_STMT_START
DEFUNC_OP_END
DEFUNC_UNIMPLEMENTED_OP (readhexstring);
-DEFUNC_UNIMPLEMENTED_OP (readline);
+
+DEFUNC_OP (readline)
+G_STMT_START
+{
+ HgStack *ostack = hg_vm_get_ostack(vm);
+ guint depth = hg_stack_depth(ostack);
+ HgValueNode *n1, *n2;
+ HgString *s, *sresult;
+ HgFileObject *file;
+ guchar c;
+ guint length = 0, maxlength;
+ gboolean result = FALSE;
+ HgMemPool *pool = hg_vm_get_current_pool(vm);
+
+ while (1) {
+ if (depth < 2) {
+ _hg_operator_set_error(vm, op, VM_e_stackunderflow);
+ break;
+ }
+ n2 = hg_stack_index(ostack, 0);
+ n1 = hg_stack_index(ostack, 1);
+ if (!HG_IS_VALUE_FILE (n1) ||
+ !HG_IS_VALUE_STRING (n2)) {
+ _hg_operator_set_error(vm, op, VM_e_typecheck);
+ break;
+ }
+ if (!hg_object_is_readable((HgObject *)n1) ||
+ !hg_object_is_writable((HgObject *)n2)) {
+ _hg_operator_set_error(vm, op, VM_e_invalidaccess);
+ break;
+ }
+ file = HG_VALUE_GET_FILE (n1);
+ s = HG_VALUE_GET_STRING (n2);
+ maxlength = hg_string_maxlength(s);
+ while (!hg_file_object_is_eof(file)) {
+ c = hg_file_object_getc(file);
+ if (c == '\r') {
+ c = hg_file_object_getc(file);
+ if (c != '\n')
+ hg_file_object_ungetc(file, c);
+ result = TRUE;
+ break;
+ } else if (c == '\n') {
+ result = TRUE;
+ break;
+ }
+ if (length > maxlength) {
+ _hg_operator_set_error(vm, op, VM_e_rangecheck);
+ return FALSE;
+ }
+ hg_string_insert_c(s, c, length++);
+ }
+ sresult = hg_string_make_substring(pool, s, 0, length - 1);
+ HG_VALUE_MAKE_STRING (n1, sresult);
+ HG_VALUE_MAKE_BOOLEAN (pool, n2, result);
+ hg_stack_pop(ostack);
+ hg_stack_pop(ostack);
+ hg_stack_push(ostack, n1);
+ retval = hg_stack_push(ostack, n2);
+ /* it must be true */
+ break;
+ }
+} G_STMT_END;
+DEFUNC_OP_END
+
DEFUNC_UNIMPLEMENTED_OP (readonly);
DEFUNC_UNIMPLEMENTED_OP (readstring);
diff --git a/hieroglyph/version.h.in b/hieroglyph/version.h.in
index d35afe2..8d4de1c 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 "91e93c07-15b6-449e-b36e-4ee0a443ac56"
+#define HIEROGLYPH_UUID "a0a8c3cc-7a90-4c2a-85c2-bec07ec78629"
const char *__hg_rcsid G_GNUC_UNUSED = "$Rev$";
diff --git a/tests/ps/currentfile.ps b/tests/ps/currentfile.ps
new file mode 100644
index 0000000..c002a7b
--- /dev/null
+++ b/tests/ps/currentfile.ps
@@ -0,0 +1,4 @@
+/str 100 string def
+currentfile str readline
+here is a line of text
+pop ==