1  /************************************************************************/
2  /*                                                                      */
3  /*                Centre for Speech Technology Research                 */
4  /*                     University of Edinburgh, UK                      */
5  /*                       Copyright (c) 1996,1997                        */
6  /*                        All Rights Reserved.                          */
7  /*                                                                      */
8  /*  Permission is hereby granted, free of charge, to use and distribute */
9  /*  this software and its documentation without restriction, including  */
10  /*  without limitation the rights to use, copy, modify, merge, publish, */
11  /*  distribute, sublicense, and/or sell copies of this work, and to     */
12  /*  permit persons to whom this work is furnished to do so, subject to  */
13  /*  the following conditions:                                           */
14  /*   1. The code must retain the above copyright notice, this list of   */
15  /*      conditions and the following disclaimer.                        */
16  /*   2. Any modifications must be clearly marked as such.               */
17  /*   3. Original authors' names are not deleted.                        */
18  /*   4. The authors' names are not used to endorse or promote products  */
19  /*      derived from this software without specific prior written       */
20  /*      permission.                                                     */
21  /*                                                                      */
22  /*  THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK       */
23  /*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING     */
24  /*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT  */
25  /*  SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE    */
26  /*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   */
27  /*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  */
28  /*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,         */
29  /*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF      */
30  /*  THIS SOFTWARE.                                                      */
31  /*                                                                      */
32  /************************************************************************/
33  /*                 Author: Richard Caley (rjc@cstr.ed.ac.uk)            */
34  /*                   Date: Tue Mar 18 1997                              */
35  /************************************************************************/
36  /*                                                                      */
37  /* Implementation of a class for manipulating filenames and so on.      */
38  /*                                                                      */
39  /* This is all hard coded to be unix filenames. I think the best        */
40  /* strategy is to have a separate version of this for any other         */
41  /* pathname format rather than trying to parameterise this. Most of     */
42  /* it is fairly simple.                                                 */
43  /*                                                                      */
44  /************************************************************************/
45 
46 #include "EST_unix.h"
47 #include "EST_Pathname.h"
48 
setup(void)49 void EST_Pathname::setup(void)
50 {
51 }
52 
is_absolute(void) const53 int EST_Pathname::is_absolute(void) const
54 {
55   return length()>0 && (*this)(0) == '/';
56 }
57 
is_dirname(void) const58 int EST_Pathname::is_dirname(void) const
59 {
60   return length()>0 && (*this)(length()-1) == '/';
61 }
62 
directory(void) const63 EST_Pathname EST_Pathname::directory(void) const {
64 
65   if (is_dirname())
66     return *this;
67 
68   int pos;
69   if ((pos=index("/", -1)) >=0)
70     return before(pos+1);
71   else
72     return "./";
73  }
74 
as_file(void) const75 EST_Pathname EST_Pathname::as_file(void) const
76 {
77   if (is_filename())
78     return *this;
79 
80   if (length() > 0)
81     return before(-1);
82 
83   return ".";
84 }
85 
as_directory(void) const86 EST_Pathname EST_Pathname::as_directory(void) const
87 {
88   if (is_dirname())
89     return *this;
90 
91   if (length() > 0)
92   {
93       EST_String xx;
94       xx = EST_String(*this) + "/";
95       return xx;
96   }
97 
98   return "./";
99 }
100 
construct(EST_Pathname dir,EST_String filename)101 EST_Pathname EST_Pathname::construct(EST_Pathname dir,
102 				     EST_String filename)
103 {
104   EST_String result(dir.as_directory());
105 
106   result += filename;
107   return result;
108 }
109 
construct(EST_Pathname dir,EST_String basename,EST_String extension)110 EST_Pathname EST_Pathname::construct(EST_Pathname dir,
111 				     EST_String basename,
112 				     EST_String extension)
113 {
114   EST_Pathname filename(basename + "." + extension);
115   return EST_Pathname::construct(dir, filename);
116 }
117 
entries(int check_for_directories) const118 EST_TList<EST_String> EST_Pathname::entries(int check_for_directories) const
119 {
120   DIR *dir;
121   EST_TList<EST_String> list;
122 
123   if ((dir = opendir(this->as_directory()))!=NULL)
124     {
125       struct dirent *entry;
126 
127       while ((entry = readdir(dir)) != NULL)
128 	{
129 	  EST_Pathname name(entry->d_name);
130 	  struct stat buf;
131 
132 	  if (check_for_directories &&
133 	      stat((EST_String)this->as_directory() + (EST_String)name, &buf)==0 &&
134 	      (buf.st_mode & S_IFDIR))
135 	    list.append(name.as_directory());
136 	  else
137 	    list.append(name);
138 	}
139       closedir(dir);
140     }
141 
142   return list;
143 }
144 
operator +(const EST_Pathname p,const EST_Pathname addition)145 EST_Pathname operator + (const EST_Pathname p, const EST_Pathname addition)
146 {return EST_Pathname::append(p, addition); }
147 
operator +(const char * p,const EST_Pathname addition)148 EST_Pathname operator + (const char *p, const EST_Pathname addition)
149 {return EST_Pathname::append(p, addition); }
150 
151 #if 0
152 EST_Pathname operator += (EST_Pathname p, const EST_Pathname addition)
153 { EST_String q = EST_Pathname::append(p, addition); return q; }
154 EST_Pathname operator += (EST_Pathname p, const EST_String addition)
155 { EST_String q = EST_Pathname::append(p, addition); return q; }
156 #endif
157 
append(EST_Pathname directory,EST_Pathname addition)158 EST_Pathname EST_Pathname::append(EST_Pathname directory, EST_Pathname addition)
159 {
160   if (addition.is_absolute())
161     return addition;
162 
163   EST_String add(addition);
164 
165   EST_String result(directory.as_directory());
166 
167   result += add;
168 
169   return result;
170 }
171 
172 
extension(void) const173 EST_String EST_Pathname::extension(void) const
174 {
175     EST_String result("");
176 
177     if (length() <= 0)
178 	return result;
179 
180     if (contains("."))
181 	result = after(index(".",-1));
182 
183     return result;
184 
185 }
186 
filename(void) const187 EST_Pathname EST_Pathname::filename(void) const
188 {
189   EST_String result(this->as_file());
190 
191     if (contains("/"))
192 	  result = result.after(index("/",-1));
193     return result;
194 }
195 
basename(int remove_all) const196 EST_String EST_Pathname::basename(int remove_all) const
197 {
198     EST_String result(this->as_file().filename());
199 
200     if (remove_all)
201       {
202 	if (result.contains("."))
203 	  result = result.before(".");
204       }
205     return result;
206 }
207