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

Last change on this file since 2327 was 2322, checked in by cmv, 23 years ago
  • passage xxstream.h en xxstream
  • compile avec gcc_3.2, gcc_2.96 et cxx En 3.2 le seek from ::end semble marcher (voir Eval/COS/pbseekios.cc)

rz+cmv 11/2/2003

File size: 9.2 KB
RevLine 
[754]1//
[2322]2// $Id: datacards.cc,v 1.9 2003-02-11 15:31:05 cmv Exp $
[754]3//
4//
[1371]5// Eric Aubourg, R. Ansari 1995-2000
6// PEIDA (EROS) - SOPHYA
7// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
[754]8
[1371]9
[754]10#include "machdefs.h"
11#include "datacards.h"
12#include "pexceptions.h"
13#include <algorithm>
[2322]14#include <iostream>
15#include <iomanip>
[754]16#include <stdio.h>
17
18//++
19// Class DataCards
[1609]20// Lib SUtils
[754]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
[895]27
[754]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
[895]38/*!
39 \class SOPHYA::DataCards
[1609]40 \ingroup SUtils
[895]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 */
[754]50DataCards::DataCards()
51{
52}
53
[895]54/*! constructor with the specification of a parameter file */
[754]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
[895]79/*!
80 Adds a new processing function for all keywords matching the
81 specified pattern.
82 \param mtch : The pattern - can contain *
83*/
[754]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
[895]106/*! Resets the objects - Suppresses all cards */
107void DataCards::Clear()
[754]108{
109cards.erase(cards.begin(), cards.end());
110}
111
[895]112/*! Reads the file named \b fn. if fn=="" the value of \b SOPHYA_DATACARDS is used */
[754]113void
114DataCards::ReadFile(string const& fn)
115{
116 string file = fn;
117 if (file == "") {
[895]118 char * efn = getenv("SOPHYA_DATACARDS");
[754]119 if (efn != NULL) file = efn;
120 }
121 if (file == "") return;
122
123 try {
124 DoReadFile(file);
125 } catch(...) {
[895]126 char* wdp = getenv("SOPHYA_WORK");
[754]127 if (wdp) {
[895]128 cerr << "DataCards::ReadFile() Error reading file " << fn << " (Trying with SOPHYA_WORK) \n";
[754]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
[895]137/*! Appends a card, represented by the string \b crd to the list of cards */
[754]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
[895]191/*! Returns true if \b key is present in the list */
[754]192bool
[1258]193DataCards::HasKey(string const& key) const
[754]194{
[1258]195 return (FindKeyC(key) != cards.end());
[754]196}
197
[895]198//! Returns the total number of cards
[754]199int
[1258]200DataCards::NbCards() const
[754]201{
202return(cards.size());
203}
204
[895]205/*! Returns the number of parameters for card \b key. (-1) if \b key not present */
[754]206int
[1258]207DataCards::NbParam(string const& key) const
[754]208{
[1258]209 DataCards::CardList::const_iterator it = FindKeyC(key);
210 if (it == cards.end()) return(-1);
211 else return((*it).tokens.size());
[754]212}
213
[1258]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
[895]241/*! Returns the parameter number \b numero for card \b key */
[754]242string
[1258]243DataCards::SParam(string const& key, int numero, string def) const
[754]244{
[1258]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];
[754]249}
250
[895]251/*! Returns the parameter number \b numero for card \b key, converted to type long */
[754]252long
[1258]253DataCards::IParam(string const& key, int numero, long def) const
[754]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
[895]263/*! Returns the parameter number \b numero for card \b key, converted to type double */
[754]264double
[1258]265DataCards::DParam(string const& key, int numero, double def) const
[754]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
[895]276/*! Prints the list of cards on the output stream \b s */
277void
278DataCards::Print(ostream& s) const
[754]279{
[895]280 for (CardList::const_iterator i = cards.begin(); i != cards.end(); i++) {
[754]281 s << setw(10) << (*i).kw << " ";
[895]282 for (vector<string>::const_iterator j = (*i).tokens.begin(); j != (*i).tokens.end(); j++)
[754]283 s << (*j) << " ";
284 s << endl;
285 }
286}
287
[895]288/*! Reads the file named \b fn. */
289void
290DataCards::DoReadFile(string const& fn)
291{
[1197]292 char line_buff[512];
293 FILE *fip;
[754]294
[1197]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);
[895]301 }
[1197]302 fclose(fip);
303 return;
[895]304}
[754]305
[895]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 *
[1258]356DataCards::FindKey(string const& key)
[895]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++)
[1258]364 if ((*i).kw == key) return &(*i);
[895]365
366 return NULL;
367}
368
369
[1258]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.