Author: iratqq
Date: Sun Jan 18 11:12:29 2009
New Revision: 5745

Modified:
   trunk/uim/uim-posix.c

Log:
* uim/uim-posix.c (make_args_or)
  (make_arg_list, c_file_open_flags, c_file_open_mode)
  (c_file_open, c_file_close, c_file_read, c_file_write):
  - New function.
  (uim_init_posix_subrs): New init_procs.

  low-level I/O functions for uim-scm.
  Note that input/output buffer must be list of integer.


Modified: trunk/uim/uim-posix.c
==============================================================================
--- trunk/uim/uim-posix.c       (original)
+++ trunk/uim/uim-posix.c       Sun Jan 18 11:12:29 2009
@@ -45,11 +45,14 @@
 #include <pwd.h>
 #include <errno.h>
 #include <assert.h>
+#include <fcntl.h>

+#include "uim.h"
 #include "uim-internal.h"
 #include "uim-scm.h"
 #include "uim-scm-abbrev.h"
 #include "uim-posix.h"
+#include "uim-notify.h"

 uim_bool
 uim_get_user_name(char *name, int len, int uid)
@@ -319,6 +322,154 @@
   return MAKE_INT(sleep((unsigned int)C_INT(seconds_)));
 }

+typedef struct {
+  int flag;
+  char *arg;
+} or_args;
+
+static int
+make_args_or(const or_args *list, char *arg)
+{
+  int flags = 0;
+  int i = 0;
+
+  while (1) {
+    if (list[i].arg == 0) {
+      uim_notify_fatal("Unknown flag %s", arg);
+      return 0;
+    }
+    if (strcmp(list[i].arg, arg) == 0) {
+      flags = list[i].flag;
+      break;
+    }
+    i++;
+  }
+  return flags;
+}
+
+static uim_lisp
+make_arg_list(const or_args *list)
+{
+  uim_lisp ret_;
+  int i = 0;
+
+  ret_ = uim_scm_null();
+  while (list[i].arg != 0) {
+    ret_ = CONS(MAKE_SYM(list[i].arg), ret_);
+    i++;
+  }
+  return ret_;
+}
+
+const static or_args open_flags[] = {
+  { O_CREAT,    "$O_CREAT" },
+  { O_EXCL,     "$O_EXCL" },
+  { O_EXLOCK,   "$O_EXLOCK" },
+  { O_NONBLOCK, "$O_NONBLOCK" },
+  { O_RDONLY,   "$O_RDONLY" },
+  { O_RDWR,     "$O_RDWR" },
+  { O_SHLOCK,   "$O_SHLOCK" },
+  { O_TRUNC,    "$O_TRUNC" },
+  { 0, 0 }
+};
+
+const static or_args open_mode[] = {
+  { S_IRWXU, "$S_IRWXU" },
+  { S_IRUSR, "$S_IRUSR" },
+  { S_IWUSR, "$S_IWUSR" },
+  { S_IXUSR, "$S_IXUSR" },
+
+  { S_IRWXG, "$S_IRWXG" },
+  { S_IRGRP, "$S_IRGRP" },
+  { S_IWGRP, "$S_IWGRP" },
+  { S_IXGRP, "$S_IXGRP" },
+
+  { S_IRWXO, "$S_IRWXO" },
+  { S_IROTH, "$S_IROTH" },
+  { S_IWOTH, "$S_IWOTH" },
+  { S_IXOTH, "$S_IXOTH" },
+  { 0, 0 }
+};
+
+
+static uim_lisp uim_lisp_open_flags;
+static uim_lisp
+c_file_open_flags(void)
+{
+  return uim_lisp_open_flags;
+}
+
+static uim_lisp uim_lisp_open_mode;
+static uim_lisp
+c_file_open_mode(void)
+{
+  return uim_lisp_open_mode;
+}
+
+static uim_lisp
+c_file_open(uim_lisp path_, uim_lisp flags_, uim_lisp mode_)
+{
+  int flags = 0;
+  int mode = 0;
+
+  while (!NULLP(flags_)) {
+    flags |= make_args_or(open_flags, C_SYM(CAR(flags_)));
+    flags_ = CDR(flags_);
+  }
+  while (!NULLP(mode_)) {
+    mode |= make_args_or(open_mode, C_SYM(CAR(mode_)));
+    mode_ = CDR(mode_);
+  }
+  return MAKE_INT(open(REFER_C_STR(path_), flags, mode));
+}
+
+static uim_lisp
+c_file_close(uim_lisp fd_)
+{
+  return MAKE_INT(close(C_INT(fd_)));
+}
+
+static uim_lisp
+c_file_read(uim_lisp d_, uim_lisp nbytes_)
+{
+  char *buf;
+  uim_lisp ret1_, ret2_;
+  int nbytes = C_INT(nbytes_);
+  int i;
+  char *p;
+
+  buf = uim_malloc(C_INT(nbytes_));
+  ret1_ = MAKE_INT((int)read(C_INT(d_), buf, nbytes));
+
+  p = buf;
+  ret2_ = uim_scm_null();
+  for (i = 0; i < nbytes; i++) {
+    ret2_ = CONS(MAKE_INT(*p), ret2_);
+    p++;
+  }
+  free(buf);
+  return CONS(ret1_, uim_scm_callf("reverse", "o", ret2_));
+}
+
+static uim_lisp
+c_file_write(uim_lisp d_, uim_lisp buf_)
+{
+  int nbytes = uim_scm_length(buf_);
+  uim_lisp ret_;
+  char *buf;
+  int i;
+  char *p;
+
+  buf = p = uim_malloc(nbytes);
+  for (i = 0; i < nbytes; i++) {
+    *p = (char)C_INT(CAR(buf_));
+    p++;
+  }
+  ret_ = MAKE_INT((int)write(C_INT(d_), buf, nbytes));
+  free(buf);
+  return ret_;
+}
+
 void
 uim_init_posix_subrs(void)
 {
@@ -342,4 +493,17 @@
   uim_scm_init_proc2("difftime", c_difftime);

   uim_scm_init_proc1("sleep", c_sleep);
+
+  uim_scm_init_proc3("file-open", c_file_open);
+  uim_scm_init_proc1("file-close", c_file_close);
+  uim_scm_init_proc2("file-read", c_file_read);
+  uim_scm_init_proc2("file-write", c_file_write);
+
+  uim_scm_gc_protect(&uim_lisp_open_flags);
+  uim_scm_gc_protect(&uim_lisp_open_mode);
+  uim_lisp_open_flags = make_arg_list(open_flags);
+  uim_lisp_open_mode = make_arg_list(open_mode);
+
+  uim_scm_init_proc0("file-open-flags?", c_file_open_flags);
+  uim_scm_init_proc0("file-open-mode?", c_file_open_mode);
 }

Reply via email to