PLUTO
parse_file.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief File parser utilities.
5 
6  This file provides a set of useful functions to open / read and
7  parse the content of a parameter file (typically pluto.ini).
8  The parameter file can contain a number of lines
9  with the general structure
10 
11  <tt> label value1 value2 ... </tt>
12 
13  where the number of values following the label can be different
14  for each line.
15 
16  ParamFileRead() reads the file and store its content into an array of
17  lines (\c **fline).
18  ParamFileGet() can be used to retrieve the n-th parameter value
19  following a given label, while ParQuery() check whether a
20  parameter actually exists.
21 
22  As an example consider the following file "myparam.txt":
23 
24  \verbatim
25  ---- File myparam.txt -----
26  nx 100
27  xdomain 15.0 30.0
28  ---------------------------
29  \endverbatim
30 
31  The parameter can be read with the following code snippet:
32  \code
33  int nlines,nx;
34  double xbeg, xend;
35  nlines = ParamFileRead("myparam.txt");
36  nx = atoi(ParamFileGet("nx", 1));
37  xbeg = atof(ParamFileGet("xdomain", 1));
38  xend = atof(ParamFileGet("xdomain", 2));
39  \endcode
40 
41  \authors A. Mignone (mignone@ph.unito.it)
42  \date June 18, 2014
43 */
44 /* ///////////////////////////////////////////////////////////////////// */
45 #include "pluto.h"
46 
47 static int nlines; /**< The total number of lines (including empty ones)
48  contained in the file */
49 static char **fline; /**< All of the lines (including empty ones) in the file */
50 static int ParamFileGetWords(char *line, char **);
51 
52 /* ********************************************************************* */
53 int ParamFileRead (char *fname)
54 /*!
55  * Parse file *fname and store its content line by line in *fline.
56  * Blank lines are excluded.
57  *
58  * \param [in] fname the name of the file to be read
59  * \return the number of liens successfully read.
60  *********************************************************************** */
61 {
62  char sline[512];
63  FILE *fp;
64 
65  if (fline == NULL) fline = ARRAY_2D(128,128,char);
66 
67  fp = fopen(fname,"r");
68  if (fp == NULL) {
69  printf ("! ParamFileRead: file %s not found\n", fname);
70  QUIT_PLUTO(1);
71  }
72  nlines = 0;
73 
74  while ( fgets(sline, 512, fp) != NULL ) {
75  if (strlen(sline) > 0) {
76  strcpy (fline[nlines],sline);
77  nlines++;
78  }
79  }
80  fclose(fp);
81 
82  return(nlines);
83 }
84 
85 /* ********************************************************************* */
86 char *ParamFileGet (const char *label, int pos)
87 /*!
88  * Search for \c *label in all the lines pointed to by \c **fline.
89  * If label exists, return a pointer to the string located pos
90  * words after label. Issue an error if this string cannot
91  * be located.
92  *
93  * \param [in] label the first word of a line to be searched
94  * \param [in] pos an integer giving the position of the word
95  * \return the n-th word contained in the same line
96  *********************************************************************** */
97 {
98  int k, nwords, nw;
99  static char **words;
100 
101 /* -------------------------------------------------------------
102  Allocate memory and initialize words[][] string array with
103  to avoid unpleasant situations occurring when there're
104  empty words.
105  ------------------------------------------------------------- */
106 
107  if (words == NULL) words = ARRAY_2D(128,128,char);
108  for (k = 0; k < 127; k++) sprintf (words[k],"\0");
109 
110  for (k = 0; k < nlines; k++) { /* Loop over lines */
111  nwords = ParamFileGetWords(fline[k],words); /* get words for k-th line */
112 
113  if (nwords > 0 && strcmp(words[0],label) == 0){ /* check if 1st word */
114  if (pos <= nwords) return words[pos]; /* matches label */
115  else {
116  printf ("! ParamFileGet: field # %d does not exist\n",pos);
117  QUIT_PLUTO(1);
118  }
119  }
120  }
121 
122  printf ("! ParamFileGet: label '%s' was not found\n",label);
123  QUIT_PLUTO(1);
124 
125  return NULL;
126 }
127 
128 /* ********************************************************************* */
129 int ParamFileHasBoth (const char *label1, const char *label2)
130 /*!
131  * Locate the line beginning with label1 and return 1 if label2
132  * can be found on the same line. Return 0 otherwise.
133  *
134  * \param [in] label1 The first word of the line to be searched
135  * \param [in] label2 A word containined in the same line beginning with
136  * label1
137  * \return 1 If label2 and label1 are in the same line. 0 otherwise.
138  *********************************************************************** */
139 {
140  int k, nwords, nw;
141  static char **words;
142 
143  if (words == NULL) words = ARRAY_2D(128,128,char);
144 
145  for (k = 0; k < nlines; k++) { /* Loop over lines */
146  nwords = ParamFileGetWords(fline[k],words); /* get words for k-th line */
147  if (strcmp(words[0],label1) == 0){
148  for (nw = 1; nw < nwords; nw++){
149  if (words[nw][0] == '#') break; /* comment detected:
150  no need to read any further */
151  if (strcmp(words[nw], label2) == 0) return 1;
152  }
153  }
154  }
155  return 0;
156 }
157 
158 /* ********************************************************************* */
159 int ParamExist (const char *label)
160 /*!
161  * Check whether *label exists in any of the lines (**fline).
162  *
163  * \param [in] label
164  * \return 0 on success, 1 if label cannot be found.
165  *********************************************************************** */
166 {
167  int k;
168  char sline[512], *str;
169  const char delimiters[] = " \t\r\f";
170 
171 /* ---------------------------------------
172  search if label exists
173  --------------------------------------- */
174 
175  for (k = 0; k < nlines; k++) {
176  sprintf (sline,"%s",fline[k]);
177  str = strtok(sline,delimiters);
178  if (strcmp(str,label) == 0) return(1);
179  }
180 
181  return (0);
182 }
183 
184 /* ********************************************************************* */
185 int ParamFileGetWords(char *line, char **words)
186 /*!
187  * Return the words and their number contained in a single line.
188  *
189  *********************************************************************** */
190 {
191  int nw, nwords=0;
192  char *str, cstr[512];
193  const char delimiters[] = " \t\r\f";
194 
195 /* -- make a local copy of 'line' since strtok will modify it -- */
196 
197  strcpy (cstr,line);
198  str = strtok(cstr,delimiters);
199 
200 /* -- loop until end of line, copy and count words -- */
201 
202  while (str != NULL && str[0] != '\n') {
203  strcpy(words[nwords],str);
204  str = strtok(NULL, delimiters);
205  nwords++;
206  }
207 
208 /* -- get rid of newline character at the end of each word (if any) -- */
209 
210  for (nw = 0; nw < nwords; nw++){
211  strcpy (cstr, words[nw]);
212  sprintf (words[nw],"%s",strtok(cstr,"\n"));
213  }
214 
215  return nw;
216 }
static int ParamFileGetWords(char *line, char **)
Definition: parse_file.c:185
int ParamExist(const char *label)
Definition: parse_file.c:159
int ParamFileHasBoth(const char *label1, const char *label2)
Definition: parse_file.c:129
static char ** fline
All of the lines (including empty ones) in the file.
Definition: parse_file.c:49
static int nlines
The total number of lines (including empty ones) contained in the file.
Definition: parse_file.c:47
int k
Definition: analysis.c:2
int ParamFileRead(char *fname)
Definition: parse_file.c:53
PLUTO main header file.
FILE * fp
Definition: analysis.c:7
#define ARRAY_2D(nx, ny, type)
Definition: prototypes.h:171
char * ParamFileGet(const char *label, int pos)
Definition: parse_file.c:86
#define QUIT_PLUTO(e_code)
Definition: macros.h:125