X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Ffile-handle-def.c;h=9c853e5e983d7968bf427e0a01765680c1cec0e0;hb=e9bebe68e0285273d0e37af5d548a9b2c26951e1;hp=95a92f57f4f6b2d41fe8aa4c45023025917b4ce2;hpb=c831ad10d7e9d494e5e22ab30306057e81bc52cd;p=pspp diff --git a/src/data/file-handle-def.c b/src/data/file-handle-def.c index 95a92f57f4..9c853e5e98 100644 --- a/src/data/file-handle-def.c +++ b/src/data/file-handle-def.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,15 +23,16 @@ #include #include +#include "data/dataset.h" +#include "data/file-name.h" +#include "data/variable.h" +#include "libpspp/cast.h" #include "libpspp/compiler.h" +#include "libpspp/hash-functions.h" #include "libpspp/hmap.h" #include "libpspp/i18n.h" #include "libpspp/message.h" #include "libpspp/str.h" -#include "libpspp/hash-functions.h" -#include "data/file-name.h" -#include "data/variable.h" -#include "data/scratch-handle.h" #include "gl/xalloc.h" @@ -50,14 +51,15 @@ struct file_handle /* FH_REF_FILE only. */ char *file_name; /* File name as provided by user. */ enum fh_mode mode; /* File mode. */ - const char *encoding; /* File encoding. */ + enum fh_line_ends line_ends; /* Line ends for text files. */ /* FH_REF_FILE and FH_REF_INLINE only. */ size_t record_width; /* Length of fixed-format records. */ size_t tab_width; /* Tab width, 0=do not expand tabs. */ + char *encoding; /* Charset for contents. */ - /* FH_REF_SCRATCH only. */ - struct scratch_handle *sh; /* Scratch file data. */ + /* FH_REF_DATASET only. */ + struct dataset *ds; /* Dataset. */ }; /* All "struct file_handle"s with nonnull 'id' member. */ @@ -71,7 +73,8 @@ static struct file_handle *default_handle; static struct file_handle *inline_file; static struct file_handle *create_handle (const char *id, - char *name, enum fh_referent); + char *name, enum fh_referent, + const char *encoding); static void free_handle (struct file_handle *); static void unname_handle (struct file_handle *); @@ -82,7 +85,8 @@ static struct hmap locks = HMAP_INITIALIZER (locks); void fh_init (void) { - inline_file = create_handle ("INLINE", xstrdup ("INLINE"), FH_REF_INLINE); + inline_file = create_handle ("INLINE", xstrdup ("INLINE"), FH_REF_INLINE, + "Auto"); inline_file->record_width = 80; inline_file->tab_width = 8; } @@ -110,7 +114,7 @@ free_handle (struct file_handle *handle) free (handle->id); free (handle->name); free (handle->file_name); - scratch_handle_destroy (handle->sh); + free (handle->encoding); free (handle); } @@ -173,11 +177,10 @@ fh_from_id (const char *id) struct file_handle *handle; HMAP_FOR_EACH_WITH_HASH (handle, struct file_handle, name_node, - hash_case_string (id, 0), &named_handles) - if (!strcasecmp (id, handle->id)) + utf8_hash_case_string (id, 0), &named_handles) + if (!utf8_strcasecmp (id, handle->id)) { - handle->ref_cnt++; - return handle; + return fh_ref (handle); } return NULL; @@ -190,7 +193,8 @@ fh_from_id (const char *id) The new handle is not fully initialized. The caller is responsible for completing its initialization. */ static struct file_handle * -create_handle (const char *id, char *handle_name, enum fh_referent referent) +create_handle (const char *id, char *handle_name, enum fh_referent referent, + const char *encoding) { struct file_handle *handle = xzalloc (sizeof *handle); @@ -198,13 +202,12 @@ create_handle (const char *id, char *handle_name, enum fh_referent referent) handle->id = id != NULL ? xstrdup (id) : NULL; handle->name = handle_name; handle->referent = referent; + handle->encoding = xstrdup (encoding); if (id != NULL) { - assert (fh_from_id (id) == NULL); hmap_insert (&named_handles, &handle->name_node, - hash_case_string (handle->id, 0)); - handle->ref_cnt++; + utf8_hash_case_string (handle->id, 0)); } return handle; @@ -216,14 +219,13 @@ create_handle (const char *id, char *handle_name, enum fh_referent referent) struct file_handle * fh_inline_file (void) { - fh_ref (inline_file); return inline_file; } -/* Creates and returns a new file handle with the given ID, which - may be null. If it is non-null, it must be unique among - existing file identifiers. The new handle is associated with - file FILE_NAME and the given PROPERTIES. */ +/* Creates and returns a new file handle with the given ID, which may be null. + If it is non-null, it must be a UTF-8 encoded string that is unique among + existing file identifiers. The new handle is associated with file FILE_NAME + and the given PROPERTIES. */ struct file_handle * fh_create_file (const char *id, const char *file_name, const struct fh_properties *properties) @@ -232,24 +234,30 @@ fh_create_file (const char *id, const char *file_name, struct file_handle *handle; handle_name = id != NULL ? xstrdup (id) : xasprintf ("`%s'", file_name); - handle = create_handle (id, handle_name, FH_REF_FILE); + handle = create_handle (id, handle_name, FH_REF_FILE, properties->encoding); handle->file_name = xstrdup (file_name); handle->mode = properties->mode; + handle->line_ends = properties->line_ends; handle->record_width = properties->record_width; handle->tab_width = properties->tab_width; - handle->encoding = properties->encoding; return handle; } /* Creates a new file handle with the given ID, which must be unique among existing file identifiers. The new handle is - associated with a scratch file (initially empty). */ + associated with a dataset file (initially empty). */ struct file_handle * -fh_create_scratch (const char *id) +fh_create_dataset (struct dataset *ds) { + const char *name; struct file_handle *handle; - handle = create_handle (id, xstrdup (id), FH_REF_SCRATCH); - handle->sh = NULL; + + name = dataset_name (ds); + if (name[0] == '\0') + name = _("active dataset"); + + handle = create_handle (NULL, xstrdup (name), FH_REF_DATASET, C_ENCODING); + handle->ds = ds; return handle; } @@ -257,8 +265,14 @@ fh_create_scratch (const char *id) const struct fh_properties * fh_default_properties (void) { +#if defined _WIN32 || defined __WIN32__ +#define DEFAULT_LINE_ENDS FH_END_CRLF +#else +#define DEFAULT_LINE_ENDS FH_END_LF +#endif + static const struct fh_properties default_properties - = {FH_MODE_TEXT, 1024, 4, C_ENCODING}; + = {FH_MODE_TEXT, DEFAULT_LINE_ENDS, 1024, 4, (char *) "Auto"}; return &default_properties; } @@ -308,6 +322,15 @@ fh_get_mode (const struct file_handle *handle) return handle->mode; } +/* Returns the line ends of HANDLE, which must be a handle associated with a + file. */ +enum fh_line_ends +fh_get_line_ends (const struct file_handle *handle) +{ + assert (handle->referent == FH_REF_FILE); + return handle->line_ends; +} + /* Returns the width of a logical record on HANDLE. */ size_t fh_get_record_width (const struct file_handle *handle) @@ -328,35 +351,25 @@ fh_get_tab_width (const struct file_handle *handle) /* Returns the encoding of characters read from HANDLE. */ const char * -fh_get_legacy_encoding (const struct file_handle *handle) -{ - assert (handle->referent & (FH_REF_FILE | FH_REF_INLINE)); - return (handle->referent == FH_REF_FILE ? handle->encoding : C_ENCODING); -} - -/* Returns the scratch file handle associated with HANDLE. - Applicable to only FH_REF_SCRATCH files. */ -struct scratch_handle * -fh_get_scratch_handle (const struct file_handle *handle) +fh_get_encoding (const struct file_handle *handle) { - assert (handle->referent == FH_REF_SCRATCH); - return handle->sh; + return handle->encoding; } -/* Sets SH to be the scratch file handle associated with HANDLE. - Applicable to only FH_REF_SCRATCH files. */ -void -fh_set_scratch_handle (struct file_handle *handle, struct scratch_handle *sh) +/* Returns the dataset handle associated with HANDLE. + Applicable to only FH_REF_DATASET files. */ +struct dataset * +fh_get_dataset (const struct file_handle *handle) { - assert (handle->referent == FH_REF_SCRATCH); - handle->sh = sh; + assert (handle->referent == FH_REF_DATASET); + return handle->ds; } /* Returns the current default handle. */ struct file_handle * fh_get_default_handle (void) { - return default_handle ? fh_ref (default_handle) : fh_inline_file (); + return default_handle ? default_handle : fh_inline_file (); } /* Sets NEW_DEFAULT_HANDLE as the default handle. */ @@ -365,7 +378,7 @@ fh_set_default_handle (struct file_handle *new_default_handle) { assert (new_default_handle == NULL || (new_default_handle->referent & (FH_REF_INLINE | FH_REF_FILE))); - if (default_handle != NULL) + if (default_handle != NULL && default_handle != inline_file) fh_unref (default_handle); default_handle = new_default_handle; if (default_handle != NULL) @@ -382,7 +395,7 @@ struct fh_lock union { struct file_identity *file; /* FH_REF_FILE only. */ - unsigned int unique_id; /* FH_REF_SCRATCH only. */ + unsigned int unique_id; /* FH_REF_DATASET only. */ } u; enum fh_access access; /* Type of file access. */ @@ -590,11 +603,8 @@ make_key (struct fh_lock *lock, const struct file_handle *h, lock->access = access; if (lock->referent == FH_REF_FILE) lock->u.file = fn_get_identity (fh_get_file_name (h)); - else if (lock->referent == FH_REF_SCRATCH) - { - struct scratch_handle *sh = fh_get_scratch_handle (h); - lock->u.unique_id = sh != NULL ? sh->unique_id : 0; - } + else if (lock->referent == FH_REF_DATASET) + lock->u.unique_id = dataset_seqno (fh_get_dataset (h)); } /* Frees the key fields in LOCK. */ @@ -616,7 +626,7 @@ compare_fh_locks (const struct fh_lock *a, const struct fh_lock *b) return a->access < b->access ? -1 : 1; else if (a->referent == FH_REF_FILE) return fn_compare_file_identities (a->u.file, b->u.file); - else if (a->referent == FH_REF_SCRATCH) + else if (a->referent == FH_REF_DATASET) return (a->u.unique_id < b->u.unique_id ? -1 : a->u.unique_id > b->u.unique_id); else @@ -630,7 +640,7 @@ hash_fh_lock (const struct fh_lock *lock) unsigned int basis; if (lock->referent == FH_REF_FILE) basis = fn_hash_identity (lock->u.file); - else if (lock->referent == FH_REF_SCRATCH) + else if (lock->referent == FH_REF_DATASET) basis = lock->u.unique_id; else basis = 0;