home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-base.tgz / octave-1.1.1p1-base.tar / fsf / octave / kpathsea / db.c < prev    next >
C/C++ Source or Header  |  1994-03-24  |  4KB  |  143 lines

  1. /* db.c: an external database to avoid filesystem lookups.
  2.  
  3. Copyright (C) 1994 Karl Berry.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <kpathsea/config.h>
  20. #include <kpathsea/c-fopen.h>
  21. #include <kpathsea/c-pathch.h>
  22. #include <kpathsea/debug.h>
  23. #include <kpathsea/db.h>
  24. #include <kpathsea/hash.h>
  25. #include <kpathsea/line.h>
  26. #include <kpathsea/readable.h>
  27. #include <kpathsea/str-list.h>
  28.  
  29.  
  30. /* If no DB_FILE, return false (maybe they aren't using this feature).
  31.    Otherwise, build the db and return true.  */
  32.  
  33. static boolean
  34. db_build P1C(hash_table_type *, table)
  35. {
  36.   string line;
  37.   string cur_dir = NULL; /* First thing in ls-R might be a filename.  */
  38.   string db_filename = concat3 (DB_DIR, DIR_SEP_STRING, DB_NAME);
  39.   FILE *db_file = fopen (db_filename, FOPEN_R_MODE);
  40.   
  41.   if (db_file)
  42.     {
  43.       while ((line = read_line (db_file)) != NULL)
  44.         {
  45.           unsigned len = strlen (line);
  46.           if (line[0] == DIR_SEP && line[len - 1] == ':') /* /...: = new dir */
  47.             {
  48.               cur_dir = xstrdup (line);
  49.               cur_dir[len - 1] = DIR_SEP;
  50.             }
  51.           else if (line[0] != 0 && cur_dir) /* other nonblank line */
  52.             { /* New hash table entry with a key of `line' and a data of
  53.                  `cur_dir'.  Already-existing identical keys are ok, since
  54.                  a file named `foo' can be in more than one directory.
  55.                  Since it doesn't hurt, share the directory name string
  56.                  among all the files in the directory. */
  57.               hash_insert (table, xstrdup (line), cur_dir);
  58.             }
  59.           /* else ignore blank lines */
  60.  
  61.           free (line);
  62.         }
  63.       xfclose (db_file, db_filename);
  64.  
  65. #ifdef DEBUG
  66.       if (DEBUG_P (DEBUG_DB_BUILD))
  67.         hash_print (*table);
  68. #endif
  69.     }
  70.  
  71.   free (db_filename);
  72.   return db_file != NULL;
  73. }
  74.  
  75. /* Return true if FILENAME could be in PATH_ELT, i.e., if the directory
  76.    part of FILENAME matches PATH_ELT.  Have to consider // wildcards, but
  77.    $ and ~ expansion have already been done.  */
  78.      
  79. static boolean
  80. match P2C(const_string, filename,  const_string, path_elt)
  81. {
  82.   return true; /* Punt for now.  */
  83. }
  84.  
  85. /* Don't bother implementing a search path for the database itself, or
  86.    multiple databases, until people ask.  */
  87.  
  88. str_list_type *
  89. kpse_db_search P3C(const_string, name,  const_string, path_elt,  boolean, all)
  90. {
  91.   static hash_table_type db;
  92.   string *db_dirs, *orig_dirs;
  93.   boolean done;
  94.   str_list_type *ret;
  95.   
  96.   /* Hash up the database if this is the first call.  */
  97.   if (db.size == 0)
  98.     {
  99.       db = hash_create (7603); /* What the heck, sparse is ok.  */
  100.       if (!db_build (&db))
  101.         { /* If db can't be built, leave `size' alone (so we don't
  102.              rebuild it), but clear `buckets' (so we don't look in it).  */
  103.           free (db.buckets);
  104.           db.buckets = NULL;
  105.         }
  106.     }
  107.   
  108.   /* If we failed to build the database, quit.  */
  109.   if (db.buckets == NULL)
  110.     return NULL;
  111.   
  112.   /* We have a db.  Look up NAME.  */
  113.   orig_dirs = db_dirs = hash_lookup (db, name);
  114.  
  115.   done = false;
  116.   ret = XTALLOC1 (str_list_type);
  117.   *ret = str_list_init ();
  118.   
  119.   /* For each filename found, see if it matches the path element.  For
  120.      example, if we have ../cx/cmr10.300pk and .../ricoh/cmr10.300pk,
  121.      and the path looks like .../cx, we don't want the ricoh file.  */
  122.   while (!done && db_dirs && *db_dirs)
  123.     {
  124.       string db_file = concat (*db_dirs, name);
  125.       
  126.       if (match (db_file, path_elt) && kpse_readable_file (db_file))
  127.         {
  128.           str_list_add (ret, db_file);
  129.           if (!all) done = true;
  130.         }
  131.       else
  132.         free (db_file);
  133.       
  134.       /* On to the next directory, if any.  */
  135.       db_dirs++;
  136.     }
  137.   
  138.   /* This is just the space for the pointers, not the strings.  */
  139.   if (orig_dirs && *orig_dirs) free (orig_dirs);
  140.   
  141.   return ret;
  142. }
  143.