ARTS  2.0.49
file.cc
Go to the documentation of this file.
1 /* Copyright (C) 2000-2008 Stefan Buehler <sbuehler@ltu.se>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
18 
20 // File description
22 
33 // External declarations
36 
37 #include "arts.h"
38 
39 #include <stdexcept>
40 #include <cmath>
41 #include <cfloat>
42 #include <cstdio>
43 
44 #ifdef HAVE_UNISTD_H
45 #include <unistd.h>
46 #endif
47 
48 #include "matpackI.h"
49 #include "array.h"
50 #include "messages.h"
51 #include "parameters.h"
52 #include "file.h"
53 
54 
56 // Default file names
58 
60 
72  String& filename,
73  const String& varname )
74 {
75  if ( "" == filename )
76  {
77  extern const String out_basename;
78  filename = out_basename+"."+varname+".aa";
79  }
80 }
81 
82 
84 // Functions to open and read ASCII files
86 
88 
97 void open_output_file(ofstream& file, const String& name)
98 {
99  String ename = expand_path(name);
100 
101  // Tell the stream that it should throw exceptions.
102  // Badbit means that the entire stream is corrupted, failbit means
103  // that the last operation has failed, but the stream is still
104  // valid. We don't want either to happen!
105  // FIXME: This does not yet work in egcs-2.91.66, try again later.
106  file.exceptions(ios::badbit |
107  ios::failbit);
108 
109  // c_str explicitly converts to c String.
110  file.open(ename.c_str() );
111 
112  // See if the file is ok.
113  // FIXME: This should not be necessary anymore in the future, when
114  // g++ stream exceptions work properly. (In that case we would not
115  // get here if there really was a problem, because of the exception
116  // thrown by open().)
117  if (!file)
118  {
119  ostringstream os;
120  os << "Cannot open output file: " << ename << '\n'
121  << "Maybe you don't have write access "
122  << "to the directory or the file?";
123  throw runtime_error(os.str());
124  }
125 }
126 
127 
129 
135 #ifdef HAVE_REMOVE
136 void cleanup_output_file(ofstream& file, const String& name)
137 {
138  if (file.is_open())
139  {
140  streampos fpos = file.tellp();
141  file.close();
142  if (!fpos) unlink(expand_path(name).c_str());
143  }
144 }
145 #else
146 void cleanup_output_file(ofstream&, const String&) {}
147 #endif
148 
149 
150 
152 
160 void open_input_file(ifstream& file, const String& name)
161 {
162  String ename = expand_path(name);
163 
164  // Tell the stream that it should throw exceptions.
165  // Badbit means that the entire stream is corrupted.
166  // On the other hand, end of file will not lead to an exception, you
167  // have to check this manually!
168  file.exceptions(ios::badbit);
169 
170  // c_str explicitly converts to c String.
171  file.open(ename.c_str() );
172 
173  // See if the file is ok.
174  // FIXME: This should not be necessary anymore in the future, when
175  // g++ stream exceptions work properly.
176  if (!file)
177  {
178  ostringstream os;
179  os << "Cannot open input file: " << ename << '\n'
180  << "Maybe the file does not exist?";
181  throw runtime_error(os.str());
182  }
183 }
184 
185 
186 
188 
197 void read_text_from_stream(ArrayOfString& text, istream& is)
198 {
199  String linebuffer;
200 
201  // Read as long as `is' is good.
202  // Contary to what I understood from the book, the explicit check
203  // for eof is necessary here, otherwise the last line is read twice
204  // if it is not terminated by a newline character!
205  while (is && is.good() && !is.eof())
206  {
207  // Read line from file into linebuffer:
208  getline(is,linebuffer);
209 
210  // Append to end of text:
211  text.push_back(linebuffer);
212  }
213 
214  // Check for error:
215  // FIXME: This should not be necessary anymore when stream
216  // exceptions work properly.
217  if ( !is.eof() ) {
218  ostringstream os;
219  os << "Read Error. Last line read:\n" << linebuffer;
220  throw runtime_error(os.str());
221  }
222 
223 }
224 
225 
226 
228 
238 void read_text_from_file(ArrayOfString& text, const String& name)
239 {
240  ifstream ifs;
241 
242  // Open input stream:
243  open_input_file(ifs, name);
244  // No need to check for error, because open_input_file throws a
245  // runtime_error with an appropriate error message.
246 
247  // Read the text from the stream. Here we catch the exception,
248  // because then we can issue a nicer error message that includes the
249  // filename.
250  try
251  {
252  read_text_from_stream(text,ifs);
253  }
254  catch (runtime_error x)
255  {
256  ostringstream os;
257  os << "Error reading file: " << name << '\n'
258  << x.what();
259  throw runtime_error(os.str());
260  }
261 }
262 
264 
275 {
276  if ((path.nelem() == 1 && path[0] == '~')
277  || (path.nelem() > 1 && path[0] == '~' && path[1] == '/'))
278  {
279  return String(getenv ("HOME")) + String(path, 1);
280  }
281  else
282  {
283  return path;
284  }
285 }
286 
288 
296 void replace_all(String& s, const String& what, const String& with)
297 {
298  Index j = s.find(what);
299  while ( j != s.npos )
300  {
301  s.replace(j,1,with);
302  j = s.find(what,j+with.size());
303  }
304 }
305 
307 
317 int check_newline(const String& s)
318 {
319  String d = s;
320  int result = 0;
321 
322  // Remove all whitespaces except \n
323  replace_all (d, " ", "");
324  replace_all (d, "\t", "");
325  replace_all (d, "\r", "");
326 
327  const char *cp = d.c_str ();
328  while ((*cp == '\n') && *cp) cp++;
329 
330  if (!(*cp))
331  result = 1;
332 
333  if (!result && d[d.length () - 1] != '\n')
334  result = 2;
335  else if (!result && d.length () > 2
336  && d[d.length () - 1] == '\n' && d[d.length () - 2] == '\n')
337  result = 3;
338 
339  return result;
340 }
341 
342 
344 
353 bool file_exists(const String& filename)
354 {
355  bool exists = false;
356  fstream fin;
357  fin.open(filename.c_str(), ios::in);
358  if (fin.is_open())
359  {
360  exists=true;
361  }
362  fin.close();
363  return exists;
364 }
365 
366 
368 
379 bool find_file(String& filename, const char* extension)
380 {
381  bool exists = true;
382  extern const Parameters parameters;
383 
384  if (!file_exists (filename))
385  {
386  if (file_exists (filename + extension))
387  {
388  filename += extension;
389  }
390  else
391  {
392  Index i;
393  for (i=0; i < parameters.includepath.nelem(); i++)
394  {
395  String fullpath;
396  fullpath = parameters.includepath[i] + "/" + filename;
397  if (file_exists (fullpath))
398  {
399  filename = fullpath;
400  break;
401  }
402  else if (file_exists (fullpath + extension))
403  {
404  filename = fullpath + extension;
405  break;
406  }
407  }
408  if (i == parameters.includepath.nelem())
409  {
410  exists = false;
411  }
412  }
413  }
414 
415  return exists;
416 }
417 
Parameters
Structure to hold all command line Parameters.
Definition: parameters.h:42
cleanup_output_file
void cleanup_output_file(ofstream &, const String &)
Closes the file.
Definition: file.cc:146
open_input_file
void open_input_file(ifstream &file, const String &name)
Open a file for reading.
Definition: file.cc:160
array.h
This file contains the definition of Array.
find_file
bool find_file(String &filename, const char *extension)
Find the given file.
Definition: file.cc:379
matpackI.h
Array
This can be used to make arrays out of anything.
Definition: array.h:103
read_text_from_stream
void read_text_from_stream(ArrayOfString &text, istream &is)
Read an ASCII stream and append the contents to the String array text.
Definition: file.cc:197
messages.h
Declarations having to do with the four output streams.
my_basic_string
The implementation for String, the ARTS string class.
Definition: mystring.h:62
file_exists
bool file_exists(const String &filename)
Checks if the given file exists.
Definition: file.cc:353
parameters.h
This file contains header information for the dealing with command line parameters.
out_basename
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:42
open_output_file
void open_output_file(ofstream &file, const String &name)
Open a file for writing.
Definition: file.cc:97
my_basic_string::nelem
Index nelem() const
Number of elements.
Definition: mystring.h:242
read_text_from_file
void read_text_from_file(ArrayOfString &text, const String &name)
Reads an ASCII file and appends the contents to the String vector text.
Definition: file.cc:238
expand_path
String expand_path(const String &path)
Definition: file.cc:274
parameters
Parameters parameters
Holds the command line parameters.
Definition: parameters.cc:40
String
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:305
check_newline
int check_newline(const String &s)
Checks if there is exactly one newline character at the end of the string.
Definition: file.cc:317
filename_ascii
void filename_ascii(String &filename, const String &varname)
Gives the default file name for the ASCII formats.
Definition: file.cc:71
file.h
This file contains basic functions to handle ASCII files.
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
my_basic_string::npos
static const Index npos
Define npos:
Definition: mystring.h:96
Parameters::includepath
ArrayOfString includepath
List of paths to search for include files.
Definition: parameters.h:97
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:172
arts.h
The global header file for ARTS.
replace_all
void replace_all(String &s, const String &what, const String &with)
Replace all occurances of ‘what’ in ‘s’ with ‘with’.
Definition: file.cc:296