X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffile-handle.q;h=98b2354c60e891ca1362f73dbc0cbd32c486bb96;hb=bbe7ad1a7454599693c188fe1eaf8f5d6e154206;hp=c70945ee381f701cf9a2694cd9e0198289ea714a;hpb=55dee937e22a49d01794ef772076d9f9d84199e9;p=pspp-builds.git diff --git a/src/file-handle.q b/src/file-handle.q index c70945ee..98b2354c 100644 --- a/src/file-handle.q +++ b/src/file-handle.q @@ -14,65 +14,60 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ #include #include "file-handle.h" -#include +#include "error.h" #include #include #include "alloc.h" #include "filename.h" #include "command.h" -#include "hash.h" #include "lexer.h" -#include "getline.h" +#include "getl.h" #include "error.h" #include "magic.h" #include "var.h" -/* (headers) */ +#include "linked-list.h" +#include "file-handle-def.h" -#include "debug-print.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) -static struct hsh_table *files; -struct file_handle *inline_file; +/* (headers) */ -static void init_file_handle (struct file_handle * handle); /* (specification) "FILE HANDLE" (fh_): name=string; - recform=recform:fixed/!variable/spanned; lrecl=integer; - mode=mode:!character/image/binary/multipunch/_360. + tabwidth=integer "x>=0" "%s must be nonnegative"; + mode=mode:!character/image. */ /* (declarations) */ /* (functions) */ + int cmd_file_handle (void) { - char handle_name[9]; - char *handle_name_p = handle_name; + char handle_name[LONG_NAME_LEN + 1]; struct cmd_file_handle cmd; - struct file_handle *fp; + struct file_handle *handle; - lex_get (); if (!lex_force_id ()) return CMD_FAILURE; - strcpy (handle_name, tokid); + str_copy_trunc (handle_name, sizeof handle_name, tokid); - fp = NULL; - if (files) - fp = hsh_find (files, &handle_name_p); - if (fp) + handle = get_handle_with_name (handle_name); + if (handle != NULL) { - msg (SE, _("File handle %s had already been defined to refer to " - "file %s. It is not possible to redefine a file " - "handle within a session."), - tokid, fp->fn); + msg (SE, _("File handle %s already refers to file %s. " + "File handles cannot be redefined within a session."), + handle_name, handle_get_filename(handle)); return CMD_FAILURE; } @@ -96,67 +91,46 @@ cmd_file_handle (void) goto lossage; } - fp = xmalloc (sizeof *fp); - init_file_handle (fp); - switch (cmd.recform) + enum file_handle_mode mode = MODE_TEXT; + size_t length = 1024; + size_t tab_width = 4; + + + switch (cmd.mode) { - case FH_FIXED: - if (cmd.n_lrecl == NOT_LONG) + case FH_CHARACTER: + mode = MODE_TEXT; + if (cmd.sbc_tabwidth) + tab_width = cmd.n_tabwidth[0]; + else + tab_width = 4; + break; + case FH_IMAGE: + mode = MODE_BINARY; + if (cmd.n_lrecl[0] == NOT_LONG) { - msg (SE, _("Fixed length records were specified on /RECFORM, but " - "record length was not specified on /LRECL. 80-character " - "records will be assumed.")); - cmd.n_lrecl = 80; + msg (SE, _("Fixed-length records were specified on /RECFORM, but " + "record length was not specified on /LRECL. " + "Assuming 1024-character records.")); + length = 1024; } - else if (cmd.n_lrecl < 1) + else if (cmd.n_lrecl[0] < 1) { msg (SE, _("Record length (%ld) must be at least one byte. " - "80-character records will be assumed."), cmd.n_lrecl); - cmd.n_lrecl = 80; + "1-character records will be assumed."), cmd.n_lrecl[0]); + length = 1; } - fp->recform = FH_RF_FIXED; - fp->lrecl = cmd.n_lrecl; - break; - case FH_VARIABLE: - fp->recform = FH_RF_VARIABLE; - break; - case FH_SPANNED: - msg (SE, - _("%s is not implemented, as the author doesn't know what it is supposed to do. Send a note to %s.") , - "/RECFORM SPANNED",PACKAGE_BUGREPORT); + else + length = cmd.n_lrecl[0]; break; default: assert (0); } - switch (cmd.mode) - { - case FH_CHARACTER: - fp->mode = FH_MD_CHARACTER; - break; - case FH_IMAGE: - msg (SE, - _("%s is not implemented, as the author doesn't know what it is supposed to do. Send a note to %s.") , - "/MODE IMAGE",PACKAGE_BUGREPORT); - break; - case FH_BINARY: - fp->mode = FH_MD_BINARY; - break; - case FH_MULTIPUNCH: - msg (SE, _("%s is not implemented. If you care, complain."),"/MODE MULTIPUNCH"); - break; - case FH__360: - msg (SE, _("%s is not implemented. If you care, complain."),"/MODE 360"); - break; - default: - assert (0); - } + handle = create_file_handle (handle_name, cmd.s_name, + mode, length, tab_width); - fp->name = xstrdup (handle_name); - fp->norm_fn = fn_normalize (cmd.s_name); - fp->where.filename = fp->fn = cmd.s_name; - hsh_force_insert (files, fp); return CMD_SUCCESS; @@ -164,207 +138,67 @@ cmd_file_handle (void) free_file_handle (&cmd); return CMD_FAILURE; } - -/* File handle functions. */ -/* Sets up some fields in H; caller should fill in - H->{NAME,NORM_FN,FN}. */ -static void -init_file_handle (struct file_handle *h) -{ - h->recform = FH_RF_VARIABLE; - h->mode = FH_MD_CHARACTER; - h->ext = NULL; - h->class = NULL; -} -/* Returns the handle corresponding to FILENAME. Creates the handle - if no handle exists for that file. All filenames are normalized - first, so different filenames referring to the same file will - return the same file handle. */ -struct file_handle * -fh_get_handle_by_filename (const char *filename) -{ - struct file_handle f, *fp; - char *fn; - char *name; - int len; - - /* Get filename. */ - fn = fn_normalize (filename); - len = strlen (fn); - - /* Create handle name with invalid identifier character to prevent - conflicts with handles created with FILE HANDLE. */ - name = xmalloc (len + 2); - name[0] = '*'; - strcpy (&name[1], fn); - - f.name = name; - fp = hsh_find (files, &f); - if (!fp) - { - fp = xmalloc (sizeof *fp); - init_file_handle (fp); - fp->name = name; - fp->norm_fn = fn; - fp->where.filename = fp->fn = xstrdup (filename); - hsh_force_insert (files, fp); - } - else - { - free (fn); - free (name); - } - return fp; -} -/* Returns the handle with identifier NAME, if it exists; otherwise - reports error to user and returns NULL. */ -struct file_handle * -fh_get_handle_by_name (const char name[9]) -{ - struct file_handle f, *fp; - f.name = (char *) name; - fp = hsh_find (files, &f); - - if (!fp) - msg (SE, _("File handle `%s' has not been previously declared on " - "FILE HANDLE."), name); - return fp; -} - -/* Returns the identifier of file HANDLE. If HANDLE was created by - referring to a filename (i.e., DATA LIST FILE='yyy' instead of FILE - HANDLE XXX='yyy'), returns the filename, enclosed in double quotes. - Return value is in a static buffer. - - Useful for printing error messages about use of file handles. */ -const char * -fh_handle_name (struct file_handle *h) -{ - static char *buf = NULL; - - if (buf) - { - free (buf); - buf = NULL; - } - if (!h) - return NULL; - - if (h->name[0] == '*') - { - int len = strlen (h->fn); +static struct linked_list *handle_list; - buf = xmalloc (len + 3); - strcpy (&buf[1], h->fn); - buf[0] = buf[len + 1] = '"'; - buf[len + 2] = 0; - return buf; - } - return h->name; -} - -/* Closes the stdio FILE associated with handle H. Frees internal - buffers associated with that file. Does *not* destroy the file - handle H. (File handles are permanent during a session.) */ -void -fh_close_handle (struct file_handle *h) -{ - if (h == NULL) - return; - - debug_printf (("Closing %s%s.\n", fh_handle_name (h), - h->class == NULL ? " (already closed)" : "")); - - if (h->class) - h->class->close (h); - h->class = NULL; - h->ext = NULL; -} - -/* Hashes the name of file handle H. */ -static unsigned -hash_file_handle (const void *handle_, void *param unused) -{ - const struct file_handle *handle = handle_; - - return hsh_hash_string (handle->name); -} - -/* Compares names of file handles A and B. */ -static int -cmp_file_handle (const void *a_, const void *b_, void *foo unused) -{ - const struct file_handle *a = a_; - const struct file_handle *b = b_; - - return strcmp (a->name, b->name); -} - -/* Initialize the hash of file handles; inserts the "inline file" - inline_file. */ -void -fh_init_files (void) -{ - /* Create hash. */ - files = hsh_create (4, cmp_file_handle, hash_file_handle, NULL, NULL); - - /* Insert inline file. */ - inline_file = xmalloc (sizeof *inline_file); - init_file_handle (inline_file); - inline_file->name = "INLINE"; - inline_file->where.filename - = inline_file->fn = inline_file->norm_fn = (char *) _(""); - inline_file->where.line_number = 0; - hsh_force_insert (files, inline_file); -} /* Parses a file handle name, which may be a filename as a string or a file handle name as an identifier. Returns the file handle or NULL on failure. */ struct file_handle * -fh_parse_file_handle (void) +fh_parse (void) { struct file_handle *handle; - if (token == T_ID) - handle = fh_get_handle_by_name (tokid); - else if (token == T_STRING) - handle = fh_get_handle_by_filename (ds_value (&tokstr)); - else + if (token != T_ID && token != T_STRING) { - lex_error (_("expecting a file name or handle")); + lex_error (_("expecting a file name or handle name")); return NULL; } - if (!handle) - return NULL; + /* Check for named handles first, then go by filename. */ + handle = NULL; + if (token == T_ID) + handle = get_handle_with_name (tokid); + if (handle == NULL) + handle = get_handle_for_filename (ds_c_str (&tokstr)); + if (handle == NULL) + { + char *filename = ds_c_str (&tokstr); + char *handle_name = xmalloc (strlen (filename) + 3); + sprintf (handle_name, "\"%s\"", filename); + handle = create_file_handle_with_defaults (handle_name, filename); + ll_push_front(handle_list, handle); + free (handle_name); + } + lex_get (); + return handle; } -/* Returns the (normalized) filename associated with file handle H. */ -char * -fh_handle_filename (struct file_handle * h) + + +void +fh_init(void) { - return h->norm_fn; + handle_list = ll_create(destroy_file_handle,0); } -/* Returns the width of a logical record on file handle H. */ -size_t -fh_record_width (struct file_handle *h) +void +fh_done(void) { - if (h == inline_file) - return 80; - else if (h->recform == FH_RF_FIXED) - return h->lrecl; - else - return 1024; + if ( handle_list ) + { + ll_destroy(handle_list); + handle_list = 0; + } } + /* Local variables: mode: c