fullpath Full path (including directory components) of the file the user wants to operate on. If the filename is a relative path, the environment variable specified by the path instance variable will be searched for filename. If filename is an absolute path, fullpath is just a copy of it. If the path instance variable is not set, filename is taken relative to the current working directory. If the filename begins with "~", "~/", or "~user", tilde expansion is performed like that of many shells.
format Printf-style format string for use by put:.
path Names the path to use as a path when searching for files. If the string value of path contains "/" or ":" characters, it is assumed to be a regular Unix- style path specifier, otherwise it is assumed to be the name of an environment variable. The default value is "LYMB_PATH".
mode Access mode for the file. Must be one of "r", "w", "a", "r+", "w+", or "a+". The default is "r".
bwrite: args Binary write the given list of arguments to the output file using the current format.
filename[=?] Set or get the filename instance variable. If it is a relative path, it will be interpreted relative to the environment variable specified by the path instance variable.
types= args Set the format for succeeding bread? or bwrite:
messages. The possible format values and their meanings are as follows:
1 unsigned char (1 byte) 2 unsigned short (2 bytes) 4 unsigned integer (4 bytes) 8 unsigned long (8 bytes) -1 signed char (1 byte) -2 signed short (2 bytes) -4 signed integer (4 bytes) -8 signed long (8 bytes) 32 IEEE single precision float (32 bits) 64 IEEE double precision float (64 bits)
Note that there is currently no way to specify strings. This can be viewed as a bug or a feature. The reason no string format is available is that there is no commonly agreed upon way to represent strings, so multiple ways should probably be supported. Also, the author only needed to read and write numeric values when this code was written...
fullpath? Get the fullpath instance variable. Fullpath is not user-settable. It is set as a side-effect of the find! message.
mode[=?] Set or get file access mode.
path[=?] Set or get file lookup path. This is the name of an environment variable to use when finding files. The default is "LYMB_PATH".
find! Locate filename using the path instance variable (if filename is a relative path). The result is saved as the fullpath instance variable. Note that path traversal is used for output files as well as input files. (This may change.)
open! Open filename using mode. Filename needn't exist in the path specified by the path instance variable if the access mode is "w", "a", "w+", or "a+". If filename is set to any of the special strings "1tdin", "1tdout", or "1tderr", then the appripriate stdio file pointer will be associated with the file object. The mode will be set to "r" for stdin and "w" for stdout and stderr. User setting of the mode instance variable is ignored. If an error occurs, a message is output on the controlling terminal (usually the terminal from which LYMB was started.)
close! Close filename. If stdin, stdout, or stderr are open, they will be closed, just like any other file, so be careful.
flush! Flush the file pointer associated with filename.
rewind! Rewind the file pointer associated with filename.
clearerr! Reset the error number for the file.
free! Close filename if open, and free local object storage.
get? Read a line from filename and return it. If the file is not open already, it will be opened.
put: arg Write arg to filename. Arg may be a list of arguments (i.e., ("Hi", 1, 2). Each argument will be printed using successive format strings from the format instance variable. If more arguments are given than format specifiers, the format string is reused. If fewer arguments than format specifiers exist, the extra format strings are printed. For instance, with a format string of `<1>' and arguments to put: of (`Hey', `There', `Hi', `There', `Ho', `There'), the output would be `<Hey><There><Hi><There><Ho><There>'. With a format string of `<1><><}C}B>' and arguments to put: of `(`Hi', `There')', the output would be `<Hi><There><1>'.
If the file is not open already, it will be opened. Note, however, that the mode must be set to "r+", "w", "a", "w+", or "a+".
file_ptr? Return the file pointer for filename. If the file is not open already, it is opened. If the open fails, a file pointer to standard output is returned. This makes it easier to continue after open errors when invoked from scripts. Script programmers should be prepared to check the filep object's errno value if stdout is not an acceptable return.
file_desc? Return the file descriptor associated with filename. If the file is not open already, it is opened. If the open fails, a file pointer to standard output is returned. This makes it easier to continue after open errors when invoked from
scripts. Script programmers should be prepared to check the filep object's errno value if stdout is not an acceptable return. This is normally only used from C code.
errno? Return the error number associated with the last operation on filename. If end-of-file has been reached, EOF (-1) is returned.
stat! Calls the system comman stat on the current file. If it is succesful then it keeps a copy of the buffer returned (until free!).
is_directory? Does a stat! on the current file and returns -1 if the stat! failed, 1 if the file is a directory and 0 if it isn't.
file_type? Does a stat! on the current file and returns 0 if the file doesn't exist, 1 if it is a regular file, 2 if it is a directory, three if it is a fifo, 4 if it is a character special device, and 5 if it is a block special device. If the file type is not known, -1 is returned. Note that the presence of a symbolic link isn't detected.
entries? Returns all entries in the current file, if it is a directory.
plain_files? Returns all plain files in the current file, if it is a directory.
directories? Returns all directory files in the current file, if it is a directory.
dirname? Returns all but the last component of the full path.
basename? Returns just the last component of the full path.
loop new: l resolution=1
duration=101 start_actions=` filep new: f filename=`/tmp/red.ramp' format=`0.00 0.00 0.00\n' mode=`w' open! ; scalar new: red = 0; scalar new: incr = 1; scalar new: output; ' tick_actions=` output = red integerize! / 100; -- round-off hack f put: output; red + incr; ' end_actions=` f flush! close! free!; red free!; incr free!; ' ;
l start!; ! The ramp file is /tmp/red.ramp parser exit!;
The following LYMB script writes the same rgb values as above, but in raw binary form.
loop new: l resolution=1 duration=101 start_actions=` filep new: f filename=`/tmp/red.ramp.binary' types=(32,32,32) mode=`w' open! ; scalar new: red = 0; scalar new: incr = 1; scalar new: output; ' tick_actions=` output = red integerize! / 100; -- round-off hack f bwrite:(output,0,0); red + incr; ' end_actions=` f flush! close! free!;
red free!; incr free!; ' ;
l start!; ! The ramp file is /tmp/red.ramp.binary parser exit!;
The following LYMB script demonstrates how format= and put: are used in concert.
filep new: f filename=`/tmp/trash.file' mode=`w'
open!
-- 11 should not be used from scripts, unless you want to see what a -- float looks like when interpreted as an int. use 0 instead format=`1 110 put:(`Hi', 1) -- that's more like it! format=`1 00 put:(`Bye', 2) format=`10 put:(`Whoa!') -- not enough args. just print the format strings format=`1 1 1 10 put:(`1', `2')
close!
format=`1 10 mode=`a' -- implicit open -- recycle the format string to print 3, 4, 5, and 6 put:(`1', `2', `3', `4', `5', `6') format=`1 1 1 10 put:(`1', `2') format=`10 put:(`Whoa!') format=`1 00 put:(`Bye', 2) format=`1 110 put:(`Hi', 1)
-- implicit close free! ; ! output is in /tmp/trash.file parser exit!;
The following LYMB script uses a filep object to divide the contents of a directory into directory and non- directory files. From those lists a file browser is then constructed.
<motifinit
actions compile_on!;
string new: current_dir = `~';
filep new: f filename= current_dir;
motif_selection_box new: sb parent=`motif' @ `cancelLabelString' : `Quit' cancel_action= `quit' @ `okLabelString' : `Home' ok_action= `go_home' help_action=`you_must_be_kidding' create! ;
-- get rid of all the stuff in the selection box that we do not need motif_list new: _list parent=sb id=[sb list_id?] ;
motif_scrolled_window new! parent=sb id=[_list parent_id?] unmanage! free! ;
_list free!;
motif_label_gadget new! parent=sb id=[sb list_label_id?] unmanage! free! ;
motif_label_gadget new! parent=sb id=[sb selection_label_id?] unmanage! free! ;
motif_text_field new! parent=sb
id=[sb text_id?] unmanage! free! ;
-- now populate it with the really useful stuff motif_form new: form parent=sb create! ;
motif_frame new: dir_frame parent=form @ `topAttachment' : XmATTACH_FORM @ `leftAttachment' : XmATTACH_FORM @ `rightAttachment' : XmATTACH_FORM create! ;
motif_label new: dir_label parent=dir_frame create! ;
motif_row_column new: lists parent=form @ `orientation' : XmHORIZONTAL @ `topAttachment' : XmATTACH_WIDGET @ `topWidget' : [dir_frame id?] @ `leftAttachment' : XmATTACH_FORM @ `rightAttachment' : XmATTACH_FORM create! ;
motif_scrolled_list new: dir_list parent=`lists' @ `scrollBarDisplayPolicy' : XmSTATIC @ `visibleItemCount' : 15 @ `unitType' : Xm100TH_FONT_UNITS @ `width' : 240 browse_selection_action=`scan' create! ;
motif_scrolled_list new: file_list parent=`lists' @ `scrollBarDisplayPolicy' : XmSTATIC @ `visibleItemCount' : 15 @ `unitType' : Xm100TH_FONT_UNITS @ `width' : 240 create! ;
motif_scrolled_window new: dir_list_sw
parent=`lists' id=[dir_list parent_id?] ;
motif_scrolled_window new: file_list_sw parent=`lists' id=[file_list parent_id?] ;
string new: current_file = current_dir; sorted_collection new: entries; logic new: if;
switch new: sw @ `.' actions=` '
@ `..' actions=` current_dir = [f dirname?]; motif application= current_dir; if equal:(current_dir, `') true:` current_dir = `/'; ' ; ' @ `default' actions=` if equal:(current_dir, `/') false:` current_dir = current_dir + `/' + [dir_list selected_items?] chop! ; ' true:` current_dir = current_dir + [dir_list selected_items?] chop! ; ' ; ' ;
actions new: scan tick_actions=` string new: `the_dir' = [dir_list selected_items?] chop!; sw switch: the_dir; current_file = `';
update_list tick!; ' ;
actions new: update_list tick_actions=` dir_label @ `labelString' : current_dir; f filename= current_dir; entries members=[f directories?] string_sort!; s_vector new: `entries_s_vec' = [entries members?] + `/';
lists off!; dir_list delete_all_items! add_item: entries_s_vec ; entries members=[f plain_files?] string_sort!; file_list delete_all_items! add_item:[entries members?] ; lists on!; ' ;
actions new: `quit' tick_actions=` parser exit!; ' ;
actions new: `go_home' tick_actions=` current_dir = `~'; update_list tick!; ' ;
actions new: `you_must_be_kidding' tick_actions=` parser parse: `! Ha! You think I would actually implement help?'; ' ;
motif on!;
update_list tick!;
motif start!;
The following C code uses the filep object to open a file in LYMB_PATH for reading. It then gets the file pointer for the file to use to read from the file directly.
OBJECT *f; FILE *fp;
f = msg_send_object("filep", "new!", 0, 0);
ARGS_BEGIN; ARGS_ADD_STRING("myfile.tst"); msg_send(f, "filename=", ARGS_COUNT, ARGS_LIST); ARGS_END;
/* read mode is implicit */ msg_send(f, "open!", 0, 0);
ARGS_BEGIN; msg_send(f, "file_ptr?", 0, 0); fp = (FILE *)ARGS_GET_POINTER(ARGS_LIST); ARGS_END;
if (fp == 0) { ARGS_BEGIN; msg_send(f, "errno?", 0, 0); errno = ARGS_GET_INTEGER(ARGS_LIST); ARGS_END; if (errno != 0) { /* analyze further */ } } else { /* use fp here to read (fgets, fgetc, fscanf, ...) the file */ }
msg_send(f, "free!", 0, 0);