TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

qconfigDB.cc 74KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547
  1. /* the Configuration Database library, Version II
  2. the TDE addressbook
  3. $ Author: Mirko Boehm $
  4. $ Copyright: (C) 1996-2001, Mirko Boehm $
  5. $ Contact: mirko@kde.org
  6. http://www.kde.org $
  7. $ License: GPL with the following explicit clarification:
  8. This code may be linked against any version of the Qt toolkit
  9. from Troll Tech, Norway. $
  10. $Id$
  11. */
  12. #include "qconfigDB.h"
  13. // #include "debug.h"
  14. extern "C" {
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <signal.h>
  18. #include <unistd.h>
  19. #include <ctype.h>
  20. }
  21. // #include <tqstring.h>
  22. #include <tqtextstream.h>
  23. #include <tqfile.h>
  24. #include <tqtimer.h>
  25. #include <tqdatetime.h>
  26. #include <tqfileinfo.h>
  27. #include "qconfigDB.moc"
  28. #include <kdebug.h>
  29. #ifdef KAB_KDEBUG_AREA
  30. #undef KAB_KDEBUG_AREA
  31. #endif
  32. #define KAB_KDEBUG_AREA 800
  33. static bool isComment(TQCString line)
  34. {
  35. // ############################################################################
  36. line=line.stripWhiteSpace();
  37. if(line.isEmpty())
  38. {
  39. return false; // line is empty but not a comment
  40. } else {
  41. return(line[0]=='#');
  42. }
  43. // ############################################################################
  44. }
  45. static void tokenize(list<TQCString>& res, const TQCString& text, char tr, bool strict=false)
  46. {
  47. register bool GUARD; GUARD=false;
  48. // ############################################################################
  49. kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: called." << endl;
  50. int eins=0, zwei=0;
  51. TQCString teil;
  52. // -----
  53. kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: partening -->%" << text.data() << "<--." << endl;
  54. res.erase(res.begin(), res.end());
  55. // -----
  56. if(text.isEmpty())
  57. {
  58. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  59. "tokenize: text is an empty string, done." << endl;
  60. return;
  61. }
  62. while(zwei!=-1)
  63. {
  64. teil="";
  65. zwei=text.find(tr, eins);
  66. if(zwei!=-1)
  67. {
  68. teil=text.mid(eins, zwei-eins);
  69. res.push_back(teil);
  70. } else { // last element
  71. if(!strict) // nur wenn dazwischen Zeichen sind
  72. {
  73. teil=text.mid(eins, text.length()-eins);
  74. res.push_back(teil);
  75. }
  76. }
  77. eins=zwei+1;
  78. // if((unsigned)eins>=text.length()) break;
  79. }
  80. kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: partened in "
  81. << res.size() << " parts.\n";
  82. // -----
  83. kdDebug(GUARD, KAB_KDEBUG_AREA) << "tokenize: done." << endl;
  84. // ############################################################################
  85. }
  86. // TQCString AuthorEmailAddress; // assign your email address to this string
  87. static TQCString ReadLineFromStream(TQTextStream& stream)
  88. {
  89. register bool GUARD; GUARD=false;
  90. // ############################################################################
  91. kdDebug(GUARD, KAB_KDEBUG_AREA) << "ReadLineFromStream:: reading line." << endl;
  92. TQCString line;
  93. // -----
  94. while(!stream.eof())
  95. {
  96. line=stream.readLine().ascii();
  97. if(!line.isEmpty())
  98. {
  99. if(isComment(line))
  100. {
  101. line="";
  102. continue;
  103. }
  104. }
  105. break;
  106. }
  107. // -----
  108. kdDebug(GUARD, KAB_KDEBUG_AREA) << "ReadLineFromStream:: line \"" << line.data() << "\" read.\n";
  109. return line;
  110. // ############################################################################
  111. }
  112. // class implementations:
  113. list<TQString> QConfigDB::LockFiles; // the lockfiles created by this session
  114. KeyValueMap::KeyValueMap()
  115. : data(new StringStringMap)
  116. {
  117. // ###########################################################################
  118. // ###########################################################################
  119. }
  120. KeyValueMap::KeyValueMap(const KeyValueMap& orig)
  121. : data(new StringStringMap(*orig.data))
  122. {
  123. // ###########################################################################
  124. // ###########################################################################
  125. }
  126. KeyValueMap::~KeyValueMap()
  127. {
  128. // ###########################################################################
  129. delete data;
  130. // ###########################################################################
  131. }
  132. bool KeyValueMap::invariant()
  133. {
  134. return true;
  135. }
  136. StringStringMap::iterator KeyValueMap::begin()
  137. {
  138. return data->begin();
  139. }
  140. StringStringMap::iterator KeyValueMap::end()
  141. {
  142. return data->end();
  143. }
  144. unsigned int
  145. KeyValueMap::size() const
  146. {
  147. // ###########################################################################
  148. return data->size();
  149. // ###########################################################################
  150. }
  151. void
  152. KeyValueMap::clear()
  153. {
  154. register bool GUARD; GUARD=false;
  155. // ###########################################################################
  156. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  157. "KeyValueMap::clear: erasing map contents ... " << endl;
  158. // -----
  159. if(!data->empty()) // erase fails on empty containers!
  160. {
  161. data->erase(data->begin(), data->end());
  162. }
  163. // -----
  164. kdDebug(GUARD, KAB_KDEBUG_AREA) << "done." << endl;
  165. // ###########################################################################
  166. }
  167. bool
  168. KeyValueMap::fill(const TQString& filename, bool force, bool relax)
  169. {
  170. register bool GUARD; GUARD=false;
  171. // ###########################################################################
  172. TQFile file(filename);
  173. TQCString line;
  174. // -----
  175. if(file.open(IO_ReadOnly))
  176. {
  177. TQTextStream stream(&file);
  178. // We read/write utf8 strings, so we don't want that TQTextStream uses local8bit
  179. // Latin1 means : no conversion, when giving char*s to a TQTextStream. (DF)
  180. stream.setEncoding(TQTextStream::Latin1);
  181. // -----
  182. while(!stream.eof())
  183. {
  184. line=stream.readLine().ascii();
  185. if(!line.isEmpty() /* && !stream.eof() */ && !isComment(line))
  186. {
  187. if(!insertLine(line, force, relax, false))
  188. {
  189. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  190. "KeyValueMap::fill: could not insert line "
  191. << line << ".\n"; // ignore this case further
  192. }
  193. }
  194. }
  195. file.close();
  196. // -----
  197. return true;
  198. } else {
  199. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  200. "KeyValueMap::fill: cannot open file " <<
  201. filename << endl;
  202. return false;
  203. }
  204. // ###########################################################################
  205. }
  206. bool
  207. KeyValueMap::save(const TQString& filename, bool force)
  208. {
  209. register bool GUARD; GUARD=false;
  210. // ###########################################################################
  211. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  212. "KeyValueMap::save: saving data to -->" <<
  213. filename << "<--.\n";
  214. StringStringMap::iterator pos;
  215. TQFile file(filename);
  216. // ----- open file, regarding existence:
  217. if(!force)
  218. {
  219. if(file.exists())
  220. {
  221. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  222. "KeyValueMap::save: file exists but may not." << endl;
  223. return false;
  224. }
  225. }
  226. if(file.open(IO_WriteOnly))
  227. {
  228. TQTextStream stream(&file);
  229. stream.setEncoding(TQTextStream::Latin1); // no conversion
  230. stream << "# saved by KeyValueMap object ($Revision$)" << endl;
  231. for(pos=data->begin(); pos!=data->end(); ++pos)
  232. { // values do not get coded here
  233. stream << (*pos).first << '=' << (*pos).second << endl;
  234. }
  235. file.close();
  236. } else {
  237. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  238. "KeyValueMap::save: could not open file -->%s<-- for saving." <<
  239. filename.utf8() << endl;
  240. return false;
  241. }
  242. // ###########################################################################
  243. return true;
  244. }
  245. bool
  246. KeyValueMap::save(TQTextStream& file, int count)
  247. {
  248. register bool GUARD; GUARD=false;
  249. // ###########################################################################
  250. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  251. "KeyValueMap::save: saving data to given output stream." << endl;
  252. StringStringMap::iterator pos;
  253. bool ret=true;
  254. char* prefix=new char[count+1];
  255. memset(prefix, ' ', count);
  256. prefix[count]=0;
  257. // -----
  258. for(pos=data->begin(); pos!=data->end(); ++pos)
  259. {
  260. file << prefix << (*pos).first << '=' << (*pos).second << endl;
  261. }
  262. delete [] prefix;
  263. // -----
  264. return ret;
  265. // ###########################################################################
  266. }
  267. bool
  268. KeyValueMap::erase(const TQCString& key)
  269. {
  270. // ###########################################################################
  271. bool rc=(data->erase(key)>0);
  272. return rc;
  273. // ###########################################################################
  274. }
  275. bool
  276. KeyValueMap::empty()
  277. {
  278. // ###########################################################################
  279. return data->empty();
  280. // ###########################################################################
  281. }
  282. bool
  283. KeyValueMap::parseComplexString
  284. (const TQCString& orig,
  285. int index, // first char to parse
  286. TQCString& result, // string without leading and trailing ".."
  287. int& noOfChars) // no of chars that represented the
  288. const // complex string in the original
  289. {
  290. register bool GUARD; GUARD=false;
  291. // ###########################################################################
  292. int first;
  293. TQCString temp(2*orig.length());
  294. TQCString mod;
  295. int count=1;
  296. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  297. "KeyValueMap::parseComplexString: parsing the string -->"
  298. << orig << "<--.\n";
  299. // -----
  300. if(orig.isEmpty())
  301. {
  302. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  303. "KeyValueMap::parseComplexString: string is empty.\n"
  304. " "
  305. "This is no valid complex string." << endl;
  306. return false;
  307. }
  308. // ----- prepare the string:
  309. temp=orig.mid(index, orig.length()-index); // remove everything before index
  310. mod=temp.stripWhiteSpace(); // remove leading and trailing white spaces
  311. // ----- test some conditions:
  312. if(mod.length()<2)
  313. {
  314. kdDebug() << "KeyValueMap::parseComplexString: no pair of brackets " << endl;
  315. return false;
  316. }
  317. if(mod[0]!='"')
  318. {
  319. kdDebug() << "KeyValueMap::parseComplexString: no opening bracket." << endl;
  320. return false;
  321. }
  322. // ----- now parse it:
  323. first=1; // first character after opening bracket
  324. temp="";
  325. for(;;)
  326. {
  327. if(mod[first]=='\\')
  328. { // handle special characters
  329. ++first;
  330. kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::parseComplexString: found "
  331. "a special character \"%c\".", mod[first]) << endl;
  332. if((unsigned)first==mod.length())
  333. {
  334. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  335. "KeyValueMap::parseComplexString: "
  336. "string lacks the closing \".\n "
  337. " This is no valid "
  338. "complex string." << endl;
  339. return false;
  340. }
  341. switch(mod[first])
  342. {
  343. case 't': temp+='\t'; break;
  344. case 'n': temp+='\n'; break;
  345. case '"': temp+='"'; break;
  346. case 'e': temp+="\\e"; break;
  347. case '\\': temp+='\\'; break;
  348. default:
  349. // WORK_TO_DO: implement octal coding here!
  350. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::parseComplexString: "
  351. "invalid control character.\n "
  352. " This is no valid complex string." << endl;
  353. return false;
  354. }
  355. count+=2; // this took 2 characters
  356. ++first;
  357. } else { // it is a character
  358. ++count;
  359. if(mod[first]=='"') // end of coded string?
  360. {
  361. break;
  362. }
  363. temp+=mod[first];
  364. ++first;
  365. }
  366. if((unsigned)first>=mod.length())
  367. {
  368. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::parseComplexString: "
  369. "string lacks the closing \".\n "
  370. " This is no valid complex string.\n";
  371. return false;
  372. }
  373. }
  374. // -----
  375. kdDebug(GUARD, KAB_KDEBUG_AREA).form(
  376. "KeyValueMap::parseComplexString: finished parsing, no errors, "
  377. "%i characters, %i in string.", count, temp.length()) << endl;
  378. noOfChars=count;
  379. result=temp;
  380. // ###########################################################################
  381. return true;
  382. }
  383. TQCString
  384. KeyValueMap::makeComplexString(const TQCString& orig)
  385. {
  386. register bool GUARD; GUARD=false;
  387. // ###########################################################################
  388. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  389. "KeyValueMap::makeComplexString: coding the string\n -->"
  390. << orig <<
  391. "<--\n into a complex string.\n";
  392. TQCString temp(2*orig.length());
  393. unsigned int count;
  394. // -----
  395. temp+='"'; // opening bracket
  396. for(count=0; count<orig.length(); count++)
  397. {
  398. switch(orig[count])
  399. { // catch all special characters:
  400. case '"':
  401. kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::makeComplexString: "
  402. "found the special char \"%c\".", orig[count]) << endl;
  403. temp+='\\';
  404. temp+='"';
  405. break;
  406. case '\n':
  407. kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::makeComplexString: "
  408. "found the special char \"%c\".", orig[count]) << endl;
  409. temp+='\\';
  410. temp+='n';
  411. break;
  412. case '\t':
  413. kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::makeComplexString: "
  414. "found the special char \"%c\".", orig[count]) << endl;
  415. temp+='\\';
  416. temp+='t';
  417. break;
  418. case '\\':
  419. kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::makeComplexString: "
  420. "found the special char \"%c\".", orig[count]) << endl;
  421. temp+='\\';
  422. temp+='\\';
  423. break;
  424. default: temp+=orig[count];
  425. }
  426. }
  427. temp+='"'; // closing bracket
  428. // -----
  429. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  430. "KeyValueMap::makeComplexString: result is\n -->"
  431. <<temp<<"<--.\n";
  432. return temp;
  433. // ###########################################################################
  434. }
  435. bool
  436. KeyValueMap::getRaw(const TQCString& key, TQCString& value) const
  437. {
  438. register bool GUARD; GUARD=false;
  439. // ###########################################################################
  440. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  441. "KeyValueMap::getRaw: trying to get raw value for key \"" << key << "\" ...\n";
  442. StringStringMap::iterator pos=data->find(key);
  443. // -----
  444. if(pos==data->end())
  445. {
  446. kdDebug(GUARD, KAB_KDEBUG_AREA) << "not in KeyValueMap." << endl;
  447. return false;
  448. } else {
  449. value=(*pos).second;
  450. kdDebug(GUARD, KAB_KDEBUG_AREA) << "in KeyValueMap, value is "
  451. << value << endl;
  452. return true;
  453. }
  454. // ###########################################################################
  455. }
  456. bool
  457. KeyValueMap::insertRaw(const TQCString& key, const TQCString& value, bool force)
  458. {
  459. register bool GUARD; GUARD=false;
  460. // ###########################################################################
  461. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  462. "KeyValueMap::insertRaw: inserting uncoded value "
  463. << value <<
  464. " for key " << key << endl;
  465. int n=0;
  466. // -----
  467. if(key.isEmpty()) // empty KEYS are errors:
  468. {
  469. kdDebug() << "KeyValueMap::insertRaw: tried to insert empty key." << endl;
  470. return false;
  471. }
  472. if(force) // entry will be replaced
  473. {
  474. n=data->erase(key);
  475. }
  476. if(data->insert(StringStringMap::value_type(key, value)).second)
  477. {
  478. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insertRaw: success"
  479. << (n==0 ? "" : " (forced)") << endl;
  480. return true;
  481. } else {
  482. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insertRaw: failed, "
  483. "key already in KeyValueMap." << endl;
  484. return false;
  485. }
  486. // ###########################################################################
  487. }
  488. // -----------------------------------------------------------------------------
  489. // HUGE SEPARATOR BETWEEN INTERNAL LOGIC AND EXTENDABLE PAIRS OF GET- AND INSERT
  490. // -METHODS.
  491. // EXTENDABLE MEANS: OTHER DATATYPES CAN BE ADDED HERE.
  492. // -----------------------------------------------------------------------------
  493. /* The following functions are the pairs of insert-get-methods for different
  494. * data types. See keyvaluemap.h for the declarations. */
  495. // ascii strings:
  496. bool
  497. KeyValueMap::insert(const TQCString& key, const TQCString& value, bool force)
  498. {
  499. register bool GUARD; GUARD=false;
  500. // ###########################################################################
  501. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  502. "KeyValueMap::insert: inserting value\n -->"
  503. << value <<
  504. "<-- \""
  505. " for key\n -->"
  506. << key <<
  507. "<--.\n";
  508. return insertRaw(key, makeComplexString(value), force);
  509. // ###########################################################################
  510. }
  511. /* Attention:
  512. * This is another insert function that partens lines like "key=value"!
  513. * It is used for reading files and command line parameters easily.
  514. */
  515. bool
  516. KeyValueMap::insertLine(TQCString line, bool force, bool relax, bool encode)
  517. {
  518. register bool GUARD; GUARD=false;
  519. // ###########################################################################
  520. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  521. "KeyValueMap::insertLine: inserting line -->"<<line<<"<--.\n";
  522. int index;
  523. TQCString key;
  524. TQCString value;
  525. // ----- is the line empty or does it contain only whitespaces?
  526. uint len = line.length();
  527. for(index=0; isspace(line[index]) && (unsigned)index<len; ++index);
  528. if(line.isEmpty() || (unsigned)index==len)
  529. {
  530. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  531. "KeyValueMap::insertLine: line is empty." << endl;
  532. return false;
  533. }
  534. // -----
  535. index=line.find('=');
  536. if(index==-1) // not found
  537. {
  538. kdDebug() << "KeyValueMap::insertLine: no \"=\" found in \""<<line<<"\".\n";
  539. return false;
  540. }
  541. // -----
  542. key=line.mid(0, index); // copy from start to '='
  543. value=line.mid(index+1, line.length()-1-index); // copy the rest
  544. // ----- only alphanumerical characters are allowed in the keys:
  545. for(index=key.length()-1; index>-1; /* nothing */)
  546. {
  547. if(!(isalnum(key[index]) || ispunct(key[index])))
  548. {
  549. key=key.remove(index, 1); // WORK_TO_DO: optimize this (very slow)!
  550. }
  551. --index;
  552. }
  553. // ----- now insert it if key is still valid:
  554. if(!key.isEmpty() && (relax==true ? 1 : !value.isEmpty() ) )
  555. {
  556. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insertLine: done." << endl;
  557. if(encode)
  558. { // the usual way:
  559. return insert(key, value, force);
  560. } else { // while loading from a already coded file:
  561. return insertRaw(key, value, force);
  562. }
  563. } else {
  564. kdDebug() << "KeyValueMap::insertLine: key " << (relax ? "" : "or value ") << " is empty." << endl;
  565. return false;
  566. }
  567. // ###########################################################################
  568. }
  569. bool
  570. KeyValueMap::get(const TQCString& key, TQCString& value) const
  571. {
  572. register bool GUARD; GUARD=false;
  573. // ###########################################################################
  574. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[string]: "
  575. "trying to get value for key \"" << key << "\" ... " << endl;
  576. TQCString raw;
  577. TQCString temp;
  578. // -----
  579. if(!getRaw(key, raw))
  580. {
  581. return false; // key does not exist
  582. } else {
  583. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[string]: checking "
  584. "wether this is a complex string." << endl;
  585. {
  586. int count;
  587. if(parseComplexString(raw, 0, temp, count))
  588. {
  589. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  590. "KeyValueMap::get[string]: complex string found." << endl;
  591. value=temp;
  592. } else {
  593. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  594. "KeyValueMap::get[string]: this is no complex string." << endl;
  595. // disabled this strong check:
  596. // CHECK(false); // kill debug version
  597. return false;
  598. }
  599. }
  600. // ^^^^^^
  601. return true;
  602. }
  603. // ###########################################################################
  604. }
  605. // (^^^ ascii strings)
  606. // UNICODE strings:
  607. bool
  608. KeyValueMap::insert(const TQCString& key, const TQString& value, bool force)
  609. {
  610. register bool GUARD; GUARD=false;
  611. // ###########################################################################
  612. TQCString v;
  613. // -----
  614. v=value.utf8();
  615. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[QString]: trying to "
  616. "insert \"" << (!value.isNull() ? "true" : "false")
  617. << "\" for key\n -->"
  618. << v
  619. << "<--.\n";
  620. return insert(key, v, force);
  621. // ###########################################################################
  622. }
  623. bool
  624. KeyValueMap::get(const TQCString& key, TQString& value) const
  625. {
  626. register bool GUARD; GUARD=false;
  627. // ###########################################################################
  628. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QString]: trying to get "
  629. "a TQString value for key " << key << endl;
  630. TQCString v;
  631. // ----- get string representation:
  632. if(!get(key, v))
  633. {
  634. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QString]: key "
  635. << key << " not in KeyValueMap.\n";
  636. return false;
  637. }
  638. // ----- find its state:
  639. value=TQString::fromUtf8(v); // is there a better way?
  640. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QString]: success, value"
  641. " (in UTF8) is " << v << endl;
  642. return true;
  643. // ###########################################################################
  644. }
  645. // (^^^ UNICODE strings)
  646. // bool:
  647. bool
  648. KeyValueMap::insert(const TQCString& key, const bool& value, bool force)
  649. {
  650. register bool GUARD; GUARD=false;
  651. // ###########################################################################
  652. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[bool]: trying to "
  653. "insert \""
  654. << (value==true ? "true" : "false")
  655. <<"\" for key\n -->"
  656. << key << "<--.\n";
  657. return insert(key, value==true ? "true" : "false", force);
  658. // ###########################################################################
  659. }
  660. bool
  661. KeyValueMap::get(const TQCString& key, bool& value) const
  662. {
  663. register bool GUARD; GUARD=false;
  664. // ###########################################################################
  665. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[bool]: trying to get "
  666. "BOOL value for key " << key << endl;
  667. TQCString v;
  668. // ----- get string representation:
  669. if(!get(key, v))
  670. {
  671. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[bool]: key "
  672. << key << " not in KeyValueMap.";
  673. return false;
  674. }
  675. // ----- find its state:
  676. v=v.stripWhiteSpace();
  677. if(v=="true")
  678. {
  679. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[bool]: success, "
  680. "value is true." << endl;
  681. value=true;
  682. return true;
  683. }
  684. if(v=="false")
  685. {
  686. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[bool]: success, "
  687. "value is false." << endl;
  688. value=false;
  689. return true;
  690. }
  691. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  692. "KeyValueMap::get[bool]: failure, unknown value." << endl;
  693. // -----
  694. return false;
  695. // ###########################################################################
  696. }
  697. // (^^^ bool)
  698. // long:
  699. bool
  700. KeyValueMap::insert(const TQCString& key, const long& value, bool force)
  701. {
  702. register bool GUARD; GUARD=false;
  703. // ###########################################################################
  704. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[int]: trying to "
  705. "insert value \""<<value << "\" for key\n -->"<<key<<"<--.\n";
  706. TQCString temp;
  707. // -----
  708. temp.setNum(value);
  709. return insert(key, temp, force);
  710. // ###########################################################################
  711. }
  712. bool
  713. KeyValueMap::get(const TQCString& key, long& value) const
  714. {
  715. register bool GUARD; GUARD=false;
  716. // ###########################################################################
  717. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int]: trying to get "
  718. "INTEGER value for key " << key << endl;
  719. TQCString v;
  720. bool ok;
  721. long temp;
  722. // -----
  723. if(!get(key, v))
  724. {
  725. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int]: key "
  726. << key <<" not in KeyValueMap.\n";
  727. return false;
  728. }
  729. // -----
  730. temp=v.toLong(&ok);
  731. if(ok)
  732. {
  733. value=temp;
  734. return true;
  735. } else {
  736. return false;
  737. }
  738. // ###########################################################################
  739. }
  740. // (^^^ long)
  741. // long int lists:
  742. bool
  743. KeyValueMap::insert(const TQCString& key, const list<long>& values, bool force)
  744. {
  745. register bool GUARD; GUARD=false;
  746. // ###########################################################################
  747. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[long int list]: "
  748. "trying to insert long int list into map." << endl;
  749. TQCString temp;
  750. TQCString value;
  751. list<long>::const_iterator pos;
  752. // -----
  753. for(pos=values.begin(); pos!=values.end(); ++pos)
  754. {
  755. temp.setNum(*pos);
  756. value=value+temp+", ";
  757. }
  758. if(!value.isEmpty())
  759. { // remove last comma and space:
  760. value.remove(value.length()-2, 2);
  761. }
  762. // -----
  763. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[long int list]: "
  764. "constructed string value is " << value << endl;
  765. return insert(key, value, force);
  766. // ###########################################################################
  767. }
  768. bool
  769. KeyValueMap::get(const TQCString& key, list<long>& values) const
  770. {
  771. register bool GUARD; GUARD=false;
  772. // ###########################################################################
  773. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[long int list]: trying "
  774. "to decode int list for key " << key << endl;
  775. kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[long int list]"
  776. ": attention - list should be empty but is not.\n";
  777. TQCString value;
  778. list<TQCString> tokens;
  779. list<TQCString>::iterator pos;
  780. long temp;
  781. bool ok;
  782. // -----
  783. if(!get(key, value))
  784. {
  785. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  786. "KeyValueMap::get[long int list]: no such key." << endl;
  787. return false;
  788. }
  789. tokenize(tokens, value, ',');
  790. if(tokens.empty())
  791. {
  792. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  793. "KeyValueMap::get[long int list]: no tokens." << endl;
  794. return false;
  795. }
  796. // -----
  797. for(pos=tokens.begin(); pos!=tokens.end(); ++pos)
  798. {
  799. temp=(*pos).toLong(&ok);
  800. if(ok)
  801. {
  802. values.push_back(temp);
  803. } else {
  804. kdDebug() << "KeyValueMap::get[long int list]: conversion error for " << endl;
  805. }
  806. }
  807. // -----
  808. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[long int list]: done." << endl;
  809. // ###########################################################################
  810. return true;
  811. }
  812. // (^^^ long int lists)
  813. // int lists:
  814. bool
  815. KeyValueMap::insert(const TQCString& key, const list<int>& values, bool force)
  816. {
  817. register bool GUARD; GUARD=false;
  818. // ###########################################################################
  819. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[int list]: trying to "
  820. "insert int list into map." << endl;
  821. TQCString temp;
  822. TQCString value;
  823. list<int>::const_iterator pos;
  824. // -----
  825. for(pos=values.begin(); pos!=values.end(); ++pos)
  826. {
  827. temp.setNum(*pos);
  828. value=value+temp+", ";
  829. }
  830. if(!value.isEmpty())
  831. { // remove last comma and space:
  832. value.remove(value.length()-2, 2);
  833. }
  834. // -----
  835. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[int list]: "
  836. "constructed string value is " << value << endl;
  837. return insert(key, value, force);
  838. // ###########################################################################
  839. }
  840. bool
  841. KeyValueMap::get(const TQCString& key, list<int>& values) const
  842. {
  843. register bool GUARD; GUARD=false;
  844. // ###########################################################################
  845. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int list]: trying to "
  846. "decode int list for key " << key << endl;
  847. kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[int list]: "
  848. "attention - list should be empty but is not.\n";
  849. TQCString value;
  850. list<TQCString> tokens;
  851. list<TQCString>::iterator pos;
  852. int temp;
  853. bool ok;
  854. // -----
  855. if(!get(key, value))
  856. {
  857. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  858. "KeyValueMap::get[int list]: no such key." << endl;
  859. return false;
  860. }
  861. tokenize(tokens, value, ',');
  862. if(tokens.empty())
  863. {
  864. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  865. "KeyValueMap::get[int list]: no tokens." << endl;
  866. return false;
  867. }
  868. // -----
  869. for(pos=tokens.begin(); pos!=tokens.end(); ++pos)
  870. {
  871. temp=(*pos).toInt(&ok);
  872. if(ok)
  873. {
  874. values.push_back(temp);
  875. } else {
  876. kdDebug() << "KeyValueMap::get[int list]: conversion error for " << *pos << endl;
  877. }
  878. }
  879. // -----
  880. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[long int list]: done." << endl;
  881. // ###########################################################################
  882. return true;
  883. }
  884. // (^^^ int lists)
  885. // doubles:
  886. bool
  887. KeyValueMap::insert(const TQCString& key, const double& value, bool force)
  888. {
  889. register bool GUARD; GUARD=false;
  890. // ###########################################################################
  891. kdDebug(GUARD, KAB_KDEBUG_AREA).form("KeyValueMap::insert[double]: trying to "
  892. "insert value \"%f\" for key\n -->", value) << key << "<--.\n";
  893. TQCString temp;
  894. // -----
  895. temp.setNum(value);
  896. return insert(key, temp, force);
  897. // ###########################################################################
  898. }
  899. bool
  900. KeyValueMap::get(const TQCString& key, double& value) const
  901. {
  902. register bool GUARD; GUARD=false;
  903. // ###########################################################################
  904. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[double]: trying to get "
  905. "FLOAT value for key " << key << endl;
  906. TQCString v;
  907. bool ok;
  908. double temp;
  909. // -----
  910. if(!get(key, v))
  911. {
  912. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int]: key "
  913. <<key<<" not in "
  914. "KeyValueMap." << endl;
  915. return false;
  916. }
  917. // -----
  918. temp=v.toDouble(&ok);
  919. if(ok)
  920. {
  921. value=temp;
  922. return true;
  923. } else {
  924. return false;
  925. }
  926. // ###########################################################################
  927. }
  928. // (^^^ doubles)
  929. // lists of strings:
  930. bool
  931. KeyValueMap::get(const TQCString& key, list<TQCString>& values) const
  932. {
  933. register bool GUARD; GUARD=false;
  934. kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[string list]: "
  935. "attention!\n \"values\" list reference is not "
  936. "empty!" << endl;
  937. // ###########################################################################
  938. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[string list]: trying to "
  939. "decode string list for key " << key << endl;
  940. TQCString raw, part, value;
  941. int first=1, second=1, i;
  942. // ----- get the string value as a whole:
  943. if(!getRaw(key, raw))
  944. {
  945. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[list<string>]: key "
  946. << key << " not in KeyValueMap." << endl;
  947. return false;
  948. }
  949. // -----
  950. for(;;)
  951. { // ----- parten the string down into a list, find special characters:
  952. second=first;
  953. for(;;)
  954. {
  955. second=raw.find('\\', second);
  956. // ----- this may never be the last and also not the second last
  957. // character in a complex string:
  958. if(second!=-1)
  959. { // ----- check for string end:
  960. // we use "\e" as token for the string-delimiter
  961. if(raw[second+1]=='e' // the right character
  962. && raw[second-1]!='\\') // not escaped
  963. {
  964. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get"
  965. "[list<string>]: found string end at pos " <<
  966. second << endl;
  967. break;
  968. } else {
  969. ++second;
  970. }
  971. } else {
  972. break;
  973. }
  974. }
  975. if(second!=-1)
  976. {
  977. // ----- now second points to the end of the substring:
  978. part="\""+raw.mid(first, second-first)+"\"";
  979. // ----- insert decoded value into the list:
  980. if(parseComplexString(part, 0, value, i))
  981. {
  982. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get"
  983. "[list<string>]: found item " << value << endl;
  984. values.push_back(value);
  985. } else {
  986. kdDebug() << "KeyValueMap::get[list<string>]: parse error." << endl;
  987. return false;
  988. }
  989. if((unsigned)second<raw.length()-3)
  990. { // ----- there may be another string
  991. first=second+2;
  992. } else { // ----- we are completely finished
  993. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  994. "KeyValueMap::get[list<string>]: list end found." << endl;
  995. break;
  996. }
  997. } else { // ----- finished:
  998. break;
  999. }
  1000. }
  1001. // -----
  1002. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[list<string>]: done." << endl;
  1003. return true;
  1004. // ###########################################################################
  1005. }
  1006. bool
  1007. KeyValueMap::insert(const TQCString& key, const list<TQCString>& values, bool force)
  1008. {
  1009. register bool GUARD; GUARD=false;
  1010. // ###########################################################################
  1011. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[string list]: "
  1012. "coding string list." << endl;
  1013. TQCString value="\"";
  1014. TQCString temp;
  1015. list<TQCString>::const_iterator pos;
  1016. // ----- create coded string list:
  1017. for(pos=values.begin();
  1018. pos!=values.end();
  1019. pos++)
  1020. { // create strings like "abc\efgh\eijk":
  1021. temp=makeComplexString(*pos);
  1022. temp.remove(0, 1); // remove the leading "\""
  1023. temp.remove(temp.length()-1, 1); // the trailing "\""
  1024. value+=temp;
  1025. value+="\\e";
  1026. }
  1027. value+="\""; // finish the string
  1028. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[string list]: result "
  1029. "of coding is " << value << endl;
  1030. // ----- insert it without coding:
  1031. return insertRaw(key, value, force);
  1032. // ###########################################################################
  1033. }
  1034. // (^^^ lists of strings)
  1035. // QStrList-s:
  1036. bool
  1037. KeyValueMap::get(const TQCString& key, TQStrList& values) const
  1038. {
  1039. register bool GUARD; GUARD=false;
  1040. kdDebug(!values.isEmpty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: "
  1041. "attention!\n \"values\" list reference is not "
  1042. "empty!" << endl;
  1043. // ###########################################################################
  1044. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: trying to "
  1045. "decode string list for key " << key << endl;
  1046. TQCString raw, part, value;
  1047. int first=1, second=1, i;
  1048. // ----- get the string value as a whole:
  1049. if(!getRaw(key, raw))
  1050. {
  1051. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: key "
  1052. << key <<" not in KeyValueMap." << endl;
  1053. return false;
  1054. }
  1055. // -----
  1056. for(;;)
  1057. { // ----- parten the string down into a list, find special characters:
  1058. second=first;
  1059. for(;;)
  1060. {
  1061. second=raw.find('\\', second);
  1062. // ----- this may never be the last and also not the second last
  1063. // character in a complex string:
  1064. if(second!=-1)
  1065. { // ----- check for string end:
  1066. // we use "\e" as token for the string-delimiter
  1067. if(raw[second+1]=='e' // the right character
  1068. && raw[second-1]!='\\') // not escaped
  1069. {
  1070. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]:"
  1071. " found string end at pos %i." << second << endl;
  1072. break;
  1073. } else {
  1074. ++second;
  1075. }
  1076. } else {
  1077. break;
  1078. }
  1079. }
  1080. if(second!=-1)
  1081. {
  1082. // ----- now second points to the end of the substring:
  1083. part="\""+raw.mid(first, second-first)+"\"";
  1084. // ----- insert decoded value into the list:
  1085. if(parseComplexString(part, 0, value, i))
  1086. {
  1087. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: "
  1088. "found item " << value << endl;
  1089. values.append(value);
  1090. } else {
  1091. kdDebug() << "KeyValueMap::get[QStrList]: parse error." << endl;
  1092. return false;
  1093. }
  1094. if((unsigned)second<raw.length()-3)
  1095. { // ----- there may be another string
  1096. first=second+2;
  1097. } else { // ----- we are completely finished
  1098. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: "
  1099. "list end found." << endl;
  1100. break;
  1101. }
  1102. } else { // ----- finished:
  1103. break;
  1104. }
  1105. }
  1106. // -----
  1107. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStrList]: done." << endl;
  1108. return true;
  1109. // ###########################################################################
  1110. }
  1111. bool
  1112. KeyValueMap::insert(const TQCString& key, const TQStrList& values, bool force)
  1113. {
  1114. register bool GUARD; GUARD=false;
  1115. // ###########################################################################
  1116. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1117. "KeyValueMap::insert[QStrList]: coding string list." << endl;
  1118. TQCString value="\"";
  1119. TQCString temp;
  1120. unsigned int count;
  1121. // ----- create coded string list:
  1122. for(count=0; count<values.count(); ++count)
  1123. { // create strings like "abc\efgh\eijk":
  1124. temp=makeComplexString(((TQStrList)values).at(count));
  1125. temp.remove(0, 1); // remove the leading "\""
  1126. temp.remove(temp.length()-1, 1); // the trailing "\""
  1127. value+=temp;
  1128. value+="\\e";
  1129. }
  1130. value+="\""; // finish the string
  1131. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1132. "KeyValueMap::insert[QStrList]: result of coding is %s." <<
  1133. value << endl;
  1134. // ----- insert it without coding:
  1135. return insertRaw(key, value, force);
  1136. // ###########################################################################
  1137. }
  1138. // (^^^ QStrList-s)
  1139. // QStringList-s:
  1140. bool
  1141. KeyValueMap::get(const TQCString& key, TQStringList& values) const
  1142. {
  1143. register bool GUARD; GUARD=false;
  1144. kdDebug(!values.isEmpty(), KAB_KDEBUG_AREA) << "KeyValueMap::get"
  1145. "[QStringList]: attention!\n \"values\" list reference"
  1146. " is not empty!" << endl;
  1147. // ###########################################################################
  1148. /* The values are stored in a utf8-coded set of QCStrings.
  1149. This list is retrieved and converted back to Unicode strings. */
  1150. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStringList]: trying to "
  1151. "decode TQStringList for key " << key << endl;
  1152. TQStrList temp;
  1153. unsigned int count;
  1154. // ----- get the plain C strings:
  1155. if(!get(key, temp))
  1156. {
  1157. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStringList]: key "
  1158. << key <<
  1159. " not in KeyValueMap." << endl;
  1160. return false;
  1161. }
  1162. // ----- do the conversion:
  1163. for(count=0; count<temp.count(); ++count)
  1164. {
  1165. values.append(TQString::fromUtf8(temp.at(count)));
  1166. }
  1167. // -----
  1168. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QStringList]: done." << endl;
  1169. return true;
  1170. // ###########################################################################
  1171. }
  1172. bool
  1173. KeyValueMap::insert(const TQCString& key, const TQStringList& values, bool force)
  1174. {
  1175. register bool GUARD; GUARD=false;
  1176. // ###########################################################################
  1177. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1178. "KeyValueMap::insert[QStringList]: coding TQStringList." << endl;
  1179. // The method simply creates a list of utf8-coded strings and inserts it.
  1180. TQStrList utf8strings;
  1181. unsigned int count;
  1182. // ----- create TQCString list:
  1183. for(count=0; count<values.count(); ++count)
  1184. {
  1185. utf8strings.append((*values.at(count)).utf8());
  1186. }
  1187. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[QStringList]: done." << endl;
  1188. return insert(key, utf8strings, force);
  1189. // ###########################################################################
  1190. }
  1191. // (^^^ QStringList-s)
  1192. // lists of doubles:
  1193. bool
  1194. KeyValueMap::insert(const TQCString& key, const list<double>& values, bool force)
  1195. {
  1196. register bool GUARD; GUARD=false;
  1197. // ###########################################################################
  1198. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[double list]: trying "
  1199. "to insert double list into map." << endl;
  1200. TQCString buffer;
  1201. // TQCString value(30*values.size()); // not usable with Qt 2
  1202. TQCString value; // WORK_TO_DO: how to reserve enough space to avoid growing?
  1203. list<double>::const_iterator pos;
  1204. // -----
  1205. for(pos=values.begin(); pos!=values.end(); ++pos)
  1206. {
  1207. buffer.setNum(*pos);
  1208. value=value+buffer+", ";
  1209. }
  1210. if(!value.isEmpty())
  1211. { // remove last comma and space:
  1212. value.remove(value.length()-2, 2);
  1213. }
  1214. // -----
  1215. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[double list]: "
  1216. "constructed string value is " << value << endl;
  1217. return insert(key, value, force);
  1218. // ###########################################################################
  1219. }
  1220. bool
  1221. KeyValueMap::get(const TQCString& key, list<double>& values) const
  1222. {
  1223. register bool GUARD; GUARD=false;
  1224. // ###########################################################################
  1225. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[double list]: trying to "
  1226. "decode double list for key " << key << endl;
  1227. kdDebug(!values.empty(), KAB_KDEBUG_AREA) << "KeyValueMap::get[double list]: "
  1228. "attention - list should be empty but is not." << endl;
  1229. TQCString value;
  1230. list<TQCString> tokens;
  1231. list<TQCString>::iterator pos;
  1232. double temp;
  1233. bool ok;
  1234. // -----
  1235. if(!get(key, value))
  1236. {
  1237. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1238. "KeyValueMap::get[double list]: no such key." << endl;
  1239. return false;
  1240. }
  1241. // -----
  1242. tokenize(tokens, value, ',');
  1243. for(pos=tokens.begin(); pos!=tokens.end(); ++pos)
  1244. {
  1245. temp=(*pos).toDouble(&ok);
  1246. if(ok)
  1247. {
  1248. values.push_back(temp);
  1249. } else {
  1250. kdDebug() << "KeyValueMap::get[double list]: conversion error for "
  1251. << *pos << endl;
  1252. }
  1253. }
  1254. // -----
  1255. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[int list]: done." << endl;
  1256. // ###########################################################################
  1257. return true;
  1258. }
  1259. // (^^^ lists of doubles)
  1260. // QDates:
  1261. bool
  1262. KeyValueMap::insert(const TQCString& key, const TQDate& value, bool force)
  1263. {
  1264. register bool GUARD; GUARD=false;
  1265. // ###########################################################################
  1266. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[QDate]: trying to "
  1267. "insert TQDate into map." << endl;
  1268. list<long> values;
  1269. // -----
  1270. if(!value.isValid())
  1271. {
  1272. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::insert[QDate]: invalid "
  1273. "date, inserting a null date." << endl;
  1274. for(int i=0; i<3; ++i) values.push_back(0);
  1275. } else {
  1276. values.push_back(value.year());
  1277. values.push_back(value.month());
  1278. values.push_back(value.day());
  1279. }
  1280. // -----
  1281. return insert(key, values, force);
  1282. // ###########################################################################
  1283. }
  1284. bool
  1285. KeyValueMap::get(const TQCString& key, TQDate& date) const
  1286. {
  1287. register bool GUARD; GUARD=false;
  1288. // ###########################################################################
  1289. kdDebug(GUARD, KAB_KDEBUG_AREA) << "KeyValueMap::get[QDate]: trying to decode"
  1290. " TQDate for key " << key << endl;
  1291. list<long> values;
  1292. long y, m, d;
  1293. TQDate temp;
  1294. // -----
  1295. if(!get(key, values))
  1296. {
  1297. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1298. "KeyValueMap::get[QDate]: no such key." << endl;
  1299. return false;
  1300. }
  1301. if(values.size()!=3)
  1302. {
  1303. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1304. "KeyValueMap::get[QDate]: more or less than 3 values." << endl;
  1305. return false;
  1306. }
  1307. y=values.front(); values.pop_front();
  1308. m=values.front(); values.pop_front();
  1309. d=values.front();
  1310. // -----
  1311. if(y!=0 || m!=0 || d!=0) temp.setYMD(y, m, d); // avoid TQDate messages
  1312. if(!temp.isValid() && !temp.isNull())
  1313. {
  1314. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1315. "KeyValueMap::get[QDate]: no valid date." << endl;
  1316. return false;
  1317. } else {
  1318. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1319. "KeyValueMap::get[QDate]: done." << endl;
  1320. date=temp;
  1321. return true;
  1322. }
  1323. // ###########################################################################
  1324. }
  1325. // (^^^ QDates)
  1326. // Section class:
  1327. const int Section::indent_width=2;
  1328. Section::Section()
  1329. {
  1330. // ###########################################################################
  1331. // ###########################################################################
  1332. }
  1333. Section::Section(const KeyValueMap& contents)
  1334. {
  1335. // ###########################################################################
  1336. keys=contents;
  1337. // ###########################################################################
  1338. }
  1339. bool
  1340. Section::add(const TQCString& name)
  1341. {
  1342. register bool GUARD; GUARD=false;
  1343. // ###########################################################################
  1344. kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::add: adding section \""
  1345. <<name<<"\" to "
  1346. "this section ..." << endl;
  1347. Section* section;
  1348. bool rc;
  1349. // -----
  1350. if(name.isEmpty())
  1351. {
  1352. kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::add: empty key." << endl;
  1353. return false;
  1354. }
  1355. section=new Section; // create an empty section
  1356. if(section==0)
  1357. {
  1358. kdDebug() << "Section::add: out of memory." << endl;
  1359. return false;
  1360. }
  1361. rc=add(name, section);
  1362. if(!rc)
  1363. {
  1364. kdDebug(GUARD && !rc, KAB_KDEBUG_AREA) << " failed.\n";
  1365. delete section;
  1366. return false;
  1367. } else {
  1368. kdDebug(GUARD && rc, KAB_KDEBUG_AREA) << " success.\n";
  1369. return true;
  1370. }
  1371. // ###########################################################################
  1372. }
  1373. bool
  1374. Section::add(const TQCString& name, Section* section)
  1375. {
  1376. register bool GUARD; GUARD=false;
  1377. // ###########################################################################
  1378. if(sections.insert(StringSectionMap::value_type(name, section)).second)
  1379. {
  1380. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1381. "Section::add: added section "<<name<<" successfully.\n";
  1382. return true;
  1383. } else {
  1384. kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::add: failed to add section "
  1385. << name << ", section already exists.\n";
  1386. return false;
  1387. }
  1388. // ###########################################################################
  1389. }
  1390. bool
  1391. Section::find(const TQCString& name, StringSectionMap::iterator& result)
  1392. {
  1393. register bool GUARD; GUARD=false;
  1394. // ###########################################################################
  1395. kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::find: trying to get section "
  1396. "\""<<name<<"\" ... \n";
  1397. StringSectionMap::iterator pos;
  1398. // -----
  1399. pos=sections.find(name);
  1400. if(pos==sections.end())
  1401. {
  1402. kdDebug(GUARD, KAB_KDEBUG_AREA) << "failed, no such section." << endl;
  1403. return false;
  1404. } else {
  1405. kdDebug(GUARD, KAB_KDEBUG_AREA) << "success." << endl;
  1406. result=pos;
  1407. return true;
  1408. }
  1409. // ###########################################################################
  1410. }
  1411. bool
  1412. Section::remove(const TQCString& name)
  1413. {
  1414. // ###########################################################################
  1415. StringSectionMap::iterator pos;
  1416. // -----
  1417. if(!find(name, pos))
  1418. {
  1419. return false; // no such section
  1420. } else {
  1421. sections.erase(pos);
  1422. return true;
  1423. }
  1424. // ###########################################################################
  1425. }
  1426. bool
  1427. Section::find(const TQCString& name, Section*& section)
  1428. {
  1429. // ###########################################################################
  1430. StringSectionMap::iterator pos;
  1431. // -----
  1432. if(!find(name, pos))
  1433. {
  1434. return false;
  1435. } else {
  1436. section=(*pos).second;
  1437. return true;
  1438. }
  1439. // ###########################################################################
  1440. }
  1441. KeyValueMap*
  1442. Section::getKeys()
  1443. {
  1444. // ###########################################################################
  1445. return &keys;
  1446. // ###########################################################################
  1447. }
  1448. void
  1449. Section::insertIndentSpace(TQTextStream& file, int level)
  1450. {
  1451. // ###########################################################################
  1452. int i, j;
  1453. // -----
  1454. for(i=0; i<level; i++)
  1455. {
  1456. for(j=0; j<indent_width; j++)
  1457. file << ' ';
  1458. }
  1459. // ###########################################################################
  1460. }
  1461. bool
  1462. Section::save(TQTextStream& stream, int level)
  1463. {
  1464. register bool GUARD; GUARD=false;
  1465. // ###########################################################################
  1466. StringSectionMap::iterator pos;
  1467. // -----
  1468. if(!sections.empty())
  1469. { // ----- insert a comment:
  1470. insertIndentSpace(stream, level);
  1471. stream << "# subsections:" << endl;
  1472. }
  1473. for(pos=sections.begin(); pos!=sections.end(); ++pos)
  1474. {
  1475. insertIndentSpace(stream, level);
  1476. stream << '[' << (*pos).first << ']' << endl;
  1477. if(!(*pos).second->save(stream, level+1))
  1478. {
  1479. kdDebug() << "Section::save: error saving child section \"" << (*pos).first.data() << "\"." << endl;
  1480. return false;
  1481. } else {
  1482. kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::save: saved section \""
  1483. << (*pos).first
  1484. << "\".\n";
  1485. }
  1486. insertIndentSpace(stream, level);
  1487. stream << "[END " << (*pos).first << ']' << endl;
  1488. }
  1489. if(!keys.empty())
  1490. {
  1491. insertIndentSpace(stream, level);
  1492. stream << "# key-value-pairs:" << endl;
  1493. if(!keys.save(stream, level*indent_width))
  1494. {
  1495. kdDebug() << "Section::save: error saving key-value-pairs." << endl;
  1496. return false;
  1497. }
  1498. }
  1499. // -----
  1500. return true;
  1501. // ###########################################################################
  1502. }
  1503. bool
  1504. Section::readSection(TQTextStream& file, bool finish)
  1505. {
  1506. register bool GUARD; GUARD=false;
  1507. // ###########################################################################
  1508. kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::readSection: reading section." << endl;
  1509. TQCString line;
  1510. TQCString name;
  1511. Section* temp;
  1512. // -----
  1513. for(;;)
  1514. {
  1515. line="";
  1516. line=ReadLineFromStream(file);
  1517. if(isEndOfSection(line))
  1518. { // ----- eof does not matter:
  1519. return true;
  1520. } else { // ----- verify it:
  1521. if(file.eof())
  1522. {
  1523. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1524. "Section::readSection: EOF, line is \""<<line<<"\".\n";
  1525. if(!line.isEmpty())
  1526. {
  1527. if(!keys.insertLine(line, false, true, false))
  1528. {
  1529. kdWarning() << "Attention: unable to parse key-value-pair "
  1530. << endl << "\t\"" << line << "\"," << endl
  1531. << "ignoring and continuing (maybe duplicate "
  1532. << "declaration of the key)."
  1533. << endl;
  1534. }
  1535. }
  1536. if(finish==true)
  1537. {
  1538. kdDebug() << "Section::readSection: missing end of section." << endl;
  1539. return false;
  1540. } else {
  1541. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1542. "Section::readSection: EOF (no error)." << endl;
  1543. return true;
  1544. }
  1545. }
  1546. }
  1547. if(isBeginOfSection(line))
  1548. {
  1549. name=nameOfSection(line);
  1550. add(name);
  1551. find(name, temp);
  1552. if(!temp->readSection(file))
  1553. {
  1554. kdDebug() << "Section::readSection: unable to read "
  1555. "subsection \"" << name << "\".\n";
  1556. return false;
  1557. }
  1558. } else { // ----- it has to be a key-value-pair:
  1559. if(!keys.insertLine(line, false, true, false))
  1560. {
  1561. kdWarning() << "Attention: unable to parse key-value-pair " << endl
  1562. << "\t\"" << line << "\"," << endl
  1563. << "ignoring and continuing (maybe duplicate declaration of"
  1564. << " the key)."
  1565. << endl;
  1566. }
  1567. }
  1568. }
  1569. // ###########################################################################
  1570. }
  1571. bool
  1572. Section::isBeginOfSection(TQCString line)
  1573. {
  1574. register bool GUARD; GUARD=false;
  1575. // ###########################################################################
  1576. line=line.simplifyWhiteSpace();
  1577. if(line.isEmpty() || line.length()<2)
  1578. {
  1579. kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::isBeginOfSection: too short "
  1580. "or empty line." << endl;
  1581. return false;
  1582. }
  1583. if(line[0]!='[' || line[line.length()-1]!=']')
  1584. {
  1585. return false;
  1586. }
  1587. // -----
  1588. if(line.contains("END"))
  1589. {
  1590. return false;
  1591. } else {
  1592. return true;
  1593. }
  1594. // ###########################################################################
  1595. }
  1596. bool
  1597. Section::isEndOfSection(TQCString line)
  1598. {
  1599. register bool GUARD; GUARD=false;
  1600. // ###########################################################################
  1601. kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::isEndOfSection: is "
  1602. << line <<" the end of"
  1603. " a section?" << endl;
  1604. int first=1, second;
  1605. TQCString temp;
  1606. // -----
  1607. line=line.simplifyWhiteSpace();
  1608. if(line.isEmpty() || line.length()<2)
  1609. {
  1610. kdDebug(GUARD, KAB_KDEBUG_AREA) << "Section::isBeginOfSection: too short "
  1611. "or empty line." << endl;
  1612. return false;
  1613. }
  1614. if(line[0]!='[' || line[line.length()-1]!=']')
  1615. {
  1616. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1617. "Section::isBeginOfSection: does not match." << endl;
  1618. return false;
  1619. }
  1620. // ----- find the word inside the brackets:
  1621. for(first=1; line[first]==' '; ++first); // find first non-whitespace character
  1622. for(second=first; line[second]!=' ' && line[second]!=']'; ++second);
  1623. temp=line.mid(first, second-first);
  1624. if(temp=="END")
  1625. {
  1626. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1627. "Section::isBeginOfSection: yes, it is." << endl;
  1628. return true;
  1629. } else {
  1630. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1631. "Section::isBeginOfSection: no, it is not." << endl;
  1632. return false;
  1633. }
  1634. // ###########################################################################
  1635. }
  1636. TQCString
  1637. Section::nameOfSection(const TQCString& line)
  1638. {
  1639. register bool GUARD; GUARD=false;
  1640. // ###########################################################################
  1641. int first=1, second;
  1642. TQCString temp;
  1643. // -----
  1644. temp=line.simplifyWhiteSpace();
  1645. if(temp.isEmpty() || temp.length()<=2)
  1646. { // empty section names are not allowed
  1647. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1648. "Section::isBeginOfSection: too short or empty line." << endl;
  1649. return "";
  1650. }
  1651. if(temp[0]!='[' || temp[temp.length()-1]!=']')
  1652. {
  1653. return "";
  1654. }
  1655. // ----- find the word inside the brackets:
  1656. for(first=1; temp[first]==' '; ++first); // find first non-whitespace character
  1657. for(second=first; temp[second]!=' ' && temp[second]!=']'; ++second);
  1658. temp=temp.mid(first, second-first);
  1659. if(temp=="END")
  1660. {
  1661. return "";
  1662. } else {
  1663. return temp;
  1664. }
  1665. // ###########################################################################
  1666. }
  1667. bool
  1668. Section::clear()
  1669. {
  1670. // ###########################################################################
  1671. StringSectionMap::iterator pos;
  1672. // -----
  1673. for(pos=sections.begin(); pos!=sections.end(); ++pos)
  1674. {
  1675. if(!(*pos).second->clear()) return false;
  1676. delete(*pos).second;
  1677. }
  1678. // sections.clear(); // seems to be not implemented
  1679. sections.erase(sections.begin(), sections.end());
  1680. keys.clear();
  1681. // -----
  1682. return true;
  1683. // ###########################################################################
  1684. }
  1685. bool
  1686. Section::empty()
  1687. {
  1688. // ###########################################################################
  1689. return keys.empty() && sections.empty();
  1690. // ###########################################################################
  1691. }
  1692. Section::StringSectionMap::iterator
  1693. Section::sectionsBegin()
  1694. {
  1695. // ###########################################################################
  1696. return sections.begin();
  1697. // ###########################################################################
  1698. }
  1699. Section::StringSectionMap::iterator
  1700. Section::sectionsEnd()
  1701. {
  1702. // ###########################################################################
  1703. return sections.end();
  1704. // ###########################################################################
  1705. }
  1706. unsigned int
  1707. Section::noOfSections()
  1708. {
  1709. // ###########################################################################
  1710. return sections.size();
  1711. // ###########################################################################
  1712. }
  1713. QConfigDB::QConfigDB(TQWidget* parent, const char* name)
  1714. : TQWidget(parent, name),
  1715. timer(0),
  1716. readonly(true),
  1717. locked(false),
  1718. mtime(new TQDateTime)
  1719. {
  1720. // ###########################################################################
  1721. hide();
  1722. // ###########################################################################
  1723. }
  1724. QConfigDB::~QConfigDB()
  1725. {
  1726. // ############################################################################
  1727. // disconnect();
  1728. // -----
  1729. if(timer!=0)
  1730. {
  1731. delete timer; timer=0;
  1732. }
  1733. if(!clear()) // this will emit changed() a last time
  1734. {
  1735. kdDebug() << "QConfigDB destructor: cannot remove me." << endl;
  1736. }
  1737. if(locked)
  1738. {
  1739. unlock();
  1740. }
  1741. // ############################################################################
  1742. }
  1743. bool QConfigDB::invariant()
  1744. {
  1745. return true;
  1746. }
  1747. bool
  1748. QConfigDB::get(const list<TQCString>& key, KeyValueMap*& map)
  1749. {
  1750. register bool GUARD; GUARD=false;
  1751. // ############################################################################
  1752. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::get: trying to get keys ... " << endl;
  1753. Section* section=&top;
  1754. list<TQCString>::const_iterator pos;
  1755. // -----
  1756. if(key.empty())
  1757. {
  1758. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1759. "ConfigDB::get: path is empty, returning toplevel section." << endl;
  1760. map=top.getKeys();
  1761. return true;
  1762. }
  1763. for(pos=key.begin(); pos!=key.end(); ++pos)
  1764. {
  1765. if(!section->find(*pos, section))
  1766. {
  1767. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1768. "failed,\n at least the element \""
  1769. << *pos <<
  1770. "\" of "
  1771. "the key-list is not declared." << endl;
  1772. return false;
  1773. }
  1774. }
  1775. // -----
  1776. map=section->getKeys();
  1777. kdDebug(GUARD, KAB_KDEBUG_AREA) << "success." << endl;
  1778. return true;
  1779. // ############################################################################
  1780. }
  1781. KeyValueMap*
  1782. QConfigDB::get()
  1783. {
  1784. // ############################################################################
  1785. return top.getKeys();
  1786. // ############################################################################
  1787. }
  1788. bool
  1789. QConfigDB::createSection(const list<TQCString>& key)
  1790. {
  1791. // ############################################################################
  1792. Section* section=&top;
  1793. unsigned int index;
  1794. list<TQCString>::const_iterator pos;
  1795. Section* thenewone;
  1796. bool rc;
  1797. // -----
  1798. pos=key.begin();
  1799. for(index=0; index<key.size()-1; index++)
  1800. {
  1801. if(!section->find(*pos, section))
  1802. { // this section is not declared
  1803. Section* temp=new Section; // WORK_TO_DO: memory hole?
  1804. if(section->add(*pos, temp))
  1805. {
  1806. section=temp;
  1807. } else {
  1808. delete temp;
  1809. return false;
  1810. }
  1811. }
  1812. ++pos;
  1813. }
  1814. // pos now points to the last element of key,
  1815. // section to the parent of the section that will be inserted
  1816. thenewone=new Section;
  1817. rc=section->add(*pos, thenewone);
  1818. return rc; // missing error report! WORK_TO_DO
  1819. // ############################################################################
  1820. }
  1821. bool
  1822. QConfigDB::clear()
  1823. {
  1824. // ############################################################################
  1825. bool rc=top.clear();
  1826. emit(changed(this));
  1827. return rc;
  1828. // ############################################################################
  1829. }
  1830. bool
  1831. QConfigDB::empty()
  1832. {
  1833. // ############################################################################
  1834. return top.empty();
  1835. // ############################################################################
  1836. }
  1837. bool
  1838. QConfigDB::createSection(const TQCString& desc)
  1839. {
  1840. // ############################################################################
  1841. return createSection(stringToKeylist(desc));
  1842. // ############################################################################
  1843. }
  1844. bool
  1845. QConfigDB::get(const TQCString& key, KeyValueMap*& map)
  1846. {
  1847. // ############################################################################
  1848. return get(stringToKeylist(key), map);
  1849. // ############################################################################
  1850. }
  1851. list<TQCString>
  1852. QConfigDB::stringToKeylist(const TQCString& desc)
  1853. {
  1854. register bool GUARD; GUARD=false;
  1855. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::stringToKeylist: parsing path " << desc << endl;
  1856. // ############################################################################
  1857. list<TQCString> key;
  1858. int first=0, second;
  1859. TQCString temp;
  1860. // -----
  1861. if(desc.isEmpty())
  1862. {
  1863. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1864. "QConfigDB::stringToKeylist: path is empty." << endl;
  1865. return key;
  1866. }
  1867. for(;;)
  1868. {
  1869. second=desc.find('/', first);
  1870. if(second==-1)
  1871. {
  1872. if((unsigned)first<desc.length()+1)
  1873. {
  1874. temp=desc.mid(first, desc.length()-first);
  1875. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1876. "QConfigDB::stringToKeylist: found last part "
  1877. << temp << endl;
  1878. key.push_back(temp);
  1879. }
  1880. break;
  1881. }
  1882. temp=desc.mid(first, second-first);
  1883. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1884. "QConfigDB::stringToKeylist: found part " << temp << endl;
  1885. key.push_back(temp);
  1886. first=second+1;
  1887. }
  1888. // -----
  1889. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::stringToKeylist: done." << endl;
  1890. return key;
  1891. // ############################################################################
  1892. }
  1893. bool
  1894. QConfigDB::get(const TQCString& key, Section*& section)
  1895. {
  1896. // ############################################################################
  1897. return get(stringToKeylist(key), section);
  1898. // ############################################################################
  1899. }
  1900. bool
  1901. QConfigDB::get(const list<TQCString>& key, Section*& section)
  1902. {
  1903. register bool GUARD; GUARD=false;
  1904. // ############################################################################
  1905. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::get: searching section ... " << endl;
  1906. Section* temp=&top;
  1907. list<TQCString>::const_iterator pos;
  1908. // -----
  1909. for(pos=key.begin(); pos!=key.end(); ++pos)
  1910. {
  1911. if(!temp->find(*pos, temp))
  1912. {
  1913. kdDebug(GUARD, KAB_KDEBUG_AREA) << "failure, no such section.";
  1914. return false;
  1915. }
  1916. }
  1917. // -----
  1918. section=temp;
  1919. kdDebug(GUARD, KAB_KDEBUG_AREA) << "success, section found." << endl;
  1920. return true;
  1921. // ############################################################################
  1922. }
  1923. bool
  1924. QConfigDB::isRO()
  1925. {
  1926. // ############################################################################
  1927. return readonly;
  1928. // ############################################################################
  1929. }
  1930. int
  1931. QConfigDB::IsLocked(const TQString& file)
  1932. {
  1933. register bool GUARD; GUARD=false;
  1934. // ############################################################################
  1935. TQString lockfile=file+".lock";
  1936. int pid=-1;
  1937. // -----
  1938. if(access(TQFile::encodeName(lockfile), F_OK)==0)
  1939. {
  1940. TQFile f(lockfile);
  1941. // -----
  1942. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::IsLocked: the file\n"
  1943. << file <<
  1944. "\nhas a lockfile.\n";
  1945. if(f.open(IO_ReadOnly))
  1946. {
  1947. TQTextStream stream(&f);
  1948. stream.setEncoding(TQTextStream::Latin1); // no conversion
  1949. // -----
  1950. stream >> pid;
  1951. if(pid==-1)
  1952. {
  1953. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::IsLocked: the file "
  1954. "does not contain the ID\n of the process that "
  1955. "created it." << endl;
  1956. return -1;
  1957. }
  1958. f.close();
  1959. } else {
  1960. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  1961. "QConfigDB::IsLocked: cannot open the lockfile." << endl;
  1962. return -1;
  1963. }
  1964. return pid;
  1965. } else {
  1966. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::IsLocked: the file\n"
  1967. << file << "\nhas no lockfile.\n";
  1968. return 0;
  1969. }
  1970. // ############################################################################
  1971. }
  1972. bool
  1973. QConfigDB::lock()
  1974. {
  1975. register bool GUARD; GUARD=false;
  1976. // ############################################################################
  1977. if(locked)
  1978. {
  1979. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock (current file): file "
  1980. "is already locked by this object." << endl;
  1981. return false;
  1982. }
  1983. if(lock(filename))
  1984. {
  1985. locked=true;
  1986. return true;
  1987. } else {
  1988. return false;
  1989. }
  1990. // ############################################################################
  1991. }
  1992. bool
  1993. QConfigDB::lock(const TQString& file)
  1994. {
  1995. register bool GUARD; GUARD=false;
  1996. // ############################################################################
  1997. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock: locking the file "
  1998. << file << endl;
  1999. TQString lockfile=file+".lock";
  2000. TQFile f(lockfile);
  2001. // -----
  2002. if(access(TQFile::encodeName(lockfile), F_OK)==0)
  2003. {
  2004. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock: the file is locked by"
  2005. " another process." << endl;
  2006. return false;
  2007. } else {
  2008. if(f.open(IO_WriteOnly))
  2009. {
  2010. TQTextStream stream(&f);
  2011. stream.setEncoding(TQTextStream::Latin1); // no conversion
  2012. // -----
  2013. stream << getpid() << endl;
  2014. f.close();
  2015. } else {
  2016. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::lock: unable to create"
  2017. " lockfile." << endl;
  2018. return false;
  2019. }
  2020. }
  2021. // -----
  2022. LockFiles.push_back(lockfile);
  2023. return true;
  2024. // ############################################################################
  2025. }
  2026. bool
  2027. QConfigDB::unlock()
  2028. {
  2029. register bool GUARD; GUARD=false;
  2030. // ############################################################################
  2031. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: unlocking the file "
  2032. << filename << endl;
  2033. TQString lockfile=filename+".lock";
  2034. list<TQString>::iterator pos;
  2035. // -----
  2036. if(!locked)
  2037. {
  2038. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: this app did not "
  2039. "lock the file!" << endl;
  2040. return false;
  2041. }
  2042. if(access(TQFile::encodeName(lockfile), F_OK | W_OK)==0)
  2043. {
  2044. if(::remove(TQFile::encodeName(lockfile))==0)
  2045. {
  2046. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2047. "QConfigDB::unlock: lockfile deleted." << endl;
  2048. for(pos=LockFiles.begin(); pos!=LockFiles.end(); ++pos)
  2049. {
  2050. if((*pos)==lockfile) break;
  2051. }
  2052. if(pos!=LockFiles.end())
  2053. {
  2054. LockFiles.erase(pos); --pos;
  2055. } else {
  2056. kdDebug() << "QConfigDB::unlock: file not mentioned in lockfile" << endl;
  2057. }
  2058. locked=false;
  2059. return true;
  2060. } else {
  2061. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: unable to "
  2062. "delete lockfile.n" << endl;
  2063. return false;
  2064. }
  2065. } else {
  2066. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::unlock: the file is not"
  2067. " locked or permission has been denied." << endl;
  2068. return false;
  2069. }
  2070. // ############################################################################
  2071. }
  2072. void
  2073. QConfigDB::CleanLockFiles(int)
  2074. {
  2075. register bool GUARD; GUARD=false;
  2076. // ############################################################################
  2077. list<TQString>::iterator pos;
  2078. // -----
  2079. kdDebug(GUARD, KAB_KDEBUG_AREA).form("QConfigDB::CleanLockFiles: removing %i "
  2080. "remaining lockfiles.", LockFiles.size()) << endl;
  2081. for(pos=LockFiles.begin(); pos!=LockFiles.end(); ++pos)
  2082. {
  2083. if(::remove(TQFile::encodeName(*pos))==0)
  2084. {
  2085. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2086. " " << *pos << " removed.\n";
  2087. LockFiles.erase(pos); --pos;
  2088. } else {
  2089. kdDebug() << " could not remove " << *pos << endl;
  2090. }
  2091. }
  2092. // -----
  2093. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CleanLockFiles: done." << endl;
  2094. // ############################################################################
  2095. }
  2096. void
  2097. QConfigDB::watch(bool state)
  2098. {
  2099. // ############################################################################
  2100. if(state)
  2101. { // start timer
  2102. if(timer==0)
  2103. {
  2104. timer=new TQTimer(this);
  2105. connect(timer, TQT_SIGNAL(timeout()), TQT_SLOT(checkFileChanged()));
  2106. }
  2107. timer->start(1000);
  2108. } else { // stop timer
  2109. if(timer!=0)
  2110. {
  2111. timer->stop();
  2112. }
  2113. }
  2114. // ############################################################################
  2115. }
  2116. bool
  2117. QConfigDB::CheckLockFile(const TQString& file)
  2118. {
  2119. register bool GUARD; GUARD=false;
  2120. // ############################################################################
  2121. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: called." << endl;
  2122. int pid;
  2123. // -----
  2124. pid=IsLocked(file);
  2125. if(pid==0)
  2126. {
  2127. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: the file is "
  2128. "not locked." << endl;
  2129. return false;
  2130. }
  2131. if(pid>0)
  2132. {
  2133. if(kill(pid, 0)!=0)
  2134. { // ----- no such process, we may remove the lockfile:
  2135. return false;
  2136. }
  2137. }
  2138. if(pid<0)
  2139. {
  2140. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: the file has "
  2141. "not been created by QConfigDB::lock." << endl;
  2142. }
  2143. // ----- check system time and creation time of lockfile:
  2144. // WORK_TO_DO: not implemented
  2145. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::CheckLockFile: done." << endl;
  2146. return true;
  2147. // ############################################################################
  2148. }
  2149. bool
  2150. QConfigDB::checkFileChanged()
  2151. {
  2152. register bool GUARD; GUARD=false;
  2153. // ############################################################################
  2154. // kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::checkFileChanged: called." << endl;
  2155. if(filename.isEmpty())
  2156. { // ----- false, as file does not exist and thus may be stored anyway
  2157. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::checkFileChanged: no filename." << endl;
  2158. return false;
  2159. }
  2160. TQFileInfo file(filename);
  2161. // -----
  2162. if(file.exists())
  2163. {
  2164. if(file.lastModified() > *mtime)
  2165. {
  2166. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2167. "QConfigDB::checkFileChanged: file has been changed.n" << endl;
  2168. emit(fileChanged());
  2169. return true;
  2170. } else {
  2171. return false;
  2172. }
  2173. } else {
  2174. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::checkFileChanged: could "
  2175. "not stat file, file does not exist." << endl;
  2176. if(!mtime->isValid())
  2177. { // the file did never exist for us:
  2178. return false; // ... so it has not changed
  2179. } else { // it existed, and now it does no more
  2180. emit(fileChanged());
  2181. return true;
  2182. }
  2183. }
  2184. // ############################################################################
  2185. }
  2186. bool
  2187. QConfigDB::storeFileAge()
  2188. {
  2189. register bool GUARD; GUARD=false;
  2190. // ############################################################################
  2191. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::storeFileAge: called." << endl;
  2192. TQFileInfo file(filename);
  2193. // -----
  2194. if(file.exists())
  2195. {
  2196. *mtime=file.lastModified();
  2197. return true;
  2198. } else {
  2199. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::save: could not stat file." << endl;
  2200. *mtime=TQDateTime(); // a null date
  2201. return false;
  2202. }
  2203. // ############################################################################
  2204. }
  2205. bool
  2206. QConfigDB::setFileName(const TQString& filename_, bool mustexist, bool readonly_)
  2207. {
  2208. register bool GUARD; GUARD=false;
  2209. // ############################################################################
  2210. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: setting filename "
  2211. "to \""
  2212. << filename_ <<"\"" << (readonly_ ? " (read only)" : "") << endl;
  2213. // ----- remove previous lock:
  2214. if(locked)
  2215. {
  2216. if(!unlock())
  2217. {
  2218. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: cannot "
  2219. "release previous lock." << endl;
  2220. return false;
  2221. }
  2222. }
  2223. // ----- remove possible stale lockfile:
  2224. if(IsLocked(filename_)!=0 && !CheckLockFile(filename_))
  2225. { // ----- it is stale:
  2226. if(::remove(TQFile::encodeName(filename_+".lock"))==0)
  2227. {
  2228. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2229. "QConfigDB::setFileName: removed stale lockfile." << endl;
  2230. } else {
  2231. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2232. "QConfigDB::setFileName: cannot remove stale lockfile." << endl;
  2233. return false;
  2234. }
  2235. }
  2236. // -----
  2237. if(mustexist)
  2238. {
  2239. if(access(TQFile::encodeName(filename_), readonly_==true ? R_OK : W_OK | R_OK)==0)
  2240. {
  2241. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2242. "QConfigDB::setFileName: permission granted." << endl;
  2243. if(!readonly_)
  2244. { // we need r/w access:
  2245. if(lock(filename_))
  2246. {
  2247. locked=true;
  2248. } else {
  2249. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: "
  2250. "could not lock the file." << endl;
  2251. return false;
  2252. }
  2253. }
  2254. readonly=readonly_;
  2255. filename=filename_;
  2256. storeFileAge();
  2257. return true;
  2258. } else {
  2259. kdDebug() << "QConfigDB::setFileName: permission denied, " << endl;
  2260. return false;
  2261. }
  2262. } else {
  2263. if(access(TQFile::encodeName(filename_), F_OK)==0)
  2264. {
  2265. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: file exists." << endl;
  2266. if(access(TQFile::encodeName(filename_), W_OK | R_OK)==0)
  2267. {
  2268. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2269. "QConfigDB::setFileName: permission granted." << endl;
  2270. if(!readonly_)
  2271. { // we need r/w access:
  2272. if(lock(filename_))
  2273. {
  2274. locked=true;
  2275. } else {
  2276. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: "
  2277. "could not lock the file." << endl;
  2278. return false;
  2279. }
  2280. }
  2281. readonly=readonly_;
  2282. filename=filename_;
  2283. storeFileAge();
  2284. return true;
  2285. } else {
  2286. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::setFileName: "
  2287. "permission denied, filename not set." << endl;
  2288. return false;
  2289. }
  2290. } else {
  2291. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2292. "QConfigDB::setFileName: permission granted, new file." << endl;
  2293. readonly=readonly_;
  2294. filename=filename_;
  2295. if(!readonly)
  2296. {
  2297. if(!lock())
  2298. {
  2299. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2300. "QConfigDB::setFileName: could not lock the file." << endl;
  2301. return false;
  2302. }
  2303. }
  2304. storeFileAge();
  2305. return true;
  2306. }
  2307. }
  2308. // ############################################################################
  2309. }
  2310. TQString
  2311. QConfigDB::fileName()
  2312. {
  2313. // ############################################################################
  2314. return filename;
  2315. // ############################################################################
  2316. }
  2317. bool
  2318. QConfigDB::save(const char* header, bool force)
  2319. {
  2320. register bool GUARD; GUARD=true;
  2321. // ############################################################################
  2322. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2323. "QConfigDB::save: saving database -->" << filename << "<--.\n";
  2324. bool wasRO=false;
  2325. bool rc;
  2326. // -----
  2327. if(checkFileChanged())
  2328. {
  2329. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2330. "QConfigDB::save: file is newer, not saving." << endl;
  2331. return false;
  2332. }
  2333. if(force && isRO())
  2334. {
  2335. if(setFileName(fileName(), true, false))
  2336. {
  2337. wasRO=true;
  2338. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2339. "QConfigDB::save: switched to (forced) r/w mode." << endl;
  2340. } else {
  2341. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2342. "QConfigDB::save: cannot switch to (forced) r/w mode." << endl;
  2343. return false;
  2344. }
  2345. }
  2346. // ----- now save it:
  2347. if(!isRO())
  2348. {
  2349. TQFile file(filename);
  2350. if(file.open(IO_WriteOnly))
  2351. {
  2352. TQTextStream stream(&file);
  2353. stream.setEncoding(TQTextStream::Latin1); // no conversion
  2354. // -----
  2355. if(header!=0)
  2356. {
  2357. stream << "# " << header << endl;
  2358. }
  2359. stream << '#' << " [File created by QConfigDB object "
  2360. << version() << "]" << endl;
  2361. if(!top.save(stream)) // traverse tree
  2362. {
  2363. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2364. "QConfigDB::save: error saving subsections." << endl;
  2365. }
  2366. storeFileAge();
  2367. file.close();
  2368. rc=true;
  2369. } else {
  2370. kdDebug() << "QConfigDB::save: error opening file \""
  2371. << filename <<
  2372. "\" for writing.\n";
  2373. rc=false;
  2374. }
  2375. } else {
  2376. rc=false;
  2377. }
  2378. // ----- reset r/o mode:
  2379. if(wasRO) // only true if we switched to forced r/w mode here
  2380. {
  2381. if(setFileName(fileName(), false, true))
  2382. {
  2383. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2384. "QConfigDB::save: reset (forced) r/w mode." << endl;
  2385. } else {
  2386. kdDebug(GUARD, KAB_KDEBUG_AREA) <<
  2387. "QConfigDB::save: cannot reset (forced) r/w mode." << endl;
  2388. rc=false;
  2389. }
  2390. }
  2391. // -----
  2392. return rc;
  2393. // ############################################################################
  2394. }
  2395. bool
  2396. QConfigDB::load()
  2397. {
  2398. register bool GUARD; GUARD=false ;
  2399. // ############################################################################
  2400. TQFile file(filename);
  2401. // -----
  2402. if(file.open(IO_ReadOnly))
  2403. {
  2404. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::load: file access OK." << endl;
  2405. TQTextStream stream(&file);
  2406. stream.setEncoding(TQTextStream::Latin1); // no conversion
  2407. // -----
  2408. clear();
  2409. bool rc=top.readSection(stream, false);
  2410. storeFileAge();
  2411. file.close();
  2412. emit(changed(this));
  2413. kdDebug(GUARD, KAB_KDEBUG_AREA) << "QConfigDB::load: done." << endl;
  2414. return rc;
  2415. } else {
  2416. kdDebug() << "QConfigDB::load: error opening file \"" << filename << "\" for reading." << endl;
  2417. return false;
  2418. }
  2419. // ############################################################################
  2420. }