PageRenderTime 35ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 1ms

/branches/gbdk-297/sdcc/sim/ucsim/pobj.cc

#
C++ | 632 lines | 314 code | 133 blank | 185 comment | 51 complexity | e2b2fed7388481ef42b38bb1857f5ab8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, GPL-3.0
  1. /*
  2. * Simulator of microcontrollers (pobj.cc)
  3. *
  4. * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
  5. *
  6. * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
  7. *
  8. */
  9. /* This file is part of microcontroller simulator: ucsim.
  10. UCSIM is free software; you can redistribute it and/or modify
  11. it under the terms of the GNU General Public License as published by
  12. the Free Software Foundation; either version 2 of the License, or
  13. (at your option) any later version.
  14. UCSIM is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. GNU General Public License for more details.
  18. You should have received a copy of the GNU General Public License
  19. along with UCSIM; see the file COPYING. If not, write to the Free
  20. Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  21. 02111-1307, USA. */
  22. /*@1@*/
  23. #include "ddconfig.h"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include "pstr.h"
  27. /*#include "pobjt.h"*/
  28. #include "pobjcl.h"
  29. /* *
  30. ==========================================================================*
  31. cl_base *
  32. ==========================================================================*
  33. *
  34. */
  35. /*
  36. * Initializing the object
  37. */
  38. cl_base::cl_base(void) {}
  39. /*
  40. * Destructing the object: calling hte virtual Done method
  41. */
  42. cl_base::~cl_base(void) {}
  43. int cl_base::init(void) {return(0);}
  44. /* *
  45. ==========================================================================*
  46. cl_list *
  47. ==========================================================================*
  48. *
  49. */
  50. /*
  51. * Initializing a collection
  52. */
  53. cl_list::cl_list(t_index alimit, t_index adelta):
  54. cl_base()
  55. {
  56. count= 0;
  57. Items= 0;
  58. Limit= 0;
  59. Delta= adelta;
  60. set_limit(alimit);
  61. }
  62. /*
  63. * Disposing object's variables
  64. */
  65. cl_list::~cl_list(void)
  66. {
  67. //delete Items;
  68. free(Items);
  69. }
  70. /*
  71. * Get indexed item from the collection
  72. */
  73. void *
  74. cl_list::at(t_index index)
  75. {
  76. if (index < 0 ||
  77. index >= count)
  78. error(1, index);
  79. return(Items[index]);
  80. }
  81. /*void *
  82. cl_list::operator[](t_index index)
  83. {
  84. if (index < 0 ||
  85. index >= count)
  86. error(1, 0);
  87. return(Items[index]);
  88. }*/
  89. /*
  90. * Deleting the indexed item from the collection
  91. */
  92. void
  93. cl_list::disconn_at(t_index index)
  94. {
  95. if (index < 0 ||
  96. index >= count)
  97. error(1, 0);
  98. count--;
  99. memmove(&Items[index], &Items[index+1], (count-index)*sizeof(void *));
  100. }
  101. /*
  102. * Deleting an item from the collection but not disposing it
  103. */
  104. void
  105. cl_list::disconn(void *item)
  106. {
  107. t_index i;
  108. if (index_of(item, &i))
  109. disconn_at(i);
  110. }
  111. /*
  112. * Deleting all the items from the collection but not disposing them
  113. */
  114. void
  115. cl_list::disconn_all(void)
  116. {
  117. count= 0;
  118. }
  119. /*
  120. * Deleting the indexed item from the collection and disposing it
  121. */
  122. void
  123. cl_list::free_at(t_index index)
  124. {
  125. void *Item= at(index);
  126. disconn_at(index);
  127. free_item(Item);
  128. }
  129. void
  130. cl_list::free_all(void)
  131. {
  132. t_index i;
  133. if (count)
  134. {
  135. for (i= count-1; i; i--)
  136. free_at(i);
  137. free_at(0);
  138. }
  139. }
  140. /*
  141. * Inserting a new item to the exact position
  142. */
  143. void
  144. cl_list::add_at(t_index index, void *item)
  145. {
  146. if (index < 0 )
  147. error(1, 0);
  148. if (count == Limit)
  149. set_limit(count + Delta);
  150. memmove(&Items[index+1], &Items[index], (count-index)*sizeof(void *));
  151. count++;
  152. Items[index]= item;
  153. }
  154. /*
  155. * Put a new item to the collection. This function replaces an existing
  156. * item with a new one but it does not delete or dispose the old item!
  157. */
  158. void
  159. cl_list::put_at(t_index index, void *item)
  160. {
  161. if (index >= count)
  162. error(1, 0);
  163. Items[index]= item;
  164. }
  165. /*
  166. * Action taken when an error occure
  167. */
  168. void
  169. cl_list::error(t_index code, t_index info)
  170. {
  171. fprintf(stderr,
  172. "Collection index error. Code= %d, Info= %d.\n",
  173. code, info);
  174. exit(code);
  175. }
  176. /*
  177. * Iterator method. This function calls 'Test' using every items as Test's
  178. * argument until Test returns TRUE.
  179. */
  180. void *
  181. cl_list::first_that(match_func test, void *arg)
  182. {
  183. for (t_index i= 0; i < count; i++)
  184. {
  185. if (test(Items[i], arg)) return(Items[i]);
  186. }
  187. return(0);
  188. }
  189. /*
  190. * Iterator method. This function calls 'Action' using every items as
  191. * Action's argument.
  192. */
  193. void
  194. cl_list::for_each(iterator_func action, void *arg)
  195. {
  196. for(t_index i= 0; i < count; i++)
  197. action(Items[i], arg);
  198. }
  199. /*
  200. * Disposing an item.
  201. */
  202. void
  203. cl_list::free_item(void *item)
  204. {
  205. delete (class cl_base*)item;
  206. }
  207. /*
  208. * Get the number of collected items.
  209. */
  210. int
  211. cl_list::get_count(void)
  212. {
  213. return(count);
  214. }
  215. void *
  216. cl_list::pop(void)
  217. {
  218. void *i;
  219. if (!count)
  220. return(0);
  221. i= Items[0];
  222. disconn_at(0);
  223. return(i);
  224. }
  225. void *
  226. cl_list::top(void)
  227. {
  228. if (!count)
  229. return(0);
  230. return(Items[0]);
  231. }
  232. /*
  233. * Returning the index of an item.
  234. */
  235. t_index
  236. cl_list::index_of(void *item)
  237. {
  238. for (t_index i= 0; i < count; i++)
  239. if (item == Items[i])
  240. return(i);
  241. error(1, 0);
  242. return(0); /* Needed by Sun! */
  243. }
  244. bool
  245. cl_list::index_of(void *item, t_index *idx)
  246. {
  247. for (t_index i= 0; i < count; i++)
  248. if (item == Items[i])
  249. {
  250. if (idx)
  251. *idx= i;
  252. return(DD_TRUE);
  253. }
  254. return(DD_FALSE);
  255. }
  256. /*
  257. * Inserting a new item to the collection.
  258. */
  259. t_index
  260. cl_list::add(void *item)
  261. {
  262. t_index loc= count;
  263. add_at(count, item);
  264. return(loc);
  265. }
  266. void
  267. cl_list::push(void *item)
  268. {
  269. if (count)
  270. add_at(0, item);
  271. else
  272. add(item);
  273. }
  274. /*
  275. * Iterator method. This function calls 'Test' using every items
  276. * (in reversed order) as Test's argument until Test returns TRUE.
  277. */
  278. void *
  279. cl_list::last_that(match_func test, void *arg)
  280. {
  281. for(t_index i= count; i > 0; i--)
  282. if (test(Items[i-1], arg))
  283. return(Items[i-1]);
  284. return(0);
  285. }
  286. /*
  287. * ???
  288. */
  289. /*void
  290. cl_list::pack(void)
  291. {
  292. void **CurDst= Items;
  293. void **CurSrc= Items;
  294. void **Last = Items + count;
  295. while (CurSrc < Last)
  296. {
  297. if (*CurSrc != 0)
  298. *CurDst++= *CurSrc;
  299. *CurSrc++;
  300. }
  301. }*/
  302. /*
  303. * Setting up the maximum number of items. This function may expand
  304. * the size of the collection.
  305. */
  306. void
  307. cl_list::set_limit(t_index alimit)
  308. {
  309. void **AItems;
  310. if (alimit < count)
  311. alimit= count;
  312. if (alimit > (int)max_list_size)
  313. alimit= max_list_size;
  314. if (alimit != Limit)
  315. {
  316. if (alimit == 0)
  317. AItems= 0;
  318. else
  319. {
  320. //AItems = new void *[alimit];
  321. int i= alimit*(sizeof(void *));
  322. AItems= (void **)malloc(i);
  323. if (count)
  324. memcpy(AItems, Items, count*sizeof(void *));
  325. }
  326. //delete Items;
  327. free(Items);
  328. Items= AItems;
  329. Limit= alimit;
  330. }
  331. }
  332. /* *
  333. ==========================================================================*
  334. cl_sorted_list *
  335. ==========================================================================*
  336. *
  337. */
  338. /*
  339. * Initilizing the sorted collection
  340. */
  341. cl_sorted_list::cl_sorted_list(t_index alimit, t_index adelta):
  342. cl_list(alimit, adelta)
  343. {
  344. Duplicates= DD_FALSE;
  345. }
  346. cl_sorted_list::~cl_sorted_list(void) {}
  347. /*
  348. * Get the address of the key field in an item.
  349. */
  350. void *
  351. cl_sorted_list::key_of(void *item)
  352. {
  353. return(item);
  354. }
  355. /*
  356. * Get index of an item.
  357. */
  358. t_index
  359. cl_sorted_list::index_of(void *item)
  360. {
  361. t_index i;
  362. if (search(key_of(item), i) == 0)
  363. return(ccNotFound);
  364. else
  365. {
  366. if (Duplicates)
  367. while (i < count &&
  368. item != Items[i])
  369. i++;
  370. if (i < count)
  371. return(i);
  372. else
  373. return(ccNotFound);
  374. }
  375. }
  376. /*
  377. * Inserting a new item to the collection
  378. */
  379. t_index
  380. cl_sorted_list::add(void *item)
  381. {
  382. t_index i;
  383. if (search(key_of(item), i) == 0 ||
  384. Duplicates) // order dependency!
  385. add_at(i, item); // must do Search
  386. // before calling
  387. // AtInsert
  388. return(i);
  389. }
  390. /*
  391. * Searching an item using binary search.
  392. */
  393. bool
  394. cl_sorted_list::search(void *key, t_index &index)
  395. {
  396. t_index l = 0;
  397. t_index h = count - 1;
  398. bool res= DD_FALSE;
  399. while (l <= h)
  400. {
  401. t_index i= (l + h) >> 1;
  402. t_index c= compare(key_of(Items[i]), key);
  403. if (c < 0) l= i + 1;
  404. else
  405. {
  406. h= i - 1;
  407. if (c == 0)
  408. {
  409. res= DD_TRUE;
  410. if (!Duplicates)
  411. l= i;
  412. }
  413. }
  414. }
  415. index= l;
  416. return(res);
  417. }
  418. /* *
  419. ==========================================================================*
  420. cl_strings *
  421. ==========================================================================*
  422. *
  423. */
  424. /*
  425. * Initilizing the string collection
  426. */
  427. cl_strings::cl_strings(t_index alimit, t_index adelta):
  428. cl_sorted_list(alimit, adelta)
  429. {
  430. Duplicates= DD_TRUE;
  431. }
  432. cl_strings::~cl_strings(void) {}
  433. /*
  434. * Comapare two string from the collection
  435. */
  436. int
  437. cl_strings::compare(void *key1, void *key2)
  438. {
  439. return(strcmp((char *)key1, (char *)key2));
  440. }
  441. /*
  442. * Deallocate string item of the collection
  443. */
  444. void
  445. cl_strings::free_item(void* item)
  446. {
  447. delete (class cl_base*)item;
  448. }
  449. /* *
  450. ==========================================================================*
  451. cl_ustrings *
  452. ==========================================================================*
  453. *
  454. */
  455. /*
  456. * Initilizing the unsorted string collection
  457. */
  458. cl_ustrings::cl_ustrings(t_index alimit, t_index adelta):
  459. cl_strings(alimit, adelta)
  460. {}
  461. cl_ustrings::~cl_ustrings(void) {}
  462. /*
  463. * Comapare two string from the collection
  464. */
  465. int
  466. cl_ustrings::compare(void *key1, void *key2)
  467. {
  468. return(-1);
  469. }
  470. /*
  471. * Searching an item using linear search.
  472. */
  473. bool
  474. cl_ustrings::search(void *key, t_index& index)
  475. {
  476. t_index i = 0;
  477. bool found= DD_FALSE;
  478. void *Actual;
  479. if ((count) && key)
  480. {
  481. while (!found && (i < count))
  482. {
  483. Actual= key_of(at(i));
  484. found = (Actual != 0) &&
  485. (compare(key, Actual) == 0);
  486. i++;
  487. }
  488. }
  489. if (found)
  490. index= i-1;
  491. else
  492. index= count;
  493. return(found);
  494. }
  495. /* End of pobj.cc */