summaryrefslogtreecommitdiff
path: root/utils/DirPath.cc
diff options
context:
space:
mode:
Diffstat (limited to 'utils/DirPath.cc')
-rw-r--r--utils/DirPath.cc214
1 files changed, 214 insertions, 0 deletions
diff --git a/utils/DirPath.cc b/utils/DirPath.cc
new file mode 100644
index 0000000..0536eb2
--- /dev/null
+++ b/utils/DirPath.cc
@@ -0,0 +1,214 @@
+/*
+ * CENA C++ Utilities
+ *
+ * by Stephane Chatty
+ *
+ * Copyright 1991, 1992
+ * Laboratoire de Recherche en Informatique (LRI)
+ * Centre d'Etudes de la Navigation Aerienne (CENA)
+ *
+ * management of search paths
+ *
+ * $Id$
+ * $CurLog$
+ */
+
+#include "DirPath.h"
+#include "String.h"
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+/*?class CcuDirPath
+\typ{CcuDirPath}s generalize the idea contained in the \com{PATH} environment variable
+of UNIX.
+A \typ{CcuDirPath} is a list of strings, which are thought of as directory names.
+When looking for a file, each directory in the list is scanned, until the file is found or the
+end of the list is reached.
+?*/
+
+
+/*?
+Construct an empty directory path.
+?*/
+CcuDirPath :: CcuDirPath ()
+: CcuList (),
+ Alloc (DontAllocNames)
+{
+}
+
+/*?
+Construct an empty directory path.
+The default allocation mode is set to \var{alloc} (see function \fun{FindFile}).
+All other constructors initialize it to 0.
+?*/
+CcuDirPath :: CcuDirPath (alloc_mode alloc)
+: CcuList (),
+ Alloc (alloc)
+{
+}
+
+/*?
+Construct a \typ{CcuDirPath} which has one element \var{name}. The string \var{name}
+is copied.
+?*/
+CcuDirPath :: CcuDirPath (const char* name)
+: CcuList (NewString (name)),
+ Alloc (DontAllocNames)
+{
+}
+
+/*?
+Construct a \typ{CcuDirPath} with two or more elements (\var{first}, \var{second},
+and so on). All strings (\var{first} and the following ones) are copied.
+{\bf The argument list must be null-terminated.}
+?*/
+CcuDirPath :: CcuDirPath (const char* first, const char*, ...)
+: CcuList (),
+ Alloc (DontAllocNames)
+{
+
+ va_list ap;
+ va_start(ap, first);
+
+ for (;;) {
+ const char* p = va_arg(ap,char*);
+ if (!p)
+ break;
+ Append (p);
+ }
+
+ va_end(ap);
+}
+
+/*?nodoc?*/
+CcuDirPath :: ~CcuDirPath ()
+{
+ CcuListIter li (*this);
+ while (++li)
+ FreeString ((char*) (*li));
+}
+
+/*?nextdoc?*/
+void
+CcuDirPath :: Append (const char* dir)
+{
+ CcuList::Append (NewString (dir));
+}
+
+/*?
+Append (resp. prepend) a directory name to a search path. A copy of the
+string \var{dir} is created.
+?*/
+void
+CcuDirPath :: Prepend (const char* dir)
+{
+ CcuList::Prepend (NewString (dir));
+}
+
+/*?nodoc?*/
+int
+CcuDirPath :: Remove (const char* d)
+{
+ int removed = 0;
+ CcuListIter li (*this);
+ CcuListIter lj (*this);
+ while (++li) {
+ int remove = (strcmp (d, (const char*) *li) == 0);
+ if (remove) {
+ ++removed;
+ RemoveAfter (lj);
+ } else
+ ++lj;
+ }
+ return removed;
+}
+
+/*?
+Search a path for a readable file with name \var{fn}. The absolute path name
+is returned, or 0 if the search fails.
+If the search succeeds, \var{alloc} determines whether
+the returned name should be a dynamically allocated string or not.
+If \var{alloc} is not null, an allocation is performed.
+If \var{alloc} is 0, and \var{fn} was already a full pathname, \var{fn} is returned.
+If \var{alloc} is 0, and \var{fn} was a relative pathname found in the search path,
+a named stored in a static buffer is returned.
+A pathname is considered a full pathname (and hence is not looked up in
+the search path) if it begins with ``\com{/}'', ``\com{./}'' or ``\com{../}''.
+?*/
+const char*
+CcuDirPath :: FindFile (const char* fn, alloc_mode alloc)
+{
+ if (!fn)
+ return 0;
+
+ static char absfn[128];
+ char *dir;
+ char* pathend;
+
+ /* If fn begins with '/', './' or '../' it is considered absolute */
+
+ register const char* p = fn;
+ while (*p == '.')
+ ++p;
+ if ((p - fn) <= 2 && (! *p || *p == '/'))
+ return access (fn, R_OK) ? 0 : alloc ? NewString (fn) : fn;
+
+ /* Else, look through search path */
+
+ CcuListIter it (*this) ;
+ while (++it) {
+ dir = (char*) (*it);
+ strcpy (absfn, dir);
+ pathend = absfn + strlen (dir);
+ if (*(pathend-1) != '/') {
+ *pathend++ = '/';
+ *pathend = '\0';
+ }
+ strcat (absfn, fn);
+ if (access (absfn, R_OK) == 0)
+ return (alloc != DontAllocNames) ? NewString (absfn) : absfn;
+ }
+ return 0;
+}
+
+#ifdef DOC
+
+/*?
+This function is similar to the previous one.
+It uses the allocation mode of this \typ{CcuDirPath} to decide whether to allocate
+the returned string or not.
+?*/
+const char*
+CcuDirPath :: FindFile (const char* fn)
+{
+}
+
+/*?
+Set the allocation mode of this dir path to \var{alloc}.
+?*/
+void
+CcuDirPath :: SetAlloc (alloc_mode alloc)
+{
+}
+
+#endif /* DOC */
+
+/*?
+Add the directories contained in a string of the same form as the environment variable ``PATH'',
+i.e. dir1:dir2:\ldots:dirN. \var{sep} is the character separating the different components.
+Its default value is ``:''.
+?*/
+void
+CcuDirPath :: AppendEnvPath (const char* path, char sep)
+{
+ const char *dir, *next = path;
+
+ for (dir = path; next; dir = next+1) {
+ next = strchr (dir, sep);
+ if (next != dir)
+ CcuList::Append (next ? NewString (dir, next-dir) : NewString (dir));
+ }
+}
+