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