autoNumberFP.C 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: autoNumberFP.C /main/7 1998/04/17 11:47:29 mgreess $ */
  24. #include "autoNumberFP.h"
  25. #include "StyleSheet/Const.h"
  26. #include "StyleSheet/Expression.h"
  27. autoNumberFP gAutoNumberFP;
  28. #ifndef CDE_NEXT
  29. typedef CC_TPtrSlistIterator<autoNumber> autoNumberListIteratorT;
  30. unsigned ANP_StringHash(const CC_String& str)
  31. {
  32. return str.hash();
  33. }
  34. #else
  35. typedef CC_TPtrSlistIterator<autoNumber> autoNumberListIteratorT;
  36. unsigned ANP_StringHash(const CC_String& str)
  37. {
  38. return str.hash();
  39. }
  40. #endif
  41. ///////////////////////////////////////////////
  42. // static member initialization
  43. ///////////////////////////////////////////////
  44. /*
  45. f_autoNumberSet_t autoNumberFP::f_autoNumberSet(ANP_StringHash);
  46. f_resetControlList_t autoNumberFP::f_resetControlList(ANP_StringHash);
  47. f_registerList_t autoNumberFP::f_registerList(ANP_StringHash);
  48. */
  49. ///////////////////////////////////////////////
  50. //
  51. ///////////////////////////////////////////////
  52. autoNumberFP::autoNumberFP() :
  53. f_autoNumberSet(ANP_StringHash),
  54. f_resetControlList(ANP_StringHash),
  55. f_registerList(ANP_StringHash)
  56. {
  57. }
  58. autoNumberFP::~autoNumberFP()
  59. {
  60. f_autoNumberSet.clearAndDestroy();
  61. f_resetControlList.clearAndDestroy();
  62. f_registerList.clearAndDestroy();
  63. }
  64. const char* autoNumberFP::stringToCharPtr(const FeatureValue* f)
  65. {
  66. if ( f ) {
  67. if ( f -> type() == FeatureValue::string ) {
  68. const char* x = *f;
  69. return x;
  70. } else
  71. throw(CASTHCREXCEPT hardCopyRendererException());
  72. }
  73. return 0;
  74. }
  75. #if 0
  76. // reset autonumbers
  77. void autoNumberFP::resetAutoNumbers(const char* name)
  78. {
  79. CC_String key(name);
  80. autoNumberListT* anList = f_resetControlList.findValue(&key);
  81. if ( anList == 0 )
  82. return;
  83. autoNumberListIteratorT l_iter(*anList);
  84. while ( ++l_iter ) {
  85. l_iter.key() -> reset();
  86. }
  87. }
  88. #endif
  89. void
  90. autoNumberFP::pushAutoNumbers(const char* giname)
  91. {
  92. if (giname && *giname)
  93. {
  94. CC_String key(giname);
  95. autoNumberListT* anList = f_resetControlList.findValue(&key);
  96. if (anList)
  97. {
  98. autoNumberListIteratorT l_iter(*anList);
  99. while ( ++l_iter )
  100. l_iter.key()->push();
  101. }
  102. }
  103. }
  104. void
  105. autoNumberFP::popAutoNumbers(const char* giname)
  106. {
  107. if (giname && *giname)
  108. {
  109. CC_String key(giname);
  110. autoNumberListT* anList = f_resetControlList.findValue(&key);
  111. if (anList)
  112. {
  113. autoNumberListIteratorT l_iter(*anList);
  114. while ( ++l_iter )
  115. l_iter.key()->pop();
  116. }
  117. }
  118. }
  119. // update autonumbers
  120. void autoNumberFP::updateAutoNumbers(const char* name)
  121. {
  122. CC_String key(name);
  123. autoNumberListT* anList = f_registerList.findValue(&key);
  124. if ( anList == 0 )
  125. return;
  126. autoNumberListIteratorT l_iter(*anList);
  127. while ( ++l_iter ) {
  128. l_iter.key() -> setNextValue();
  129. }
  130. }
  131. //////////////////////////////////////////////////////////////////////////
  132. //
  133. // Array fields:
  134. // Type, InitValue, Delta, RegisterList, ControlList, [Prefix], [PostFix]
  135. //
  136. // Type, Pretfix and Postfix are strings.
  137. // RegisterList and ControlList are array.
  138. // InitValue and Delta are integers.
  139. // Prefix and Postfix are optional
  140. //////////////////////////////////////////////////////////////////////////
  141. void
  142. autoNumberFP::defineAutoNumber(const char* nm, const FeatureValue* f)
  143. {
  144. if ( f -> type() != FeatureValue::array ) {
  145. debug(cerr, f -> type());
  146. cerr << "Autonumber: should use an array to define.\n";
  147. throw(CASTHCREXCEPT hardCopyRendererException());
  148. }
  149. FeatureValueArray* fa = (FeatureValueArray*)f;
  150. if ( fa -> length() != 5 ) {
  151. cerr << "Autonumber: invalid number of arguments.\n";
  152. throw(CASTHCREXCEPT hardCopyRendererException());
  153. }
  154. // name
  155. const char* name = nm;
  156. // type
  157. if ( (*fa)[0] -> type() != FeatureValue::string ) {
  158. cerr << "Autonumber: type should be a string.\n";
  159. throw(CASTHCREXCEPT hardCopyRendererException());
  160. }
  161. const char* type = stringToCharPtr((*fa)[0]);
  162. // init value
  163. if ( (*fa)[1] -> type() != FeatureValue::string ) {
  164. cerr << "Autonumber: initial value should be a string.\n";
  165. throw(CASTHCREXCEPT hardCopyRendererException());
  166. }
  167. const char* initvalue = stringToCharPtr((*fa)[1]);
  168. // delta
  169. if ( (*fa)[2] -> type() != FeatureValue::string ) {
  170. cerr << "Autonumber: delta value should be a string.\n";
  171. throw(CASTHCREXCEPT hardCopyRendererException());
  172. }
  173. int delta = atoi(stringToCharPtr((*fa)[2]));
  174. // register list
  175. FeatureValueArray* registerList = 0;
  176. if ( (*fa)[3] -> type() != FeatureValue::array ) {
  177. cerr << "Autonumber: counter list should be an array\n.";
  178. throw(CASTHCREXCEPT hardCopyRendererException());
  179. } else {
  180. registerList = (FeatureValueArray*)(*fa)[3];
  181. }
  182. // control list
  183. FeatureValueArray* controlList = 0;
  184. if ( (*fa)[4] -> type() != FeatureValue::array ) {
  185. cerr << "Autonumber: reset list should be an array\n.";
  186. throw(CASTHCREXCEPT hardCopyRendererException());
  187. } else {
  188. controlList = (FeatureValueArray*)(*fa)[4];
  189. }
  190. // prefix
  191. const char* prefix = "";
  192. // postfix
  193. const char* postfix = "";
  194. //////////////////////////////////
  195. // create the autonumber object
  196. //////////////////////////////////
  197. autoNumber* an = 0;
  198. if ( strcasecmp(type, AUTO_NUMBER_NUMERIC) == 0 )
  199. an = new autoNumberNumeric(
  200. name, delta, atoi(initvalue), prefix, postfix
  201. );
  202. else
  203. if ( strcasecmp(type, AUTO_NUMBER_ALPHABETIC_UPPERCASE) == 0 ) {
  204. an = new autoNumberAlphabetic(
  205. name, delta, autoNumberCased::UPPER, initvalue, prefix, postfix
  206. );
  207. } else
  208. if ( strcasecmp(type, AUTO_NUMBER_ALPHABETIC_LOWERCASE) == 0 ) {
  209. an = new autoNumberAlphabetic(
  210. name, delta, autoNumberCased::LOWER, initvalue, prefix, postfix
  211. );
  212. } else
  213. if ( strcasecmp(type, AUTO_NUMBER_ROMAN_UPPERCASE) == 0 )
  214. an = new autoNumberRoman(
  215. name, delta, autoNumberCased::UPPER, initvalue, prefix, postfix
  216. );
  217. else
  218. if ( strcasecmp(type, AUTO_NUMBER_ROMAN_LOWERCASE) == 0 )
  219. an = new autoNumberRoman(
  220. name, delta, autoNumberCased::LOWER, initvalue, prefix, postfix
  221. );
  222. else {
  223. MESSAGE(cerr, form("unknown type: %s", type));
  224. cerr << form("Autonumber: unknown type %s.", type) << "\n";
  225. throw(CASTHCREXCEPT hardCopyRendererException());
  226. }
  227. //////////////////////////
  228. // log the new autonumber
  229. //////////////////////////
  230. CC_String *key = new CC_String(name);
  231. if ( f_autoNumberSet.findValue(key) ) {
  232. delete key;
  233. delete an;
  234. return;
  235. } else
  236. f_autoNumberSet.insertKeyAndValue(key, an);
  237. ///////////////////////////////
  238. // log into reset control list
  239. ///////////////////////////////
  240. const char* gi = 0;
  241. autoNumberListT* anList = 0;
  242. unsigned int i;
  243. for (i=0; i<controlList -> length(); i++ ) {
  244. gi = stringToCharPtr((*controlList)[i]);
  245. key = new CC_String(gi);
  246. anList = f_resetControlList.findValue(key);
  247. if ( anList == 0 ) {
  248. anList = new autoNumberListT();
  249. f_resetControlList.insertKeyAndValue(key, anList);
  250. } else
  251. delete key;
  252. anList -> append(an);
  253. }
  254. ////////////////////////////////
  255. // log into register list
  256. ////////////////////////////////
  257. for (i=0; i<registerList -> length(); i++ ) {
  258. gi = stringToCharPtr((*registerList)[i]);
  259. key = new CC_String(gi);
  260. anList = f_registerList.findValue(key);
  261. if ( anList == 0 ) {
  262. anList = new autoNumberListT();
  263. f_registerList.insertKeyAndValue(key, anList);
  264. } else
  265. delete key;
  266. anList -> append(an);
  267. }
  268. }
  269. void autoNumberFP::setSeenTagStatus(const char* tagName)
  270. {
  271. CC_String key(tagName);
  272. autoNumberListT* anList = f_registerList.findValue(&key);
  273. if ( anList == 0 )
  274. return;
  275. autoNumberListIteratorT next(*anList);
  276. while ( ++next ) {
  277. next.key() -> setNumTagsSeen();
  278. }
  279. }
  280. FeatureValue*
  281. autoNumberFP::evaluate(const char* varName)
  282. {
  283. CC_String key(varName);
  284. autoNumber* an = f_autoNumberSet.findValue(&key);
  285. if ( an == 0 ) {
  286. MESSAGE(cerr, form("Warning: unknown autonumber name %s.", varName));
  287. return 0;
  288. } else
  289. return new FeatureValueString(an -> getValue());
  290. }
  291. unsigned int
  292. autoNumberFP::accept(const char* name, const Expression* expr)
  293. {
  294. FeatureValue* fv = 0;
  295. mtry
  296. {
  297. fv = expr -> evaluate();
  298. }
  299. mcatch_any()
  300. {
  301. return false;
  302. }
  303. end_try;
  304. /*
  305. debug(cerr, name);
  306. fv -> print(cerr);
  307. */
  308. if ( fv -> type() != FeatureValue::array ) {
  309. delete fv;
  310. return false;
  311. }
  312. FeatureValueArray* fvArray = (FeatureValueArray*) fv;
  313. /*
  314. debug(cerr, fvArray -> length());
  315. debug(cerr, fvArray -> name());
  316. */
  317. if ( fvArray -> length() >= 1 &&
  318. strcasecmp(fvArray -> name(), AUTO_NUMBER) == 0
  319. )
  320. {
  321. defineAutoNumber(name, fv);
  322. delete fv;
  323. return true;
  324. } else {
  325. delete fv;
  326. return false;
  327. }
  328. }
  329. void
  330. autoNumberFP::beginElement(const Element& element)
  331. {
  332. const char* giname = element.gi().name();
  333. if (giname && *giname)
  334. {
  335. pushAutoNumbers(giname);
  336. setSeenTagStatus(giname);
  337. updateAutoNumbers(giname);
  338. }
  339. #ifdef DEBUG
  340. else
  341. abort();
  342. #endif
  343. }
  344. void
  345. autoNumberFP::endElement(const Symbol& sym)
  346. {
  347. const char* giname = sym.name();
  348. if (giname && *giname)
  349. {
  350. popAutoNumbers(giname);
  351. }
  352. #ifdef DEBUG
  353. else
  354. abort();
  355. #endif
  356. }
  357. #if 0
  358. void autoNumberFP::preEvaluate(const Element& element)
  359. {
  360. setSeenTagStatus(element.gi().name());
  361. updateAutoNumbers(element.gi().name());
  362. }
  363. void autoNumberFP::postEvaluate(const Element& element)
  364. {
  365. resetAutoNumbers(element.gi().name());
  366. }
  367. #endif
  368. void autoNumberFP::clear()
  369. {
  370. f_autoNumberSet.clearAndDestroy();
  371. f_resetControlList.clearAndDestroy();
  372. f_registerList.clearAndDestroy();
  373. }
  374. // reset All autonumbers
  375. void autoNumberFP::resetAllAutoNumbers()
  376. {
  377. hashTableIterator<CC_String, autoNumberListT> l_rc_iterator(f_resetControlList);
  378. while ( ++l_rc_iterator ) {
  379. autoNumberListT* anList = l_rc_iterator.value();
  380. autoNumberListIteratorT l_iter(*anList);
  381. while ( ++l_iter ) {
  382. l_iter.key() -> reset();
  383. }
  384. }
  385. }