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

Last change on this file since 1238 was 1197, checked in by ansari, 25 years ago

correction petit bug ds datacard.cc (ajout fclose(fip)) et numero de version - Reza 22/9/2000

File size: 8.2 KB
Line 
1/// $Id: datacards.cc,v 1.4 2000-09-22 10:37:44 ansari Exp $
2//
3// Datacards, acquisition EROS II
4//
5//
6// Eric Aubourg, Decembre 95
7//
8// DAPNIA/SPP (Saclay) / CEA
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 SysTools
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 SysTools
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)
194{
195 return FindKey(key) != NULL;
196}
197
198//! Returns the total number of cards
199int
200DataCards::NbCards()
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)
208{
209 DataCards::Card * p = FindKey(key);
210 if (!p) return(-1);
211 else return(p->tokens.size());
212}
213
214/*! Returns the parameter number \b numero for card \b key */
215string
216DataCards::SParam(string const& key, int numero, string def)
217{
218 DataCards::Card * p = FindKey(key);
219 if (!p) return def;
220 if ( (numero < 0) || (numero >= p->tokens.size()) ) return def;
221 return p->tokens[numero];
222}
223
224/*! Returns the parameter number \b numero for card \b key, converted to type long */
225long
226DataCards::IParam(string const& key, int numero, long def)
227{
228 string p = SParam(key, numero, "");
229 if (p == "") return def;
230 long i;
231 //istrstream(p.c_str(), p.length()) >> i;
232 sscanf(p.c_str(),"%ld",&i);
233 return i;
234}
235
236/*! Returns the parameter number \b numero for card \b key, converted to type double */
237double
238DataCards::DParam(string const& key, int numero, double def)
239{
240 string p = SParam(key, numero, "");
241 if (p == "") return def;
242 double i;
243 //istrstream(p.c_str(), p.length()) >> i;
244 sscanf(p.c_str(),"%lg",&i);
245 return i;
246}
247
248
249/*! Prints the list of cards on the output stream \b s */
250void
251DataCards::Print(ostream& s) const
252{
253 for (CardList::const_iterator i = cards.begin(); i != cards.end(); i++) {
254 s << setw(10) << (*i).kw << " ";
255 for (vector<string>::const_iterator j = (*i).tokens.begin(); j != (*i).tokens.end(); j++)
256 s << (*j) << " ";
257 s << endl;
258 }
259}
260
261/*! Reads the file named \b fn. */
262void
263DataCards::DoReadFile(string const& fn)
264{
265 char line_buff[512];
266 FILE *fip;
267
268 if ( (fip = fopen(fn.c_str(),"r")) == NULL )
269 throw IOExc("DataCards::DoReadFile() fopen Error ") ;
270 while (fgets(line_buff,511,fip) != NULL) {
271 line_buff[strlen(line_buff)-1] = '\0'; /* LF/CR de la fin */
272 string line(line_buff);
273 AppendCard(line);
274 }
275 fclose(fip);
276 return;
277}
278
279int
280DataCards::ApplyPF(CrdPF & cpf, string const& key, string const& toks)
281{
282int l,lk;
283int rc = 0;
284// On verifie si le "pattern" correspond
285bool mtch = false;
286l = cpf.patt.length();
287if (cpf.patt == "*") mtch = true;
288else if (cpf.patt[0] == '*')
289 {
290 lk = key.length();
291 if (cpf.patt[l-1] != '*')
292 {
293 if (strcmp(key.c_str()+(lk-l+1), cpf.patt.c_str()+1) == 0) mtch = true;
294 }
295 else if (key.find(cpf.patt.substr(1,l-2)) < lk) mtch = true;
296 }
297else if (cpf.patt[l-1] == '*')
298 {
299 if ( strncmp(key.c_str(), cpf.patt.c_str(),l-1) == 0) mtch = true;
300 }
301else if (key == cpf.patt) mtch = true;
302
303// Si oui, on appelle la fonction correspondante
304if (mtch) rc = cpf.pf(key, toks);
305
306return(rc);
307}
308
309
310int
311DataCards::ApplyPFL(string const& key, string const& toks)
312{
313int rc = 0;
314CrdPFList::iterator icf;
315for(icf = cpfs.begin(); icf != cpfs.end(); icf++)
316 rc += ApplyPF((*icf), key, toks);
317return(rc);
318}
319
320void
321DataCards::RemoveCard(string const& key)
322{
323CardList::iterator i;
324for(i=cards.begin(); i != cards.end(); i++)
325 if ((*i).kw == key) { cards.erase(i); break; }
326}
327
328DataCards::Card *
329DataCards::FindKey(string const& key)
330{
331/*
332 CardList::iterator i = find_if(cards.begin(), cards.end(), bind2nd(KeyEq(),key));
333 if (i == cards.end() ) return NULL;
334*/
335 CardList::iterator i;
336 for(i=cards.begin(); i != cards.end(); i++)
337 if ((*i).kw == key) return &*i;
338
339 return NULL;
340}
341
342
343
Note: See TracBrowser for help on using the repository browser.