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

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

Documentation de fichiers - Reza 12/4/2000

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