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