# HG changeset patch # User jwe # Date 1091559624 0 # Node ID 1cf16fb3459a2febd30a5d301a0b9e5f1544ac57 # Parent b7732e23965be6b2a36efeec6ff9812b231798ea [project @ 2004-08-03 19:00:24 by jwe] diff -r b7732e23965b -r 1cf16fb3459a liboctave/kpse.cc --- a/liboctave/kpse.cc Tue Aug 03 05:00:33 2004 +0000 +++ b/liboctave/kpse.cc Tue Aug 03 19:00:24 2004 +0000 @@ -199,9 +199,6 @@ #undef fopen #define fopen kpse_fopen_trace static FILE *fopen (const char *filename, const char *mode); -#undef fclose -#define fclose kpse_fclose_trace -static int fclose (FILE *); #endif /* not NO_DEBUG */ @@ -340,15 +337,6 @@ return f; } -static void -xfclose (FILE *f, const std::string& filename) -{ - assert (f != 0); - - if (! fclose (f)) - FATAL_PERROR (filename.c_str ()); -} - /* A single (key,value) pair. */ struct hash_element_type @@ -380,49 +368,6 @@ return n; } -static hash_table_type -hash_create (unsigned size) -{ - /* hash_table_type ret; changed into "static ..." to work around gcc - optimizer bug for Alpha. */ - static hash_table_type ret; - unsigned b; - ret.buckets = new hash_element_type * [size]; - ret.size = size; - - /* calloc's zeroes aren't necessarily NULL, so be safe. */ - for (b = 0; b key = key; - new_elt->value = value; - new_elt->next = 0; - - /* Insert the new element at the end of the list. */ - if (! table->buckets[n]) - /* first element in bucket is a special case. */ - table->buckets[n] = new_elt; - else - { - hash_element_type *loc = table->buckets[n]; - while (loc->next) /* Find the last element. */ - loc = loc->next; - loc->next = new_elt; /* Insert the new one after. */ - } -} - /* Look up STR in MAP. Return a (dynamically-allocated) list of the corresponding strings or NULL if no match. */ @@ -461,55 +406,6 @@ return ret; } -/* We only print nonempty buckets, to decrease output volume. */ - -static void -hash_print (hash_table_type table, int summary_only) -{ - unsigned b; - unsigned total_elements = 0, total_buckets = 0; - - for (b = 0; b < table.size; b++) - { - hash_element_type *bucket = table.buckets[b]; - - if (bucket) - { - unsigned len = 1; - hash_element_type *tb; - - total_buckets++; - if (! summary_only) - fprintf (stderr, "%4d ", b); - - for (tb = bucket->next; tb; tb = tb->next) - len++; - - if (! summary_only) - fprintf (stderr, ":%-5d", len); - - total_elements += len; - - if (! summary_only) - { - for (tb = bucket; tb; tb = tb->next) - fprintf (stderr, " %s=>%s", tb->key.c_str (), - tb->value.c_str ()); - - putc ('\n', stderr); - } - } - } - - fprintf (stderr, - "%u buckets, %u nonempty (%u%%); %u entries, average chain %.1f.\n", - table.size, - total_buckets, - 100 * total_buckets / table.size, - total_elements, - total_buckets ? total_elements / (double) total_buckets : 0.0); -} - /* A way to step through a path, extracting one directory name at a time. */ @@ -1802,163 +1698,8 @@ } \ while (0) -/* Find the final search path to use for the format entry INFO, given - the compile-time default (DEFAULT_PATH), and the environment - variables to check (the remaining arguments, terminated with NULL). - We set the `path' and `path_source' members of INFO. The - `client_path' member must already be set upon entry. */ - -static void -init_path (kpse_format_info_type& info, const char *default_path, ...) -{ - va_list ap; - - va_start (ap, default_path); - - info.default_path = default_path; - - /* First envvar that's set to a nonempty value will exit the loop. If - none are set, we want the first cnf entry that matches. Find the - cnf entries simultaneously, to avoid having to go through envvar - list twice -- because of the PVAR?C macro, that would mean having - to create a str_list and then use it twice. Yuck. */ - - char *env_name; - - std::string var; - - while ((env_name = va_arg (ap, char *))) - { - /* Since sh doesn't like envvar names with `.', check PATH_prog - rather than PATH.prog. */ - - if (var.empty ()) - { - /* Try simply PATH. */ - std::string env_value = octave_env::getenv (env_name); - - if (! env_value.empty ()) - var = env_name; - } - - if (! var.empty () && ! info.cnf_path.empty ()) - break; - } - - va_end (ap); - - /* Expand any extra :'s. For each level, we replace an extra : with - the path at the next lower level. For example, an extra : in a - user-set envvar should be replaced with the path from the cnf file. - things are complicated because none of the levels above the very - bottom are guaranteed to exist. */ - - /* Assume we can reliably start with the compile-time default. */ - info.path = info.raw_path = info.default_path; - info.path_source = "compile-time paths.h"; - - EXPAND_DEFAULT (info.cnf_path, "texmf.cnf"); - EXPAND_DEFAULT (info.client_path, "program config file"); - - if (! var.empty ()) - { - std::string val = octave_env::getenv (var); - EXPAND_DEFAULT (val, var + " environment variable"); - } - - EXPAND_DEFAULT (info.override_path, "application override variable"); - std::string tmp = kpse_brace_expand (info.path); - info.path = tmp; -} - -static std::string -remove_dbonly (const std::string& path) -{ - std::string ret = path; - size_t path_len = path.length (); - - size_t i = 0, j = 0; - - bool new_elt = true; - - while (i < path_len) - { - if (new_elt && i + 1 < path_len && path[i] == '!' && path[i+1] == '!') - i += 2; - else - { - new_elt = (path[i] == ENV_SEP); - ret[j++] = path[i++]; - } - } - - ret.resize (j); - - return ret; -} - -/* Initialize everything for FORMAT. */ - -static std::string -kpse_init_format (void) -{ - /* If we get called twice, don't redo all the work. */ - if (! kpse_format_info.path.empty ()) - return kpse_format_info.path; - - kpse_format_info.type = "ls-R"; - init_path (kpse_format_info, DEFAULT_TEXMFDBS, DB_ENVS, 0); - kpse_format_info.suffix.append (std::string ("ls-R")); - kpse_format_info.path = remove_dbonly (kpse_format_info.path); - -#ifdef KPSE_DEBUG -#define MAYBE(member) \ - (kpse_format_info.member.empty () \ - ? "(none)" : kpse_format_info.member.c_str ()) - - /* Describe the monster we've created. */ - if (KPSE_DEBUG_P (KPSE_DEBUG_PATHS)) - { - DEBUGF2 ("Search path for %s files (from %s)\n", - kpse_format_info.type.c_str (), - kpse_format_info.path_source.c_str ()); - - DEBUGF1 (" = %s\n", kpse_format_info.path.c_str ()); - - DEBUGF1 (" before expansion = %s\n", - kpse_format_info.raw_path.c_str ()); - - DEBUGF1 (" application override path = %s\n", MAYBE (override_path)); - - DEBUGF1 (" application config file path = %s\n", MAYBE (client_path)); - - DEBUGF1 (" texmf.cnf path = %s\n", MAYBE (cnf_path)); - - DEBUGF1 (" compile-time path = %s\n", MAYBE (default_path)); - - DEBUGF (" default suffixes ="); - - if (! kpse_format_info.suffix.empty ()) - { - string_vector tmp = kpse_format_info.suffix; - int len = tmp.length (); - for (int i = 0; i < len; i++) - { - fprintf (stderr, " %s", tmp[i].c_str ()); - } - putc ('\n', stderr); - } - else - { - fputs (" (none)\n", stderr); - } - } -#endif /* KPSE_DEBUG */ - - return kpse_format_info.path; -} - static hash_table_type db; /* The hash table for all the ls-R's. */ + /* SMALL: The old size of the hash table was 7603, with the assumption that a minimal ls-R bas about 3500 entries. But a typical ls-R will be more like double that size. */ @@ -1979,196 +1720,6 @@ static string_vector db_dir_list; -/* If DIRNAME contains any element beginning with a `.' (that is more - than just `./'), return true. This is to allow ``hidden'' - directories -- ones that don't get searched. */ - -static bool -ignore_dir_p (const std::string& dirname) -{ - size_t dot_pos = 0; - size_t len = dirname.length (); - - while ((dot_pos = dirname.find ('.', dot_pos + 1)) != NPOS) - { - /* If / before and no / after, skip it. But don't skip xxx/../yyy. */ - if (IS_DIR_SEP (dirname[dot_pos-1]) - && dot_pos + 1 < len - && ! (IS_DIR_SEP (dirname[dot_pos+1]) || dirname[dot_pos+1] == '.')) - return true; - } - - return false; -} - -static bool -read_line (FILE *f, std::string& line) -{ - bool read_something = false; - - int c; - - OSSTREAM buf; - - while ((c = getc (f)) != EOF) - { - read_something = true; - - if (c == '\n' || c == '\r') - break; - - buf << static_cast (c); - } - - /* If we read anything, return it. This can't represent a last - ``line'' which doesn't end in a newline, but so what. */ - if (read_something) - { - /* Absorb LF of a CRLF pair. */ - if (c == '\r') - { - c = getc (f); - if (c != '\n') - ungetc (c, f); - } - - buf << OSSTREAM_ENDS; - line = OSSTREAM_STR (buf); - OSSTREAM_FREEZE (buf); - } - - return read_something; -} - -/* If no DB_FILENAME, return false (maybe they aren't using this feature). - Otherwise, add entries from DB_FILENAME to TABLE, and return true. */ - -static bool -db_build (hash_table_type *table, const std::string& db_filename) -{ - std::string line; - - unsigned dir_count = 0, file_count = 0, ignore_dir_count = 0; - - unsigned len = db_filename.length () - sizeof (DB_NAME) + 1; /* Keep the /. */ - std::string top_dir = db_filename.substr (0, len); - - std::string cur_dir; - - FILE *db_file = xfopen (db_filename, "r"); - - if (db_file) - { - while (read_line (db_file, line)) - { - len = line.length (); - - /* A line like `/foo:' = new dir foo. Allow both absolute (/...) - and explicitly relative (./...) names here. It's a kludge to - pass in the directory name with the trailing : still attached, - but it doesn't actually hurt. */ - if (len > 0 && line[len - 1] == ':' && kpse_absolute_p (line, true)) - { - /* New directory line. */ - if (! ignore_dir_p (line)) - { - /* If they gave a relative name, prepend full - directory name now. */ - line[len - 1] = DIR_SEP; - - /* Skip over leading `./', it confuses `match' and - is just a waste of space, anyway. This will lose - on `../', but `match' won't work there, either, - so it doesn't matter. */ - - cur_dir = line[0] == '.' ? top_dir + line.substr (2) : line; - - dir_count++; - } - else - { - cur_dir = std::string (); - ignore_dir_count++; - } - - /* Ignore blank, `.' and `..' lines. */ - - } - else if (len > 0 && ! cur_dir.empty () /* a file line? */ - && ! (line[0] == '.' - && (len == 1 || (len == 2 && line[1] == '.')))) - { - /* Make a new hash table entry with a key of `line' and - a data of `cur_dir'. An already-existing identical - key is ok, since a file named `foo' can be in more - than one directory. Share `cur_dir' among all its - files (and hence never free it). */ - hash_insert (table, line, cur_dir); - file_count++; - } - } - - xfclose (db_file, db_filename); - - if (file_count == 0) - { - (*current_liboctave_warning_handler) - ("kpathsea: No usable entries in %s", db_filename.c_str ()); - - (*current_liboctave_warning_handler) - ("kpathsea: See the manual for how to generate ls-R"); - - db_file = 0; - } - else - db_dir_list.append (top_dir); - -#ifdef KPSE_DEBUG - if (KPSE_DEBUG_P (KPSE_DEBUG_HASH)) - { - /* Don't make this a debugging bit, since the output is so - voluminous, and being able to specify -1 is too useful. - Instead, let people who want it run the program under - a debugger and change the variable that way. */ - bool hash_summary_only = true; - - DEBUGF4 ("%s: %u entries in %d directories (%d hidden).\n", - db_filename.c_str (), file_count, dir_count, - ignore_dir_count); - - DEBUGF ("ls-R hash table:"); - hash_print (*table, hash_summary_only); - fflush (stderr); - } -#endif /* KPSE_DEBUG */ - } - - return db_file != 0; -} - -/* Insert FNAME into the hash table. This is for files that get built - during a run. We wouldn't want to reread all of ls-R, even if it got - rebuilt. */ - -static void -kpse_db_insert (const std::string& passed_fname) -{ - /* We might not have found ls-R, or even had occasion to look for it - yet, so do nothing if we have no hash table. */ - if (db.buckets) - { - const char *fname = passed_fname.c_str (); - const char *baseptr = octave_basename (fname); - - size_t len = baseptr - fname; - - std::string file_part = passed_fname.substr (len); - std::string dir_part = passed_fname.substr (0, len); - - hash_insert (&db, file_part, dir_part); - } -} - /* Return true if FILENAME could be in PATH_ELT, i.e., if the directory part of FILENAME matches PATH_ELT. Have to consider // wildcards, but $ and ~ expansion have already been done. */ @@ -2280,137 +1831,6 @@ return found; } -/* If ALIAS_FILENAME exists, read it into TABLE. */ - -static bool -alias_build (hash_table_type *table, const std::string& alias_filename) -{ - unsigned count = 0; - - FILE *alias_file = xfopen (alias_filename, "r"); - - if (alias_file) - { - std::string line; - - while (read_line (alias_file, line)) - { - size_t len = line.length (); - - /* comments or empty */ - if (len == 0 || line[0] == '%' || line[0] == '#') - /* do nothing */ ; - else - { - size_t i = 0; - - while (i < len && isspace (line[i])) - i++; - - size_t real_beg = i; - - while (i < len && ! isspace (line[i])) - i++; - - size_t real_len = i - real_beg; - - while (i < len && isspace (line[i])) - i++; - - size_t alias_beg = i; - - while (i < len && ! isspace (line[i])) - i++; - - size_t alias_len = i - alias_beg; - - /* Is the check for errors strong enough? Should we - warn the user for potential errors? */ - if (real_len > 0 && alias_len > 0) - { - hash_insert (table, line.substr (alias_beg, alias_len), - line.substr (real_beg, real_len)); - count++; - } - } - } - -#ifdef KPSE_DEBUG - if (KPSE_DEBUG_P (KPSE_DEBUG_HASH)) - { - /* As with ls-R above ... */ - bool hash_summary_only = true; - DEBUGF2 ("%s: %u aliases.\n", alias_filename.c_str (), count); - DEBUGF ("alias hash table:"); - hash_print (*table, hash_summary_only); - fflush (stderr); - } -#endif /* KPSE_DEBUG */ - - xfclose (alias_file, alias_filename); - } - - return alias_file != 0; -} - -/* Initialize the path for ls-R files, and read them all into the hash - table `db'. If no usable ls-R's are found, set db.buckets to NULL. - Until this is called, no ls-R matches will be found. */ - -static void -kpse_init_db (void) -{ - bool ok = false; - const std::string db_path = kpse_init_format (); - string_vector db_files = kpse_all_path_search (db_path.c_str (), DB_NAME); - - /* Must do this after the path searching (which ends up calling - kpse_db_search recursively), so db.buckets stays NULL. */ - db = hash_create (DB_HASH_SIZE); - - int len = db_files.length (); - for (int i = 0; i < len; i++) - { - if (! db_files[i].empty ()) - { - if (db_build (&db, db_files[i])) - ok = true; - } - } - - if (! ok) - { - /* If db can't be built, leave `size' nonzero (so we don't - rebuild it), but clear `buckets' (so we don't look in it). */ - free (db.buckets); - db.buckets = 0; - } - - /* Add the content of any alias databases. There may exist more than - one alias file along DB_NAME files. This duplicates the above code - -- should be a function. */ - ok = false; - db_files = kpse_all_path_search (db_path.c_str (), ALIAS_NAME); - - alias_db = hash_create (ALIAS_HASH_SIZE); - - len = db_files.length (); - for (int i = 0; i < len; i++) - { - if (! db_files[i].empty ()) - { - if (alias_build (&alias_db, db_files[i])) - ok = true; - } - } - - if (! ok) - { - free (alias_db.buckets); - alias_db.buckets = 0; - } -} - /* Avoid doing anything if this PATH_ELT is irrelevant to the databases. */ /* Return list of matches for NAME in the ls-R file matching PATH_ELT. If @@ -3022,18 +2442,6 @@ return ret; } -static int -fclose (FILE *f) -{ -#undef fclose - int ret = fclose (f); - - if (KPSE_DEBUG_P (KPSE_DEBUG_FOPEN)) - DEBUGF2 ("fclose (0x%lx) => %d\n", (unsigned long) f, ret); - - return ret; -} - #endif /* Implementation of a linked list of strings. */ diff -r b7732e23965b -r 1cf16fb3459a src/dirfns.cc --- a/src/dirfns.cc Tue Aug 03 05:00:33 2004 +0000 +++ b/src/dirfns.cc Tue Aug 03 19:00:24 2004 +0000 @@ -302,7 +302,7 @@ DEFUN (mkdir, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} mkdir (@var{dir})\\n\ +@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} mkdir (@var{dir})\n\ Create a directory named @var{dir}.\n\ \n\ If successful, @var{err} is 0 and @var{msg} is an empty string.\n\ diff -r b7732e23965b -r 1cf16fb3459a src/syscalls.cc --- a/src/syscalls.cc Tue Aug 03 05:00:33 2004 +0000 +++ b/src/syscalls.cc Tue Aug 03 19:00:24 2004 +0000 @@ -587,7 +587,7 @@ DEFUN (mkfifo, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})\n\ -Create a @var{fifo} special file named @var{name} with file mode @var{mode}\n\\n\ +Create a @var{fifo} special file named @var{name} with file mode @var{mode}\n\ \n\ If successful, @var{err} is 0 and @var{msg} is an empty string.\n\ Otherwise, @var{err} is nonzero and @var{msg} contains a\n\