00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <string.h>
00025 #include <glib.h>
00026 #include "cr-simple-sel.h"
00027
00028
00029
00030
00031
00032
00033 CRSimpleSel *
00034 cr_simple_sel_new (void)
00035 {
00036 CRSimpleSel *result = NULL;
00037
00038 result = g_try_malloc (sizeof (CRSimpleSel));
00039 if (!result) {
00040 cr_utils_trace_info ("Out of memory");
00041 return NULL;
00042 }
00043 memset (result, 0, sizeof (CRSimpleSel));
00044
00045 return result;
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055 CRSimpleSel *
00056 cr_simple_sel_append_simple_sel (CRSimpleSel * a_this, CRSimpleSel * a_sel)
00057 {
00058 CRSimpleSel *cur = NULL;
00059
00060 g_return_val_if_fail (a_sel, NULL);
00061
00062 if (a_this == NULL)
00063 return a_sel;
00064
00065 for (cur = a_this; cur->next; cur = cur->next) ;
00066
00067 cur->next = a_sel;
00068 a_sel->prev = cur;
00069
00070 return a_this;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079 CRSimpleSel *
00080 cr_simple_sel_prepend_simple_sel (CRSimpleSel * a_this, CRSimpleSel * a_sel)
00081 {
00082 g_return_val_if_fail (a_sel, NULL);
00083
00084 if (a_this == NULL)
00085 return a_sel;
00086
00087 a_sel->next = a_this;
00088 a_this->prev = a_sel;
00089
00090 return a_sel;
00091 }
00092
00093 guchar *
00094 cr_simple_sel_to_string (CRSimpleSel * a_this)
00095 {
00096 GString *str_buf = NULL;
00097 guchar *result = NULL;
00098
00099 CRSimpleSel *cur = NULL;
00100
00101 g_return_val_if_fail (a_this, NULL);
00102
00103 str_buf = g_string_new (NULL);
00104 for (cur = a_this; cur; cur = cur->next) {
00105 if (cur->name) {
00106 guchar *str = g_strndup (cur->name->stryng->str,
00107 cur->name->stryng->len);
00108
00109 if (str) {
00110 switch (cur->combinator) {
00111 case COMB_WS:
00112 g_string_append (str_buf, " ");
00113 break;
00114
00115 case COMB_PLUS:
00116 g_string_append (str_buf, "+");
00117 break;
00118
00119 case COMB_GT:
00120 g_string_append (str_buf, ">");
00121 break;
00122
00123 default:
00124 break;
00125 }
00126
00127 g_string_append (str_buf, str);
00128 g_free (str);
00129 str = NULL;
00130 }
00131 }
00132
00133 if (cur->add_sel) {
00134 guchar *tmp_str = NULL;
00135
00136 tmp_str = cr_additional_sel_to_string (cur->add_sel);
00137 if (tmp_str) {
00138 g_string_append (str_buf, tmp_str);
00139 g_free (tmp_str);
00140 tmp_str = NULL;
00141 }
00142 }
00143 }
00144
00145 if (str_buf) {
00146 result = str_buf->str;
00147 g_string_free (str_buf, FALSE);
00148 str_buf = NULL;
00149 }
00150
00151 return result;
00152 }
00153
00154
00155 guchar *
00156 cr_simple_sel_one_to_string (CRSimpleSel * a_this)
00157 {
00158 GString *str_buf = NULL;
00159 guchar *result = NULL;
00160
00161 g_return_val_if_fail (a_this, NULL);
00162
00163 str_buf = g_string_new (NULL);
00164 if (a_this->name) {
00165 guchar *str = g_strndup (a_this->name->stryng->str,
00166 a_this->name->stryng->len);
00167
00168 if (str) {
00169 g_string_append_printf (str_buf, "%s", str);
00170 g_free (str);
00171 str = NULL;
00172 }
00173 }
00174
00175 if (a_this->add_sel) {
00176 guchar *tmp_str = NULL;
00177
00178 tmp_str = cr_additional_sel_to_string (a_this->add_sel);
00179 if (tmp_str) {
00180 g_string_append_printf
00181 (str_buf, "%s", tmp_str);
00182 g_free (tmp_str);
00183 tmp_str = NULL;
00184 }
00185 }
00186
00187 if (str_buf) {
00188 result = str_buf->str;
00189 g_string_free (str_buf, FALSE);
00190 str_buf = NULL;
00191 }
00192
00193 return result;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 enum CRStatus
00206 cr_simple_sel_dump (CRSimpleSel * a_this, FILE * a_fp)
00207 {
00208 guchar *tmp_str = NULL;
00209
00210 g_return_val_if_fail (a_fp, CR_BAD_PARAM_ERROR);
00211
00212 if (a_this) {
00213 tmp_str = cr_simple_sel_to_string (a_this);
00214 if (tmp_str) {
00215 fprintf (a_fp, "%s", tmp_str);
00216 g_free (tmp_str);
00217 tmp_str = NULL;
00218 }
00219 }
00220
00221 return CR_OK;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230 enum CRStatus
00231 cr_simple_sel_compute_specificity (CRSimpleSel * a_this)
00232 {
00233 CRAdditionalSel *cur_add_sel = NULL;
00234 CRSimpleSel *cur_sel = NULL;
00235 gulong a = 0,
00236 b = 0,
00237 c = 0;
00238
00239 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
00240
00241 for (cur_sel = a_this; cur_sel; cur_sel = cur_sel->next) {
00242 if (cur_sel->type_mask | TYPE_SELECTOR) {
00243 c++;
00244 } else if (!cur_sel->name
00245 || !cur_sel->name->stryng
00246 || !cur_sel->name->stryng->str) {
00247 if (cur_sel->add_sel->type ==
00248 PSEUDO_CLASS_ADD_SELECTOR) {
00249
00250
00251
00252
00253 continue;
00254 }
00255 }
00256
00257 for (cur_add_sel = cur_sel->add_sel;
00258 cur_add_sel; cur_add_sel = cur_add_sel->next) {
00259 switch (cur_add_sel->type) {
00260 case ID_ADD_SELECTOR:
00261 a++;
00262 break;
00263
00264 case NO_ADD_SELECTOR:
00265 continue;
00266
00267 default:
00268 b++;
00269 break;
00270 }
00271 }
00272 }
00273
00274
00275 a_this->specificity = a * 1000000 + b * 1000 + c;
00276
00277 return CR_OK;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 void
00287 cr_simple_sel_destroy (CRSimpleSel * a_this)
00288 {
00289 g_return_if_fail (a_this);
00290
00291 if (a_this->name) {
00292 cr_string_destroy (a_this->name);
00293 a_this->name = NULL;
00294 }
00295
00296 if (a_this->add_sel) {
00297 cr_additional_sel_destroy (a_this->add_sel);
00298 a_this->add_sel = NULL;
00299 }
00300
00301 if (a_this->next) {
00302 cr_simple_sel_destroy (a_this->next);
00303 }
00304
00305 if (a_this) {
00306 g_free (a_this);
00307 }
00308 }