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

Last change on this file since 3866 was 3572, checked in by cmv, 17 years ago

char* -> const char* pour regler les problemes de deprecated string const... + comparaison unsigned signed + suppression EVOL_PLANCK rz+cmv 07/02/2009

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