diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | arith.c | 6 | ||||
-rw-r--r-- | eval.c | 25 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | stream.c | 15 | ||||
-rw-r--r-- | stream.h | 5 | ||||
-rw-r--r-- | txr.1 | 96 |
7 files changed, 170 insertions, 3 deletions
@@ -1,3 +1,28 @@ +2012-09-18 Kaz Kylheku <kaz@kylheku.com> + + * arith.c (logtest): New function. + + * eval.c (eval_init): Registered logtest. + Registered s-ifmt, s-iflnk, s-ifreg, s-ifblk, s-ifdir, + s-ifchr, s-ififo, s-isuid, s-isgid, s-isvtx, s-irwxu, + s-irusr, s-iwusr, s-ixusr, s-irwxg, s-irgrp, s-iwgrp, + s-ixgrp, s-irwxo, s-iroth, s-iwoth, s-ixoth variables. + + * lib.h (logtest): Declared. + + * stream.c (s_ifmt, s_ifsock, s_iflnk, s_ifreg, s_ifblk, + s_ifdir, s_ifchr, s_ififo, s_isuid, s_isgid, s_isvtx, s_irwxu, s_irusr, + s_iwusr, s_ixusr, s_irwxg, s_irgrp, s_iwgrp, s_ixgrp, s_irwxo, s_iroth, + s_iwoth, s_ixoth): New global variables. + + * stream.h (s_ifmt, s_ifsock, s_iflnk, s_ifreg, s_ifblk, + s_ifdir, s_ifchr, s_ififo, s_isuid, s_isgid, s_isvtx, s_irwxu, s_irusr, + s_iwusr, s_ixusr, s_irwxg, s_irgrp, s_iwgrp, s_ixgrp, s_irwxo, s_iroth, + s_iwoth, s_ixoth): Declared. + + * txr.1: Documented logtest and s-* variables for stat, + as well as open-file and open-directory. + 2012-09-17 Kaz Kylheku <kaz@kylheku.com> * stream.c (vformat): Slight change in ~s directive. For a floating @@ -1618,6 +1618,12 @@ bad: uw_throwf(error_s, lit("logxor: operation failed on ~s ~s"), a, b, nao); } +val logtest(val a, val b) +{ + /* TODO: optimize */ + return logand(a, b) == zero; +} + static val comp_trunc(val a, val bits) { cnum an, bn; @@ -2234,6 +2234,7 @@ void eval_init(void) reg_fun(intern(lit("logand"), user_package), func_n2(logand)); reg_fun(intern(lit("logior"), user_package), func_n2(logior)); reg_fun(intern(lit("logxor"), user_package), func_n2(logxor)); + reg_fun(intern(lit("logtest"), user_package), func_n2(logtest)); reg_fun(intern(lit("lognot"), user_package), func_n2o(lognot, 1)); reg_fun(intern(lit("logtrunc"), user_package), func_n2(logtrunc)); reg_fun(intern(lit("ash"), user_package), func_n2(ash)); @@ -2302,6 +2303,30 @@ void eval_init(void) reg_fun(intern(lit("put-byte"), user_package), func_n2o(put_byte, 1)); reg_fun(intern(lit("flush-stream"), user_package), func_n1(flush_stream)); reg_fun(intern(lit("stat"), user_package), func_n1(statf)); + + reg_var(intern(lit("s-ifmt"), user_package), &s_ifmt); + reg_var(intern(lit("s-iflnk"), user_package), &s_iflnk); + reg_var(intern(lit("s-ifreg"), user_package), &s_ifreg); + reg_var(intern(lit("s-ifblk"), user_package), &s_ifblk); + reg_var(intern(lit("s-ifdir"), user_package), &s_ifdir); + reg_var(intern(lit("s-ifchr"), user_package), &s_ifchr); + reg_var(intern(lit("s-ififo"), user_package), &s_ififo); + reg_var(intern(lit("s-isuid"), user_package), &s_isuid); + reg_var(intern(lit("s-isgid"), user_package), &s_isgid); + reg_var(intern(lit("s-isvtx"), user_package), &s_isvtx); + reg_var(intern(lit("s-irwxu"), user_package), &s_irwxu); + reg_var(intern(lit("s-irusr"), user_package), &s_irusr); + reg_var(intern(lit("s-iwusr"), user_package), &s_iwusr); + reg_var(intern(lit("s-ixusr"), user_package), &s_ixusr); + reg_var(intern(lit("s-irwxg"), user_package), &s_irwxg); + reg_var(intern(lit("s-irgrp"), user_package), &s_irgrp); + reg_var(intern(lit("s-iwgrp"), user_package), &s_iwgrp); + reg_var(intern(lit("s-ixgrp"), user_package), &s_ixgrp); + reg_var(intern(lit("s-irwxo"), user_package), &s_irwxo); + reg_var(intern(lit("s-iroth"), user_package), &s_iroth); + reg_var(intern(lit("s-iwoth"), user_package), &s_iwoth); + reg_var(intern(lit("s-ixoth"), user_package), &s_ixoth); + reg_fun(intern(lit("open-directory"), user_package), func_n1(open_directory)); reg_fun(intern(lit("open-file"), user_package), func_n2(open_file)); reg_fun(intern(lit("open-command"), user_package), func_n2(open_command)); @@ -474,6 +474,7 @@ val expo(val); val logand(val, val); val logior(val, val); val logxor(val, val); +val logtest(val, val); val lognot(val, val); val logtrunc(val a, val bits); val ash(val a, val bits); @@ -56,6 +56,11 @@ val dev_k, ino_k, mode_k, nlink_k, uid_k; val gid_k, rdev_k, size_k, blksize_k, blocks_k; val atime_k, mtime_k, ctime_k; +val s_ifmt, s_ifsock, s_iflnk, s_ifreg, s_ifblk, s_ifdir; +val s_ifchr, s_ififo, s_isuid, s_isgid, s_isvtx, s_irwxu; +val s_irusr, s_iwusr, s_ixusr, s_irwxg, s_irgrp, s_iwgrp; +val s_ixgrp, s_irwxo, s_iroth, s_iwoth, s_ixoth; + struct strm_ops { struct cobj_ops cobj_ops; val (*put_string)(val, val); @@ -1497,7 +1502,6 @@ val statf(val path) path, num(errno), string_utf8(strerror(errno)), nao); return list(dev_k, num(st.st_dev), - dev_k, num(st.st_dev), ino_k, num(st.st_ino), mode_k, num(st.st_mode), nlink_k, num(st.st_nlink), @@ -1729,4 +1733,13 @@ void stream_init(void) atime_k = intern(lit("atime"), keyword_package); mtime_k = intern(lit("mtime"), keyword_package); ctime_k = intern(lit("ctime"), keyword_package); + + s_ifmt = num(S_IFMT); s_iflnk = num(S_IFLNK); + s_ifreg = num(S_IFREG); s_ifblk = num(S_IFBLK); s_ifdir = num(S_IFDIR); + s_ifchr = num(S_IFCHR); s_ififo = num(S_IFIFO); s_isuid = num(S_ISUID); + s_isgid = num(S_ISGID); s_isvtx = num(S_ISVTX); s_irwxu = num(S_IRWXU); + s_irusr = num(S_IRUSR); s_iwusr = num(S_IWUSR); s_ixusr = num(S_IXUSR); + s_irwxg = num(S_IRWXG); s_irgrp = num(S_IRGRP); s_iwgrp = num(S_IWGRP); + s_ixgrp = num(S_IXGRP); s_irwxo = num(S_IRWXO); s_iroth = num(S_IROTH); + s_iwoth = num(S_IWOTH); s_ixoth = num(S_IXOTH); } @@ -27,6 +27,11 @@ extern val std_input, std_output, std_debug, std_error; extern val output_produced; +extern val s_ifmt, s_iflnk, s_ifreg, s_ifblk, s_ifdir; +extern val s_ifchr, s_ififo, s_isuid, s_isgid, s_isvtx, s_irwxu; +extern val s_irusr, s_iwusr, s_ixusr, s_irwxg, s_irgrp, s_iwgrp; +extern val s_ixgrp, s_irwxo, s_iroth, s_iwoth, s_ixoth; + val make_stdio_stream(FILE *, val descr, val input, val output); val make_pipe_stream(FILE *, val descr, val input, val output); val make_string_input_stream(val); @@ -8726,6 +8726,21 @@ For example (logand -2 7) produces 6. This is because -2 is ..111110 in infinite-bit two's-complement. Or-ing this value with 7 (111) produces 110. +.SS Functions logtest + +.TP +Syntax: + + (logtest <int1> <int2>) + +.TP +Description: + +The logtest function returns true if <int1> and <int1> have bits in +common. The following equivalence holds: + + (logtest a b) <--> (not (zerop (logand a b))) + .SS Functions lognot and logtrunc .TP @@ -9285,8 +9300,9 @@ symbols in the program. (op foo @rest @1) -> (lambda (arg1 . rest) [foo rest arg1]) -.TP +.PP +.TP Examples: ;; Take a list of pairs and produce a list in which those pairs @@ -9555,6 +9571,8 @@ number. If the precision is omitted, then the number of digits after the decimal point is three. If the precision is zero, then a decimal portion is truncated off entirely, including the decimal point. +.PP + .SS Functions print, pprint, tostring, tostringp .TP @@ -9751,6 +9769,8 @@ values in the range 0 to 255. Note that if a stream supports both byte input and character input, then mixing the two operations will interfere with the UTF-8 decoding. +These functions return nil when the end of data is reached. Errors are +represented as exceptions. .SS Functions put-string, put-line, put-char and put-byte .TP @@ -9799,9 +9819,81 @@ meaningful, it does nothing. .SS Function stat +.TP +Syntax: + + (stat <path>) + +.TP +Description: + +The stat function inquires the filesystem about the existence of an object +denoted by the string <path>. If the object is not found or cannot be +accessed, an exception is thrown. + +Otherwise information is retrieved about the object. The information takes the +form of a property list in which keyword symbols denote numerous properties. +An example such property list is (:dev 2049 :ino 669944 :mode 16832 :nlink 23 +:uid 500 :gid 500 :rdev 0 :size 12288 :blksize 4096 :blocks 24 :atime +1347933533 :mtime 1347933534 :ctime 1347933534) + +These properties correspond to the similarly-named entires of the struct stat +structure in POSIX. For instance, the :dev property has the same value +as the st_dev field. + +.SS The variables s-ifmt s-iflnk s-ifreg s-ifblk ... s-ixoth + +The following variables exist, having integer values. These are bitmasks +which can be applied against the value given by the :mode property +in the property list returned by the function stat: s-ifmt, s-iflnk, s-ifreg, +s-ifblk, s-ifdir, s-ifchr, s-ififo, s-isuid, s-isgid, s-isvtx, s-irwxu, +s-irusr, s-iwusr, s-ixusr, s-irwxg, s-irgrp, s-iwgrp, s-ixgrp, s-irwxo, +s-iroth, s-iwoth and s-ixoth. + +These variables correspond to the C constants S_IFMT, S_IFLNK, S_IFREG +and so forth. + +The logtest function can be used to test these against values of mode. +For example (logtest mode s-irgrp) tests for the group read permission. + .SS Function open-directory -.SS Functions open-file +.TP +Syntax: + + (open-directory <path>) + +.TP +Description: + +The open-directory function tries to create a stream which reads the +directory given by the string argument <path>. If a filesystem object exists +under the path, is accessible, and is a directory, then the function +returns a stream. Otherwise, a file error exception is thrown. + +The resulting stream supports the get-line operation. Each call to the +get-line operation retrieves a string representing the next directory +entry. The value nil is returned when there are no more directory entries. +The . and .. entries in Unix filesystems are not skipped. + +.SS Function open-file + +.TP +Syntax: + + (open-file <path> <mode-string>) + +.TP +Description: + +The open-file function creates a stream connected to the file +which is located at the given <path>, which is a string. +The <mode-string> argument is a string which uses the same +conventions as the mode argument of the C language fopen function. +The mode string determines whether the stream is an input stream +or output stream. Note that the "b" mode is not supported. +Whether a stream is text or binary depends on which operations +are invoked on it. .SH COPROCESSES |