PageRenderTime 35ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/cssed-0.4.0/libcroco/parser/cr-prop-list.c

#
C | 360 lines | 209 code | 50 blank | 101 comment | 52 complexity | ed155a0de65443330520724843ea7df4 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * This file is part of The Croco Library
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of version 2.1 of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Lesser General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  16. * USA
  17. *
  18. * Author: Dodji Seketeli
  19. * See COPYRIGHTS file for copyrights information.
  20. */
  21. #include <string.h>
  22. #include "cr-prop-list.h"
  23. #define PRIVATE(a_obj) (a_obj)->priv
  24. struct _CRPropListPriv {
  25. CRString *prop;
  26. CRDeclaration *decl;
  27. CRPropList *next;
  28. CRPropList *prev;
  29. };
  30. static CRPropList *cr_prop_list_allocate (void);
  31. /**
  32. *Default allocator of CRPropList
  33. *@return the newly allocated CRPropList or NULL
  34. *if an error arises.
  35. */
  36. static CRPropList *
  37. cr_prop_list_allocate (void)
  38. {
  39. CRPropList *result = NULL;
  40. result = g_try_malloc (sizeof (CRPropList));
  41. if (!result) {
  42. cr_utils_trace_info ("could not allocate CRPropList");
  43. return NULL;
  44. }
  45. memset (result, 0, sizeof (CRPropList));
  46. PRIVATE (result) = g_try_malloc (sizeof (CRPropListPriv));
  47. if (!result) {
  48. cr_utils_trace_info ("could not allocate CRPropListPriv");
  49. g_free (result);
  50. return NULL;
  51. }
  52. memset (PRIVATE (result), 0, sizeof (CRPropListPriv));
  53. return result;
  54. }
  55. /****************
  56. *public methods
  57. ***************/
  58. /**
  59. *Appends a property list to the current one.
  60. *@param a_this the current instance of #CRPropList
  61. *@param a_to_append the property list to append
  62. *@return the resulting prop list, or NULL if an error
  63. *occured
  64. */
  65. CRPropList *
  66. cr_prop_list_append (CRPropList * a_this, CRPropList * a_to_append)
  67. {
  68. CRPropList *cur = NULL;
  69. g_return_val_if_fail (a_to_append, NULL);
  70. if (!a_this)
  71. return a_to_append;
  72. /*go fetch the last element of the list */
  73. for (cur = a_this;
  74. cur && PRIVATE (cur) && PRIVATE (cur)->next;
  75. cur = PRIVATE (cur)->next) ;
  76. g_return_val_if_fail (cur, NULL);
  77. PRIVATE (cur)->next = a_to_append;
  78. PRIVATE (a_to_append)->prev = cur;
  79. return a_this;
  80. }
  81. /**
  82. *Appends a pair of prop/declaration to
  83. *the current prop list.
  84. *@param a_this the current instance of #CRPropList
  85. *@param a_prop the property to consider
  86. *@param a_decl the declaration to consider
  87. *@return the resulting property list, or NULL in case
  88. *of an error.
  89. */
  90. CRPropList *
  91. cr_prop_list_append2 (CRPropList * a_this,
  92. CRString * a_prop,
  93. CRDeclaration * a_decl)
  94. {
  95. CRPropList *list = NULL,
  96. *result = NULL;
  97. g_return_val_if_fail (a_prop && a_decl, NULL);
  98. list = cr_prop_list_allocate ();
  99. g_return_val_if_fail (list && PRIVATE (list), NULL);
  100. PRIVATE (list)->prop = a_prop;
  101. PRIVATE (list)->decl = a_decl;
  102. result = cr_prop_list_append (a_this, list);
  103. return result;
  104. }
  105. /**
  106. *Prepends a list to the current list
  107. *@param a_this the current instance of #CRPropList
  108. *@param the new list to prepend.
  109. */
  110. CRPropList *
  111. cr_prop_list_prepend (CRPropList * a_this, CRPropList * a_to_prepend)
  112. {
  113. CRPropList *cur = NULL;
  114. g_return_val_if_fail (a_to_prepend, NULL);
  115. if (!a_this)
  116. return a_to_prepend;
  117. for (cur = a_to_prepend; cur && PRIVATE (cur)->next;
  118. cur = PRIVATE (cur)->next) ;
  119. g_return_val_if_fail (cur, NULL);
  120. PRIVATE (cur)->next = a_this;
  121. PRIVATE (a_this)->prev = cur;
  122. return a_to_prepend;
  123. }
  124. /**
  125. *Prepends a list to the current list
  126. *@param a_this the current instance of #CRPropList
  127. *@param the new list to prepend.
  128. */
  129. CRPropList *
  130. cr_prop_list_prepend2 (CRPropList * a_this,
  131. CRString * a_prop, CRDeclaration * a_decl)
  132. {
  133. CRPropList *list = NULL,
  134. *result = NULL;
  135. g_return_val_if_fail (a_this && PRIVATE (a_this)
  136. && a_prop && a_decl, NULL);
  137. list = cr_prop_list_allocate ();
  138. g_return_val_if_fail (list, NULL);
  139. PRIVATE (list)->prop = a_prop;
  140. PRIVATE (list)->decl = a_decl;
  141. result = cr_prop_list_prepend (a_this, list);
  142. return result;
  143. }
  144. /**
  145. *Sets the property of a CRPropList
  146. *@param a_this the current instance of #CRPropList
  147. *@param a_prop the property to set
  148. */
  149. enum CRStatus
  150. cr_prop_list_set_prop (CRPropList * a_this, CRString * a_prop)
  151. {
  152. g_return_val_if_fail (a_this && PRIVATE (a_this)
  153. && a_prop, CR_BAD_PARAM_ERROR);
  154. PRIVATE (a_this)->prop = a_prop;
  155. return CR_OK;
  156. }
  157. /**
  158. *Getter of the property associated to the current instance
  159. *of #CRPropList
  160. *@param a_this the current instance of #CRPropList
  161. *@param a_prop out parameter. The returned property
  162. *@return CR_OK upon successful completion, an error code
  163. *otherwise.
  164. */
  165. enum CRStatus
  166. cr_prop_list_get_prop (CRPropList * a_this, CRString ** a_prop)
  167. {
  168. g_return_val_if_fail (a_this && PRIVATE (a_this)
  169. && a_prop, CR_BAD_PARAM_ERROR);
  170. *a_prop = PRIVATE (a_this)->prop;
  171. return CR_OK;
  172. }
  173. enum CRStatus
  174. cr_prop_list_set_decl (CRPropList * a_this, CRDeclaration * a_decl)
  175. {
  176. g_return_val_if_fail (a_this && PRIVATE (a_this)
  177. && a_decl, CR_BAD_PARAM_ERROR);
  178. PRIVATE (a_this)->decl = a_decl;
  179. return CR_OK;
  180. }
  181. enum CRStatus
  182. cr_prop_list_get_decl (CRPropList * a_this, CRDeclaration ** a_decl)
  183. {
  184. g_return_val_if_fail (a_this && PRIVATE (a_this)
  185. && a_decl, CR_BAD_PARAM_ERROR);
  186. *a_decl = PRIVATE (a_this)->decl;
  187. return CR_OK;
  188. }
  189. /**
  190. *Lookup a given property/declaration pair
  191. *@param a_this the current instance of #CRPropList
  192. *@param a_prop the property to lookup
  193. *@param a_prop_list out parameter. The property/declaration
  194. *pair found (if and only if the function returned code if CR_OK)
  195. *@return CR_OK if a prop/decl pair has been found,
  196. *CR_VALUE_NOT_FOUND_ERROR if not, or an error code if something
  197. *bad happens.
  198. */
  199. enum CRStatus
  200. cr_prop_list_lookup_prop (CRPropList * a_this,
  201. CRString * a_prop, CRPropList ** a_pair)
  202. {
  203. CRPropList *cur = NULL;
  204. g_return_val_if_fail (a_prop && a_pair, CR_BAD_PARAM_ERROR);
  205. if (!a_this)
  206. return CR_VALUE_NOT_FOUND_ERROR;
  207. g_return_val_if_fail (PRIVATE (a_this), CR_BAD_PARAM_ERROR);
  208. for (cur = a_this; cur; cur = PRIVATE (cur)->next) {
  209. if (PRIVATE (cur)->prop
  210. && PRIVATE (cur)->prop->stryng
  211. && PRIVATE (cur)->prop->stryng->str
  212. && a_prop->stryng
  213. && a_prop->stryng->str
  214. && !strcmp (PRIVATE (cur)->prop->stryng->str,
  215. a_prop->stryng->str))
  216. break;
  217. }
  218. if (cur) {
  219. *a_pair = cur;
  220. return CR_OK;
  221. }
  222. return CR_VALUE_NOT_FOUND_ERROR;
  223. }
  224. /**
  225. *Gets the next prop/decl pair in the list
  226. *@param a_this the current instance of CRPropList
  227. *@param the next prop/decl pair, or NULL if we
  228. *reached the end of the list.
  229. *@return the next prop/declaration pair of the list,
  230. *or NULL if we reached end of list (or if an error occurs)
  231. */
  232. CRPropList *
  233. cr_prop_list_get_next (CRPropList * a_this)
  234. {
  235. g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
  236. return PRIVATE (a_this)->next;
  237. }
  238. /**
  239. *Gets the previous prop/decl pair in the list
  240. *@param a_this the current instance of CRPropList
  241. *@param the previous prop/decl pair, or NULL if we
  242. *reached the end of the list.
  243. *@return the previous prop/declaration pair of the list,
  244. *or NULL if we reached end of list (or if an error occurs)
  245. */
  246. CRPropList *
  247. cr_prop_list_get_prev (CRPropList * a_this)
  248. {
  249. g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
  250. return PRIVATE (a_this)->prev;
  251. }
  252. /**
  253. *Unlinks a prop/decl pair from the list
  254. *@param a_this the current list of prop/decl pairs
  255. *@param a_pair the prop/decl pair to unlink.
  256. *@return the new list or NULL in case of an error.
  257. */
  258. CRPropList *
  259. cr_prop_list_unlink (CRPropList * a_this, CRPropList * a_pair)
  260. {
  261. CRPropList *prev = NULL,
  262. *next = NULL;
  263. g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pair, NULL);
  264. /*some sanity checks */
  265. if (PRIVATE (a_pair)->next) {
  266. next = PRIVATE (a_pair)->next;
  267. g_return_val_if_fail (PRIVATE (next), NULL);
  268. g_return_val_if_fail (PRIVATE (next)->prev == a_pair, NULL);
  269. }
  270. if (PRIVATE (a_pair)->prev) {
  271. prev = PRIVATE (a_pair)->prev;
  272. g_return_val_if_fail (PRIVATE (prev), NULL);
  273. g_return_val_if_fail (PRIVATE (prev)->next == a_pair, NULL);
  274. }
  275. if (prev) {
  276. PRIVATE (prev)->next = next;
  277. }
  278. if (next) {
  279. PRIVATE (next)->prev = prev;
  280. }
  281. PRIVATE (a_pair)->prev = PRIVATE (a_pair)->next = NULL;
  282. if (a_this == a_pair) {
  283. if (next)
  284. return next;
  285. return NULL;
  286. }
  287. return a_this;
  288. }
  289. void
  290. cr_prop_list_destroy (CRPropList * a_this)
  291. {
  292. CRPropList *tail = NULL,
  293. *cur = NULL;
  294. g_return_if_fail (a_this && PRIVATE (a_this));
  295. for (tail = a_this;
  296. tail && PRIVATE (tail) && PRIVATE (tail)->next;
  297. tail = cr_prop_list_get_next (tail)) ;
  298. g_return_if_fail (tail);
  299. cur = tail;
  300. while (cur) {
  301. tail = PRIVATE (cur)->prev;
  302. if (tail && PRIVATE (tail))
  303. PRIVATE (tail)->next = NULL;
  304. PRIVATE (cur)->prev = NULL;
  305. g_free (PRIVATE (cur));
  306. PRIVATE (cur) = NULL;
  307. g_free (cur);
  308. cur = tail;
  309. }
  310. }