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 * See COPYRIGHTS file for copyrights information. 00021 */ 00022 00023 #include <stdio.h> 00024 #include "cr-attr-sel.h" 00025 00026 /** 00027 * CRAttrSel: 00028 * 00029 * #CRAdditionalSel abstracts an attribute selector. 00030 * Attributes selectors are described in the css2 spec [5.8]. 00031 * There are more generally used in the css2 selectors described in 00032 * css2 spec [5] . 00033 */ 00034 00035 /** 00036 * cr_attr_sel_new: 00037 * The constructor of #CRAttrSel. 00038 * Returns the newly allocated instance 00039 * of #CRAttrSel. 00040 */ 00041 CRAttrSel * 00042 cr_attr_sel_new (void) 00043 { 00044 CRAttrSel *result = NULL; 00045 00046 result = g_malloc0 (sizeof (CRAttrSel)); 00047 00048 return result; 00049 } 00050 00051 /** 00052 * cr_attr_sel_append_attr_sel: 00053 * @a_this: the this pointer of the current instance of #CRAttrSel. 00054 * @a_attr_sel: selector to append. 00055 * 00056 * Appends an attribute selector to the current list of 00057 * attribute selectors represented by a_this. 00058 * Returns CR_OK upon successfull completion, an error code otherwise. 00059 */ 00060 enum CRStatus 00061 cr_attr_sel_append_attr_sel (CRAttrSel * a_this, CRAttrSel * a_attr_sel) 00062 { 00063 CRAttrSel *cur_sel = NULL; 00064 00065 g_return_val_if_fail (a_this && a_attr_sel, 00066 CR_BAD_PARAM_ERROR); 00067 00068 for (cur_sel = a_this; 00069 cur_sel->next; 00070 cur_sel = cur_sel->next) ; 00071 00072 cur_sel->next = a_attr_sel; 00073 a_attr_sel->prev = cur_sel; 00074 00075 return CR_OK; 00076 } 00077 00078 /** 00079 * cr_attr_sel_prepend_attr_sel: 00080 *@a_this: the "this pointer" of the current instance *of #CRAttrSel. 00081 *@a_attr_sel: the attribute selector to append. 00082 * 00083 *Prepends an attribute selector to the list of 00084 *attributes selector represented by a_this. 00085 *Returns CR_OK upon successfull completion, an error code otherwise. 00086 */ 00087 enum CRStatus 00088 cr_attr_sel_prepend_attr_sel (CRAttrSel * a_this, 00089 CRAttrSel * a_attr_sel) 00090 { 00091 g_return_val_if_fail (a_this && a_attr_sel, 00092 CR_BAD_PARAM_ERROR); 00093 00094 a_attr_sel->next = a_this; 00095 a_this->prev = a_attr_sel; 00096 00097 return CR_OK; 00098 } 00099 00100 /** 00101 * cr_attr_sel_to_string: 00102 * @a_this: the current instance of #CRAttrSel. 00103 * 00104 * Serializes an attribute selector into a string 00105 * Returns the serialized attribute selector. 00106 */ 00107 guchar * 00108 cr_attr_sel_to_string (CRAttrSel const * a_this) 00109 { 00110 CRAttrSel const *cur = NULL; 00111 guchar *result = NULL; 00112 GString *str_buf = NULL; 00113 00114 g_return_val_if_fail (a_this, NULL); 00115 00116 str_buf = g_string_new (NULL); 00117 00118 for (cur = a_this; cur; cur = cur->next) { 00119 if (cur->prev) { 00120 g_string_append_c (str_buf, ' '); 00121 } 00122 00123 if (cur->name) { 00124 guchar *name = NULL; 00125 00126 name = g_strndup (cur->name->stryng->str, 00127 cur->name->stryng->len); 00128 if (name) { 00129 g_string_append (str_buf, name); 00130 g_free (name); 00131 name = NULL; 00132 } 00133 } 00134 00135 if (cur->value) { 00136 guchar *value = NULL; 00137 00138 value = g_strndup (cur->value->stryng->str, 00139 cur->value->stryng->len); 00140 if (value) { 00141 switch (cur->match_way) { 00142 case SET: 00143 break; 00144 00145 case EQUALS: 00146 g_string_append_c (str_buf, '='); 00147 break; 00148 00149 case INCLUDES: 00150 g_string_append (str_buf, "~="); 00151 break; 00152 00153 case DASHMATCH: 00154 g_string_append (str_buf, "|="); 00155 break; 00156 00157 default: 00158 break; 00159 } 00160 00161 g_string_append_printf 00162 (str_buf, "\"%s\"", value); 00163 00164 g_free (value); 00165 value = NULL; 00166 } 00167 } 00168 } 00169 00170 if (str_buf) { 00171 result = str_buf->str; 00172 g_string_free (str_buf, FALSE); 00173 } 00174 00175 return result; 00176 } 00177 00178 /** 00179 * cr_attr_sel_dump: 00180 * @a_this: the "this pointer" of the current instance of 00181 * #CRAttrSel. 00182 * @a_fp: the destination file. 00183 * 00184 * Dumps the current instance of #CRAttrSel to a file. 00185 */ 00186 void 00187 cr_attr_sel_dump (CRAttrSel const * a_this, FILE * a_fp) 00188 { 00189 guchar *tmp_str = NULL; 00190 00191 g_return_if_fail (a_this); 00192 00193 tmp_str = cr_attr_sel_to_string (a_this); 00194 00195 if (tmp_str) { 00196 fprintf (a_fp, "%s", tmp_str); 00197 g_free (tmp_str); 00198 tmp_str = NULL; 00199 } 00200 } 00201 00202 /** 00203 *cr_attr_sel_destroy: 00204 *@a_this: the "this pointer" of the current 00205 *instance of #CRAttrSel. 00206 * 00207 *Destroys the current instance of #CRAttrSel. 00208 *Frees all the fields if they are non null. 00209 */ 00210 void 00211 cr_attr_sel_destroy (CRAttrSel * a_this) 00212 { 00213 g_return_if_fail (a_this); 00214 00215 if (a_this->name) { 00216 cr_string_destroy (a_this->name); 00217 a_this->name = NULL; 00218 } 00219 00220 if (a_this->value) { 00221 cr_string_destroy (a_this->value); 00222 a_this->value = NULL; 00223 } 00224 00225 if (a_this->next) { 00226 cr_attr_sel_destroy (a_this->next); 00227 a_this->next = NULL; 00228 } 00229 00230 if (a_this) { 00231 g_free (a_this); 00232 a_this = NULL; 00233 } 00234 } 00235