Libcroco
|
00001 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ 00002 00003 /* 00004 * This file is part of The Croco Library 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of version 2.1 of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00018 * USA 00019 * 00020 * Author: Dodji Seketeli 00021 * See COPYRIGHTS file for copyright information. 00022 * 00023 */ 00024 00025 #include "cr-additional-sel.h" 00026 #include "string.h" 00027 00028 /** 00029 * CRAdditionalSel: 00030 * 00031 * #CRAdditionalSel abstracts an additionnal selector. 00032 * An additional selector is the selector part 00033 * that comes after the combination of type selectors. 00034 * It can be either "a class selector (the .class part), 00035 * a pseudo class selector, an attribute selector 00036 * or an id selector. 00037 */ 00038 00039 /** 00040 * cr_additional_sel_new: 00041 * 00042 * Default constructor of #CRAdditionalSel. 00043 * Returns the newly build instance of #CRAdditionalSel. 00044 */ 00045 CRAdditionalSel * 00046 cr_additional_sel_new (void) 00047 { 00048 CRAdditionalSel *result = NULL; 00049 00050 result = g_try_malloc (sizeof (CRAdditionalSel)); 00051 00052 if (result == NULL) { 00053 cr_utils_trace_debug ("Out of memory"); 00054 return NULL; 00055 } 00056 00057 memset (result, 0, sizeof (CRAdditionalSel)); 00058 00059 return result; 00060 } 00061 00062 /** 00063 * cr_additional_sel_new_with_type: 00064 * @a_sel_type: the type of the newly built instance 00065 * of #CRAdditionalSel. 00066 * 00067 * Constructor of #CRAdditionalSel. 00068 * Returns the newly built instance of #CRAdditionalSel. 00069 */ 00070 CRAdditionalSel * 00071 cr_additional_sel_new_with_type (enum AddSelectorType a_sel_type) 00072 { 00073 CRAdditionalSel *result = NULL; 00074 00075 result = cr_additional_sel_new (); 00076 00077 g_return_val_if_fail (result, NULL); 00078 00079 result->type = a_sel_type; 00080 00081 return result; 00082 } 00083 00084 /** 00085 * cr_additional_sel_set_class_name: 00086 * @a_this: the "this pointer" of the current instance 00087 * of #CRAdditionalSel . 00088 * @a_class_name: the new class name to set. 00089 * 00090 * Sets a new class name to a 00091 * CLASS additional selector. 00092 */ 00093 void 00094 cr_additional_sel_set_class_name (CRAdditionalSel * a_this, 00095 CRString * a_class_name) 00096 { 00097 g_return_if_fail (a_this && a_this->type == CLASS_ADD_SELECTOR); 00098 00099 if (a_this->content.class_name) { 00100 cr_string_destroy (a_this->content.class_name); 00101 } 00102 00103 a_this->content.class_name = a_class_name; 00104 } 00105 00106 /** 00107 * cr_additional_sel_set_id_name: 00108 * @a_this: the "this pointer" of the current instance 00109 * of #CRAdditionalSel . 00110 * @a_id: the new id to set. 00111 * 00112 * Sets a new id name to an 00113 * ID additional selector. 00114 */ 00115 void 00116 cr_additional_sel_set_id_name (CRAdditionalSel * a_this, CRString * a_id) 00117 { 00118 g_return_if_fail (a_this && a_this->type == ID_ADD_SELECTOR); 00119 00120 if (a_this->content.id_name) { 00121 cr_string_destroy (a_this->content.id_name); 00122 } 00123 00124 a_this->content.id_name = a_id; 00125 } 00126 00127 /** 00128 * cr_additional_sel_set_pseudo: 00129 * @a_this: the "this pointer" of the current instance 00130 * of #CRAdditionalSel . 00131 * @a_pseudo: the new pseudo to set. 00132 * 00133 * Sets a new pseudo to a 00134 * PSEUDO additional selector. 00135 */ 00136 void 00137 cr_additional_sel_set_pseudo (CRAdditionalSel * a_this, CRPseudo * a_pseudo) 00138 { 00139 g_return_if_fail (a_this 00140 && a_this->type == PSEUDO_CLASS_ADD_SELECTOR); 00141 00142 if (a_this->content.pseudo) { 00143 cr_pseudo_destroy (a_this->content.pseudo); 00144 } 00145 00146 a_this->content.pseudo = a_pseudo; 00147 } 00148 00149 /** 00150 * cr_additional_sel_set_attr_sel: 00151 * @a_this: the "this pointer" of the current instance 00152 * of #CRAdditionalSel . 00153 * @a_sel: the new instance of #CRAttrSel to set. 00154 * 00155 * Sets a new instance of #CRAttrSel to 00156 * a ATTRIBUTE additional selector. 00157 */ 00158 void 00159 cr_additional_sel_set_attr_sel (CRAdditionalSel * a_this, CRAttrSel * a_sel) 00160 { 00161 g_return_if_fail (a_this && a_this->type == ATTRIBUTE_ADD_SELECTOR); 00162 00163 if (a_this->content.attr_sel) { 00164 cr_attr_sel_destroy (a_this->content.attr_sel); 00165 } 00166 00167 a_this->content.attr_sel = a_sel; 00168 } 00169 00170 /** 00171 * cr_additional_sel_append: 00172 * @a_this: the "this pointer" of the current instance 00173 * of #CRAdditionalSel . 00174 * @a_sel: the new instance to #CRAdditional to append. 00175 * 00176 * Appends a new instance of #CRAdditional to the 00177 * current list of #CRAdditional. 00178 * 00179 * Returns the new list of CRAdditionalSel or NULL if an error arises. 00180 */ 00181 CRAdditionalSel * 00182 cr_additional_sel_append (CRAdditionalSel * a_this, CRAdditionalSel * a_sel) 00183 { 00184 CRAdditionalSel *cur_sel = NULL; 00185 00186 g_return_val_if_fail (a_sel, NULL); 00187 00188 if (a_this == NULL) { 00189 return a_sel; 00190 } 00191 00192 if (a_sel == NULL) 00193 return NULL; 00194 00195 for (cur_sel = a_this; 00196 cur_sel && cur_sel->next; cur_sel = cur_sel->next) ; 00197 00198 g_return_val_if_fail (cur_sel != NULL, NULL); 00199 00200 cur_sel->next = a_sel; 00201 a_sel->prev = cur_sel; 00202 00203 return a_this; 00204 } 00205 00206 /** 00207 * cr_additional_sel_prepend: 00208 * @a_this: the "this pointer" of the current instance 00209 * of #CRAdditionalSel . 00210 * @a_sel: the new instance to #CRAdditional to preappend. 00211 * 00212 * Preppends a new instance of #CRAdditional to the 00213 * current list of #CRAdditional. 00214 * 00215 * Returns the new list of CRAdditionalSel or NULL if an error arises. 00216 */ 00217 CRAdditionalSel * 00218 cr_additional_sel_prepend (CRAdditionalSel * a_this, CRAdditionalSel * a_sel) 00219 { 00220 g_return_val_if_fail (a_sel, NULL); 00221 00222 if (a_this == NULL) { 00223 return a_sel; 00224 } 00225 00226 a_sel->next = a_this; 00227 a_this->prev = a_sel; 00228 00229 return a_sel; 00230 } 00231 00232 guchar * 00233 cr_additional_sel_to_string (CRAdditionalSel const * a_this) 00234 { 00235 guchar *result = NULL; 00236 GString *str_buf = NULL; 00237 CRAdditionalSel const *cur = NULL; 00238 00239 g_return_val_if_fail (a_this, NULL); 00240 00241 str_buf = g_string_new (NULL); 00242 00243 for (cur = a_this; cur; cur = cur->next) { 00244 switch (cur->type) { 00245 case CLASS_ADD_SELECTOR: 00246 { 00247 guchar *name = NULL; 00248 00249 if (cur->content.class_name) { 00250 name = (guchar *) g_strndup 00251 (cur->content.class_name->stryng->str, 00252 cur->content.class_name->stryng->len); 00253 00254 if (name) { 00255 g_string_append_printf 00256 (str_buf, ".%s", 00257 name); 00258 g_free (name); 00259 name = NULL; 00260 } 00261 } 00262 } 00263 break; 00264 00265 case ID_ADD_SELECTOR: 00266 { 00267 guchar *name = NULL; 00268 00269 if (cur->content.id_name) { 00270 name = (guchar *) g_strndup 00271 (cur->content.id_name->stryng->str, 00272 cur->content.id_name->stryng->len); 00273 00274 if (name) { 00275 g_string_append_printf 00276 (str_buf, "#%s", 00277 name); 00278 g_free (name); 00279 name = NULL; 00280 } 00281 } 00282 } 00283 00284 break; 00285 00286 case PSEUDO_CLASS_ADD_SELECTOR: 00287 { 00288 if (cur->content.pseudo) { 00289 guchar *tmp_str = NULL; 00290 00291 tmp_str = cr_pseudo_to_string 00292 (cur->content.pseudo); 00293 if (tmp_str) { 00294 g_string_append_printf 00295 (str_buf, ":%s", 00296 tmp_str); 00297 g_free (tmp_str); 00298 tmp_str = NULL; 00299 } 00300 } 00301 } 00302 break; 00303 00304 case ATTRIBUTE_ADD_SELECTOR: 00305 if (cur->content.attr_sel) { 00306 guchar *tmp_str = NULL; 00307 00308 g_string_append_c (str_buf, '['); 00309 tmp_str = cr_attr_sel_to_string 00310 (cur->content.attr_sel); 00311 if (tmp_str) { 00312 g_string_append_printf 00313 (str_buf, "%s]", tmp_str); 00314 g_free (tmp_str); 00315 tmp_str = NULL; 00316 } 00317 } 00318 break; 00319 00320 default: 00321 break; 00322 } 00323 } 00324 00325 if (str_buf) { 00326 result = (guchar *) str_buf->str; 00327 g_string_free (str_buf, FALSE); 00328 str_buf = NULL; 00329 } 00330 00331 return result; 00332 } 00333 00334 guchar * 00335 cr_additional_sel_one_to_string (CRAdditionalSel const *a_this) 00336 { 00337 guchar *result = NULL; 00338 GString *str_buf = NULL; 00339 00340 g_return_val_if_fail (a_this, NULL) ; 00341 00342 str_buf = g_string_new (NULL) ; 00343 00344 switch (a_this->type) { 00345 case CLASS_ADD_SELECTOR: 00346 { 00347 guchar *name = NULL; 00348 00349 if (a_this->content.class_name) { 00350 name = (guchar *) g_strndup 00351 (a_this->content.class_name->stryng->str, 00352 a_this->content.class_name->stryng->len); 00353 00354 if (name) { 00355 g_string_append_printf 00356 (str_buf, ".%s", 00357 name); 00358 g_free (name); 00359 name = NULL; 00360 } 00361 } 00362 } 00363 break; 00364 00365 case ID_ADD_SELECTOR: 00366 { 00367 guchar *name = NULL; 00368 00369 if (a_this->content.id_name) { 00370 name = (guchar *) g_strndup 00371 (a_this->content.id_name->stryng->str, 00372 a_this->content.id_name->stryng->len); 00373 00374 if (name) { 00375 g_string_append_printf 00376 (str_buf, "#%s", 00377 name); 00378 g_free (name); 00379 name = NULL; 00380 } 00381 } 00382 } 00383 00384 break; 00385 00386 case PSEUDO_CLASS_ADD_SELECTOR: 00387 { 00388 if (a_this->content.pseudo) { 00389 guchar *tmp_str = NULL; 00390 00391 tmp_str = cr_pseudo_to_string 00392 (a_this->content.pseudo); 00393 if (tmp_str) { 00394 g_string_append_printf 00395 (str_buf, ":%s", 00396 tmp_str); 00397 g_free (tmp_str); 00398 tmp_str = NULL; 00399 } 00400 } 00401 } 00402 break; 00403 00404 case ATTRIBUTE_ADD_SELECTOR: 00405 if (a_this->content.attr_sel) { 00406 guchar *tmp_str = NULL; 00407 00408 g_string_append_printf (str_buf, "["); 00409 tmp_str = cr_attr_sel_to_string 00410 (a_this->content.attr_sel); 00411 if (tmp_str) { 00412 g_string_append_printf 00413 (str_buf, "%s]", tmp_str); 00414 g_free (tmp_str); 00415 tmp_str = NULL; 00416 } 00417 } 00418 break; 00419 00420 default: 00421 break; 00422 } 00423 00424 if (str_buf) { 00425 result = (guchar *) str_buf->str; 00426 g_string_free (str_buf, FALSE); 00427 str_buf = NULL; 00428 } 00429 00430 return result; 00431 } 00432 00433 /** 00434 * cr_additional_sel_dump: 00435 * @a_this: the "this pointer" of the current instance of 00436 * #CRAdditionalSel. 00437 * @a_fp: the destination file. 00438 * 00439 * Dumps the current instance of #CRAdditionalSel to a file 00440 */ 00441 void 00442 cr_additional_sel_dump (CRAdditionalSel const * a_this, FILE * a_fp) 00443 { 00444 guchar *tmp_str = NULL; 00445 00446 g_return_if_fail (a_fp); 00447 00448 if (a_this) { 00449 tmp_str = cr_additional_sel_to_string (a_this); 00450 if (tmp_str) { 00451 fprintf (a_fp, "%s", tmp_str); 00452 g_free (tmp_str); 00453 tmp_str = NULL; 00454 } 00455 } 00456 } 00457 00458 /** 00459 * cr_additional_sel_destroy: 00460 * @a_this: the "this pointer" of the current instance 00461 * of #CRAdditionalSel . 00462 * 00463 * Destroys an instance of #CRAdditional. 00464 */ 00465 void 00466 cr_additional_sel_destroy (CRAdditionalSel * a_this) 00467 { 00468 g_return_if_fail (a_this); 00469 00470 switch (a_this->type) { 00471 case CLASS_ADD_SELECTOR: 00472 cr_string_destroy (a_this->content.class_name); 00473 a_this->content.class_name = NULL; 00474 break; 00475 00476 case PSEUDO_CLASS_ADD_SELECTOR: 00477 cr_pseudo_destroy (a_this->content.pseudo); 00478 a_this->content.pseudo = NULL; 00479 break; 00480 00481 case ID_ADD_SELECTOR: 00482 cr_string_destroy (a_this->content.id_name); 00483 a_this->content.id_name = NULL; 00484 break; 00485 00486 case ATTRIBUTE_ADD_SELECTOR: 00487 cr_attr_sel_destroy (a_this->content.attr_sel); 00488 a_this->content.attr_sel = NULL; 00489 break; 00490 00491 default: 00492 break; 00493 } 00494 00495 if (a_this->next) { 00496 cr_additional_sel_destroy (a_this->next); 00497 } 00498 00499 g_free (a_this); 00500 }