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