source: Sophya/trunk/SophyaLib/SUtils/datacards.cc@ 1607

Last change on this file since 1607 was 1607, checked in by cmv, 24 years ago

after base restructuration cmv 31/7/01

File size: 9.2 KB
Line 
1//
2// $Id: datacards.cc,v 1.7 2001-07-31 08:06:06 cmv Exp $
3//
4//
5// Eric Aubourg, R. Ansari 1995-2000
6// PEIDA (EROS) - SOPHYA
7// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
8
9
10#include "machdefs.h"
11#include "datacards.h"
12#include "pexceptions.h"
13#include <algorithm>
14#include <iostream.h>
15#include <iomanip.h>
16#include <stdio.h>
17
18//++
19// Class DataCards
20// Lib Utils
21// include datacards.h
22//
23// Cette classe permet la gestion des parametres d'un programme a partir
24// de mot-cle (lecture d'un fichier par exemple)
25//--
26
27
28//++
29// Titre Constructeurs
30//--
31//++
32//
33// DataCards()
34// DataCards(string const& fn)
35// Createur avec lecture des parametres ds le fichier de nom "fn"
36//--
37
38/*!
39 \class SOPHYA::DataCards
40 \ingroup Utils
41 This class can be used for decoding program parameters from an ascii
42 file. Each line of the ascii contains a keyword starting with \b @ .
43 Lines with any other character in the first column are treated as comments.
44 Keywords can be followed by 0 or more parameters.
45 Processing functions (\b ProcCard) can automatically be called for
46 keywords matching a given pattern. (see \b AddProcF )
47*/
48
49/* Default constructor */
50DataCards::DataCards()
51{
52}
53
54/*! constructor with the specification of a parameter file */
55DataCards::DataCards(string const& fn)
56{
57 ReadFile(fn);
58}
59
60//++
61// Titre Methodes
62//--
63//++
64// AddProcF(ProcCard f, string const& mtch="*")
65// Ajoute une fonction de traitement a la liste pour les mots cle
66// compatibles avec la chaine "mtch" ("mtch" peut contenir "*" en debut
67// fin de mot)
68//
69// Clear()
70// Supprime les cartes existantes
71//
72// ReadFile(string const& fn)
73// Lit le contenu du fichiers "fn" et ajoute les cartes a la liste
74//
75// AppendCard(string const& line)
76// Rajoute la carte "line" a la liste
77//--
78
79/*!
80 Adds a new processing function for all keywords matching the
81 specified pattern.
82 \param mtch : The pattern - can contain *
83*/
84void
85DataCards::AddProcF(ProcCard f, string const& mtch)
86{
87CrdPF mpf;
88if (f == NULL) return;
89mpf.pf = f;
90if (mtch.length() <= 0) mpf.patt = "*";
91else mpf.patt = mtch;
92cpfs.push_back(mpf);
93
94// On applique cette nouvelle fonction aux cartes existantes
95CardList::iterator ic;
96for(ic = cards.begin(); ic != cards.end(); ic ++)
97 {
98 vector<string>::iterator ik;
99 string tks;
100 for(ik = (*ic).tokens.begin(); ik != (*ic).tokens.end(); ik++)
101 tks = tks + " " + (*ik);
102 ApplyPF(mpf, (*ic).kw, tks);
103 }
104}
105
106/*! Resets the objects - Suppresses all cards */
107void DataCards::Clear()
108{
109cards.erase(cards.begin(), cards.end());
110}
111
112/*! Reads the file named \b fn. if fn=="" the value of \b SOPHYA_DATACARDS is used */
113void
114DataCards::ReadFile(string const& fn)
115{
116 string file = fn;
117 if (file == "") {
118 char * efn = getenv("SOPHYA_DATACARDS");
119 if (efn != NULL) file = efn;
120 }
121 if (file == "") return;
122
123 try {
124 DoReadFile(file);
125 } catch(...) {
126 char* wdp = getenv("SOPHYA_WORK");
127 if (wdp) {
128 cerr << "DataCards::ReadFile() Error reading file " << fn << " (Trying with SOPHYA_WORK) \n";
129 file = wdp + file;
130 DoReadFile(file);
131 }
132 else cerr << "DataCards::ReadFile() Error reading file " << fn << "\n";
133 throw IOExc("DataCards::ReadFile() Error");
134 }
135}
136
137/*! Appends a card, represented by the string \b crd to the list of cards */
138void
139DataCards::AppendCard(string const& crd)
140{
141Card c;
142size_t p = 1;
143size_t q = crd.find_first_of(" \t");
144size_t l = crd.length();
145
146string toks;
147if (l < 2) return;
148if (crd[0] != '@') return;
149
150if (q < l)
151 { c.kw = crd.substr(p,q-p); toks = crd.substr(q, l-q); }
152else { c.kw = crd.substr(p,l-p); toks = ""; }
153// On applique les ProcFunc's
154ApplyPFL(c.kw, toks);
155while (q < l)
156 {
157 p = crd.find_first_not_of(" \t",q+1); // au debut d'un token
158 if (p>=l) break;
159 q = crd.find_first_of(" \t",p); // la fin du token;
160 string token = crd.substr(p,q-p);
161 c.tokens.push_back(token);
162 }
163// On supprime la carte de la liste, si elle existe deja ...
164RemoveCard(c.kw);
165cards.push_back(c);
166}
167
168
169//++
170// Titre Acces aux parametres
171//--
172//++
173// int NbCards()
174// Renvoie le nombre de cartes data
175// bool HasKey(string const& key)
176// Indique l'existence d'une carte avec la cle "key"
177// int NbParam(string const& key)
178// Indique le nombre de parametre (separes par des espaces) pour la cle "key"
179// string SParam(string const& key, int num = 0, string def="")
180// Renvoie la valeur du parametre numero "num" ( 0..(NbParam()-1) ) sous forme de
181// chaine de caracteres ("string")
182// long IParam(string const& key, int numero = 0, long def = 0)
183// Renvoie la valeur du parametre numero "num" ( 0..(NbParam()-1) ) convertie
184// en entier ("long")
185// double DParam(string const& key, int numero = 0, double def = 0)
186// Renvoie la valeur du parametre numero "num" ( 0..(NbParam()-1) ) convertie
187// en flottant ("double")
188//--
189
190
191/*! Returns true if \b key is present in the list */
192bool
193DataCards::HasKey(string const& key) const
194{
195 return (FindKeyC(key) != cards.end());
196}
197
198//! Returns the total number of cards
199int
200DataCards::NbCards() const
201{
202return(cards.size());
203}
204
205/*! Returns the number of parameters for card \b key. (-1) if \b key not present */
206int
207DataCards::NbParam(string const& key) const
208{
209 DataCards::CardList::const_iterator it = FindKeyC(key);
210 if (it == cards.end()) return(-1);
211 else return((*it).tokens.size());
212}
213
214/*! Returns the key for card number \b num. */
215string
216DataCards::GetKey(int num) const
217{
218 if ((num < 0) || (num >= cards.size()) ) return("");
219 int k = 0;
220 CardList::const_iterator i;
221 for(i=cards.begin(); i != cards.end(); i++) {
222 if (k == num) return((*i).kw);
223 else k++;
224 }
225 return("");
226}
227
228/*! Returns the list of parameters for card \b key. */
229string
230DataCards::GetParams(string const& key) const
231{
232 string rs;
233 DataCards::CardList::const_iterator it = FindKeyC(key);
234 if (it == cards.end()) return(rs);
235 for (int k=0; k<(*it).tokens.size(); k++) {
236 rs += ' '; rs += (*it).tokens[k];
237 }
238 return(rs);
239}
240
241/*! Returns the parameter number \b numero for card \b key */
242string
243DataCards::SParam(string const& key, int numero, string def) const
244{
245 DataCards::CardList::const_iterator it = FindKeyC(key);
246 if (it == cards.end()) return(def);
247 if ( (numero < 0) || (numero >= (*it).tokens.size()) ) return def;
248 return (*it).tokens[numero];
249}
250
251/*! Returns the parameter number \b numero for card \b key, converted to type long */
252long
253DataCards::IParam(string const& key, int numero, long def) const
254{
255 string p = SParam(key, numero, "");
256 if (p == "") return def;
257 long i;
258 //istrstream(p.c_str(), p.length()) >> i;
259 sscanf(p.c_str(),"%ld",&i);
260 return i;
261}
262
263/*! Returns the parameter number \b numero for card \b key, converted to type double */
264double
265DataCards::DParam(string const& key, int numero, double def) const
266{
267 string p = SParam(key, numero, "");
268 if (p == "") return def;
269 double i;
270 //istrstream(p.c_str(), p.length()) >> i;
271 sscanf(p.c_str(),"%lg",&i);
272 return i;
273}
274
275
276/*! Prints the list of cards on the output stream \b s */
277void
278DataCards::Print(ostream& s) const
279{
280 for (CardList::const_iterator i = cards.begin(); i != cards.end(); i++) {
281 s << setw(10) << (*i).kw << " ";
282 for (vector<string>::const_iterator j = (*i).tokens.begin(); j != (*i).tokens.end(); j++)
283 s << (*j) << " ";
284 s << endl;
285 }
286}
287
288/*! Reads the file named \b fn. */
289void
290DataCards::DoReadFile(string const& fn)
291{
292 char line_buff[512];
293 FILE *fip;
294
295 if ( (fip = fopen(fn.c_str(),"r")) == NULL )
296 throw IOExc("DataCards::DoReadFile() fopen Error ") ;
297 while (fgets(line_buff,511,fip) != NULL) {
298 line_buff[strlen(line_buff)-1] = '\0'; /* LF/CR de la fin */
299 string line(line_buff);
300 AppendCard(line);
301 }
302 fclose(fip);
303 return;
304}
305
306int
307DataCards::ApplyPF(CrdPF & cpf, string const& key, string const& toks)
308{
309int l,lk;
310int rc = 0;
311// On verifie si le "pattern" correspond
312bool mtch = false;
313l = cpf.patt.length();
314if (cpf.patt == "*") mtch = true;
315else if (cpf.patt[0] == '*')
316 {
317 lk = key.length();
318 if (cpf.patt[l-1] != '*')
319 {
320 if (strcmp(key.c_str()+(lk-l+1), cpf.patt.c_str()+1) == 0) mtch = true;
321 }
322 else if (key.find(cpf.patt.substr(1,l-2)) < lk) mtch = true;
323 }
324else if (cpf.patt[l-1] == '*')
325 {
326 if ( strncmp(key.c_str(), cpf.patt.c_str(),l-1) == 0) mtch = true;
327 }
328else if (key == cpf.patt) mtch = true;
329
330// Si oui, on appelle la fonction correspondante
331if (mtch) rc = cpf.pf(key, toks);
332
333return(rc);
334}
335
336
337int
338DataCards::ApplyPFL(string const& key, string const& toks)
339{
340int rc = 0;
341CrdPFList::iterator icf;
342for(icf = cpfs.begin(); icf != cpfs.end(); icf++)
343 rc += ApplyPF((*icf), key, toks);
344return(rc);
345}
346
347void
348DataCards::RemoveCard(string const& key)
349{
350CardList::iterator i;
351for(i=cards.begin(); i != cards.end(); i++)
352 if ((*i).kw == key) { cards.erase(i); break; }
353}
354
355DataCards::Card *
356DataCards::FindKey(string const& key)
357{
358/*
359 CardList::iterator i = find_if(cards.begin(), cards.end(), bind2nd(KeyEq(),key));
360 if (i == cards.end() ) return NULL;
361*/
362 CardList::iterator i;
363 for(i=cards.begin(); i != cards.end(); i++)
364 if ((*i).kw == key) return &(*i);
365
366 return NULL;
367}
368
369
370DataCards::CardList::const_iterator
371DataCards::FindKeyC(string const& key) const
372{
373 CardList::const_iterator i;
374 for(i=cards.begin(); i != cards.end(); i++)
375 if ((*i).kw == key) return i;
376 return cards.end();
377}
Note: See TracBrowser for help on using the repository browser.