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
00028
00029
00030 #include "string.h"
00031 #include "cr-tknzr.h"
00032 #include "cr-doc-handler.h"
00033
00034 struct _CRTknzrPriv {
00035
00036 CRInput *input;
00037
00038
00039
00040
00041
00042
00043
00044
00045 CRToken *token_cache;
00046
00047
00048
00049
00050
00051 CRInputPos prev_pos;
00052
00053 CRDocHandler *sac_handler;
00054
00055
00056
00057
00058
00059
00060 glong ref_count;
00061 };
00062
00063 #define PRIVATE(obj) ((obj)->priv)
00064
00065
00066
00067
00068
00069 #define IS_NUM(a_char) (((a_char) >= '0' && (a_char) <= '9')?TRUE:FALSE)
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #define CHECK_PARSING_STATUS(status, is_exception) \
00081 if ((status) != CR_OK) \
00082 { \
00083 if (is_exception == FALSE) \
00084 { \
00085 status = CR_PARSING_ERROR ; \
00086 } \
00087 goto error ; \
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 #define PEEK_NEXT_CHAR(a_tknzr, a_to_char) \
00100 {\
00101 status = cr_tknzr_peek_char (a_tknzr, a_to_char) ; \
00102 CHECK_PARSING_STATUS (status, TRUE) \
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 #define READ_NEXT_CHAR(a_tknzr, to_char) \
00114 status = cr_tknzr_read_char (a_tknzr, to_char) ;\
00115 CHECK_PARSING_STATUS (status, TRUE)
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 #define RECORD_INITIAL_POS(a_tknzr, a_pos) \
00128 status = cr_input_get_cur_pos (PRIVATE \
00129 (a_tknzr)->input, a_pos) ; \
00130 g_return_val_if_fail (status == CR_OK, status)
00131
00132
00133
00134
00135
00136
00137
00138
00139 #define RECORD_CUR_BYTE_ADDR(a_tknzr, a_addr) \
00140 status = cr_input_get_cur_byte_addr \
00141 (PRIVATE (a_tknzr)->input, a_addr) ; \
00142 CHECK_PARSING_STATUS (status, TRUE)
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 #define PEEK_BYTE(a_tknzr, a_offset, a_byte_ptr) \
00156 status = cr_tknzr_peek_byte (a_tknzr, \
00157 a_offset, \
00158 a_byte_ptr) ; \
00159 CHECK_PARSING_STATUS (status, TRUE) ;
00160
00161 #define BYTE(a_input, a_n, a_eof) \
00162 cr_input_peek_byte2 (a_input, a_n, a_eof)
00163
00164
00165
00166
00167
00168
00169
00170
00171 #define READ_NEXT_BYTE(a_tknzr, a_byte_ptr) \
00172 status = \
00173 cr_input_read_byte (PRIVATE (a_tknzr)->input, a_byte_ptr) ;\
00174 CHECK_PARSING_STATUS (status, TRUE) ;
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 #define SKIP_BYTES(a_tknzr, a_nb_bytes) \
00185 status = cr_input_seek_index (PRIVATE (a_tknzr)->input, \
00186 CR_SEEK_CUR, a_nb_bytes) ; \
00187 CHECK_PARSING_STATUS (status, TRUE) ;
00188
00189
00190
00191
00192
00193
00194
00195
00196 #define SKIP_CHARS(a_tknzr, a_nb_chars) \
00197 { \
00198 glong nb_chars = a_nb_chars ; \
00199 status = cr_input_consume_chars \
00200 (PRIVATE (a_tknzr)->input,0, &nb_chars) ; \
00201 CHECK_PARSING_STATUS (status, TRUE) ; \
00202 }
00203
00204
00205
00206
00207
00208
00209
00210 #define ENSURE_PARSING_COND(condition) \
00211 if (! (condition)) {status = CR_PARSING_ERROR; goto error ;}
00212
00213 static enum CRStatus cr_tknzr_parse_nl (CRTknzr * a_this,
00214 guchar ** a_start,
00215 guchar ** a_end,
00216 CRParsingLocation *a_location);
00217
00218 static enum CRStatus cr_tknzr_parse_w (CRTknzr * a_this,
00219 guchar ** a_start,
00220 guchar ** a_end,
00221 CRParsingLocation *a_location) ;
00222
00223 static enum CRStatus cr_tknzr_parse_unicode_escape (CRTknzr * a_this,
00224 guint32 * a_unicode,
00225 CRParsingLocation *a_location) ;
00226
00227 static enum CRStatus cr_tknzr_parse_escape (CRTknzr * a_this,
00228 guint32 * a_esc_code,
00229 CRParsingLocation *a_location);
00230
00231 static enum CRStatus cr_tknzr_parse_string (CRTknzr * a_this,
00232 CRString ** a_str);
00233
00234 static enum CRStatus cr_tknzr_parse_comment (CRTknzr * a_this,
00235 CRString ** a_comment);
00236
00237 static enum CRStatus cr_tknzr_parse_nmstart (CRTknzr * a_this,
00238 guint32 * a_char,
00239 CRParsingLocation *a_location);
00240
00241 static enum CRStatus cr_tknzr_parse_num (CRTknzr * a_this,
00242 CRNum ** a_num);
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 static enum CRStatus
00261 cr_tknzr_parse_w (CRTknzr * a_this,
00262 guchar ** a_start,
00263 guchar ** a_end,
00264 CRParsingLocation *a_location)
00265 {
00266 guint32 cur_char = 0;
00267 CRInputPos init_pos;
00268 enum CRStatus status = CR_OK;
00269
00270 g_return_val_if_fail (a_this && PRIVATE (a_this)
00271 && PRIVATE (a_this)->input
00272 && a_start && a_end,
00273 CR_BAD_PARAM_ERROR);
00274
00275 RECORD_INITIAL_POS (a_this, &init_pos);
00276
00277 *a_start = NULL;
00278 *a_end = NULL;
00279
00280 READ_NEXT_CHAR (a_this, &cur_char);
00281
00282 if (cr_utils_is_white_space (cur_char) == FALSE) {
00283 status = CR_PARSING_ERROR;
00284 goto error;
00285 }
00286 if (a_location) {
00287 cr_tknzr_get_parsing_location (a_this,
00288 a_location) ;
00289 }
00290 RECORD_CUR_BYTE_ADDR (a_this, a_start);
00291 *a_end = *a_start;
00292
00293 for (;;) {
00294 gboolean is_eof = FALSE;
00295
00296 cr_input_get_end_of_file (PRIVATE (a_this)->input, &is_eof);
00297 if (is_eof)
00298 break;
00299
00300 status = cr_tknzr_peek_char (a_this, &cur_char);
00301 if (status == CR_END_OF_INPUT_ERROR) {
00302 status = CR_OK;
00303 break;
00304 } else if (status != CR_OK) {
00305 goto error;
00306 }
00307
00308 if (cr_utils_is_white_space (cur_char) == TRUE) {
00309 READ_NEXT_CHAR (a_this, &cur_char);
00310 RECORD_CUR_BYTE_ADDR (a_this, a_end);
00311 } else {
00312 break;
00313 }
00314 }
00315
00316 return CR_OK;
00317
00318 error:
00319 cr_tknzr_set_cur_pos (a_this, &init_pos);
00320
00321 return status;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 static enum CRStatus
00336 cr_tknzr_parse_nl (CRTknzr * a_this,
00337 guchar ** a_start,
00338 guchar ** a_end,
00339 CRParsingLocation *a_location)
00340 {
00341 CRInputPos init_pos;
00342 guchar next_chars[2] = { 0 };
00343 enum CRStatus status = CR_PARSING_ERROR;
00344
00345 g_return_val_if_fail (a_this && PRIVATE (a_this)
00346 && a_start && a_end, CR_BAD_PARAM_ERROR);
00347
00348 RECORD_INITIAL_POS (a_this, &init_pos);
00349
00350 PEEK_BYTE (a_this, 1, &next_chars[0]);
00351 PEEK_BYTE (a_this, 2, &next_chars[1]);
00352
00353 if ((next_chars[0] == '\r' && next_chars[1] == '\n')) {
00354 SKIP_BYTES (a_this, 1);
00355 if (a_location) {
00356 cr_tknzr_get_parsing_location
00357 (a_this, a_location) ;
00358 }
00359 SKIP_CHARS (a_this, 1);
00360
00361 RECORD_CUR_BYTE_ADDR (a_this, a_end);
00362
00363 status = CR_OK;
00364 } else if (next_chars[0] == '\n'
00365 || next_chars[0] == '\r' || next_chars[0] == '\f') {
00366 SKIP_CHARS (a_this, 1);
00367 if (a_location) {
00368 cr_tknzr_get_parsing_location
00369 (a_this, a_location) ;
00370 }
00371 RECORD_CUR_BYTE_ADDR (a_this, a_start);
00372 *a_end = *a_start;
00373 status = CR_OK;
00374 } else {
00375 status = CR_PARSING_ERROR;
00376 goto error;
00377 }
00378 return CR_OK ;
00379
00380 error:
00381 cr_tknzr_set_cur_pos (a_this, &init_pos) ;
00382 return status;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 static enum CRStatus
00394 cr_tknzr_try_to_skip_spaces (CRTknzr * a_this)
00395 {
00396 enum CRStatus status = CR_ERROR;
00397 guint32 cur_char = 0;
00398
00399 g_return_val_if_fail (a_this && PRIVATE (a_this)
00400 && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR);
00401
00402 status = cr_input_peek_char (PRIVATE (a_this)->input, &cur_char);
00403
00404 if (status != CR_OK) {
00405 if (status == CR_END_OF_INPUT_ERROR)
00406 return CR_OK;
00407 return status;
00408 }
00409
00410 if (cr_utils_is_white_space (cur_char) == TRUE) {
00411 glong nb_chars = -1;
00412
00413 status = cr_input_consume_white_spaces
00414 (PRIVATE (a_this)->input, &nb_chars);
00415 }
00416
00417 return status;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 static enum CRStatus
00430 cr_tknzr_parse_comment (CRTknzr * a_this,
00431 CRString ** a_comment)
00432 {
00433 enum CRStatus status = CR_OK;
00434 CRInputPos init_pos;
00435 guint32 cur_char = 0, next_char= 0;
00436 CRString *comment = NULL;
00437 CRParsingLocation loc = {0} ;
00438
00439 g_return_val_if_fail (a_this && PRIVATE (a_this)
00440 && PRIVATE (a_this)->input,
00441 CR_BAD_PARAM_ERROR);
00442
00443 RECORD_INITIAL_POS (a_this, &init_pos);
00444 READ_NEXT_CHAR (a_this, &cur_char) ;
00445 ENSURE_PARSING_COND (cur_char == '/');
00446 cr_tknzr_get_parsing_location (a_this, &loc) ;
00447
00448 READ_NEXT_CHAR (a_this, &cur_char);
00449 ENSURE_PARSING_COND (cur_char == '*');
00450 comment = cr_string_new ();
00451 for (;;) {
00452 READ_NEXT_CHAR (a_this, &cur_char);
00453
00454
00455 if (cur_char == '/') {
00456 READ_NEXT_CHAR (a_this, &cur_char);
00457 ENSURE_PARSING_COND (cur_char != '*');
00458 g_string_append_c (comment->stryng, '/');
00459 g_string_append_unichar (comment->stryng,
00460 cur_char);
00461 continue;
00462 }
00463
00464
00465 if (cur_char == '*') {
00466 PEEK_NEXT_CHAR (a_this, &next_char);
00467
00468 if (next_char == '/') {
00469
00470
00471
00472
00473 SKIP_CHARS (a_this, 1) ;
00474 status = CR_OK;
00475 break;
00476 } else {
00477 g_string_append_c (comment->stryng,
00478 '*');
00479 }
00480 }
00481 g_string_append_unichar (comment->stryng, cur_char);
00482 }
00483
00484 if (status == CR_OK) {
00485 cr_parsing_location_copy (&comment->location,
00486 &loc) ;
00487 *a_comment = comment;
00488 return CR_OK;
00489 }
00490 error:
00491
00492 if (comment) {
00493 cr_string_destroy (comment);
00494 comment = NULL;
00495 }
00496
00497 cr_tknzr_set_cur_pos (a_this, &init_pos);
00498
00499 return status;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 static enum CRStatus
00519 cr_tknzr_parse_unicode_escape (CRTknzr * a_this,
00520 guint32 * a_unicode,
00521 CRParsingLocation *a_location)
00522 {
00523 guint32 cur_char;
00524 CRInputPos init_pos;
00525 glong occur = 0;
00526 guint32 unicode = 0;
00527 guchar *tmp_char_ptr1 = NULL,
00528 *tmp_char_ptr2 = NULL;
00529 enum CRStatus status = CR_OK;
00530
00531 g_return_val_if_fail (a_this && PRIVATE (a_this)
00532 && a_unicode, CR_BAD_PARAM_ERROR);
00533
00534
00535 RECORD_INITIAL_POS (a_this, &init_pos);
00536
00537 READ_NEXT_CHAR (a_this, &cur_char);
00538
00539 if (cur_char != '\\') {
00540 status = CR_PARSING_ERROR;
00541 goto error;
00542 }
00543 if (a_location) {
00544 cr_tknzr_get_parsing_location
00545 (a_this, a_location) ;
00546 }
00547 PEEK_NEXT_CHAR (a_this, &cur_char);
00548
00549 for (occur = 0, unicode = 0; ((cur_char >= '0' && cur_char <= '9')
00550 || (cur_char >= 'a' && cur_char <= 'f')
00551 || (cur_char >= 'A' && cur_char <= 'F'))
00552 && occur < 6; occur++) {
00553 gint cur_char_val = 0;
00554
00555 READ_NEXT_CHAR (a_this, &cur_char);
00556
00557 if ((cur_char >= '0' && cur_char <= '9')) {
00558 cur_char_val = (cur_char - '0');
00559 } else if ((cur_char >= 'a' && cur_char <= 'f')) {
00560 cur_char_val = 10 + (cur_char - 'a');
00561 } else if ((cur_char >= 'A' && cur_char <= 'F')) {
00562 cur_char_val = 10 + (cur_char - 'A');
00563 }
00564
00565 unicode = unicode * 10 + cur_char_val;
00566
00567 PEEK_NEXT_CHAR (a_this, &cur_char);
00568 }
00569
00570 if (occur == 5) {
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 cr_tknzr_parse_w (a_this, &tmp_char_ptr1,
00581 &tmp_char_ptr2, NULL);
00582 status = CR_OK;
00583 } else {
00584
00585
00586
00587
00588
00589
00590 status = cr_tknzr_parse_w (a_this, &tmp_char_ptr1,
00591 &tmp_char_ptr2, NULL);
00592 }
00593
00594 if (status == CR_OK) {
00595 *a_unicode = unicode;
00596 return CR_OK;
00597 }
00598
00599 error:
00600
00601
00602
00603
00604 cr_tknzr_set_cur_pos (a_this, &init_pos);
00605
00606 return status;
00607 }
00608
00609
00610
00611
00612
00613
00614 static enum CRStatus
00615 cr_tknzr_parse_escape (CRTknzr * a_this, guint32 * a_esc_code,
00616 CRParsingLocation *a_location)
00617 {
00618 enum CRStatus status = CR_OK;
00619 guint32 cur_char = 0;
00620 CRInputPos init_pos;
00621 guchar next_chars[2];
00622
00623 g_return_val_if_fail (a_this && PRIVATE (a_this)
00624 && a_esc_code, CR_BAD_PARAM_ERROR);
00625
00626 RECORD_INITIAL_POS (a_this, &init_pos);
00627
00628 PEEK_BYTE (a_this, 1, &next_chars[0]);
00629 PEEK_BYTE (a_this, 2, &next_chars[1]);
00630
00631 if (next_chars[0] != '\\') {
00632 status = CR_PARSING_ERROR;
00633 goto error;
00634 }
00635
00636 if ((next_chars[1] >= '0' && next_chars[1] <= '9')
00637 || (next_chars[1] >= 'a' && next_chars[1] <= 'f')
00638 || (next_chars[1] >= 'A' && next_chars[1] <= 'F')) {
00639 status = cr_tknzr_parse_unicode_escape (a_this, a_esc_code,
00640 a_location);
00641 } else {
00642
00643 READ_NEXT_CHAR (a_this, &cur_char);
00644 if (a_location) {
00645 cr_tknzr_get_parsing_location (a_this,
00646 a_location) ;
00647 }
00648
00649 READ_NEXT_CHAR (a_this, &cur_char);
00650
00651 if (cur_char != ' ' && (cur_char < 200 || cur_char > 4177777)) {
00652 status = CR_PARSING_ERROR;
00653 goto error;
00654 }
00655 *a_esc_code = cur_char;
00656
00657 }
00658 if (status == CR_OK) {
00659 return CR_OK;
00660 }
00661 error:
00662 cr_tknzr_set_cur_pos (a_this, &init_pos);
00663 return status;
00664 }
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 static enum CRStatus
00682 cr_tknzr_parse_string (CRTknzr * a_this, CRString ** a_str)
00683 {
00684 guint32 cur_char = 0,
00685 delim = 0;
00686 CRInputPos init_pos;
00687 enum CRStatus status = CR_OK;
00688 CRString *str = NULL;
00689
00690 g_return_val_if_fail (a_this && PRIVATE (a_this)
00691 && PRIVATE (a_this)->input
00692 && a_str, CR_BAD_PARAM_ERROR);
00693
00694 RECORD_INITIAL_POS (a_this, &init_pos);
00695 READ_NEXT_CHAR (a_this, &cur_char);
00696
00697 if (cur_char == '"')
00698 delim = '"';
00699 else if (cur_char == '\'')
00700 delim = '\'';
00701 else {
00702 status = CR_PARSING_ERROR;
00703 goto error;
00704 }
00705 str = cr_string_new ();
00706 if (str) {
00707 cr_tknzr_get_parsing_location
00708 (a_this, &str->location) ;
00709 }
00710 for (;;) {
00711 guchar next_chars[2] = { 0 };
00712
00713 PEEK_BYTE (a_this, 1, &next_chars[0]);
00714 PEEK_BYTE (a_this, 2, &next_chars[1]);
00715
00716 if (next_chars[0] == '\\') {
00717 guchar *tmp_char_ptr1 = NULL,
00718 *tmp_char_ptr2 = NULL;
00719 guint32 esc_code = 0;
00720
00721 if (next_chars[1] == '\'' || next_chars[1] == '"') {
00722 g_string_append_unichar (str->stryng,
00723 next_chars[1]);
00724 SKIP_BYTES (a_this, 2);
00725 status = CR_OK;
00726 } else {
00727 status = cr_tknzr_parse_escape
00728 (a_this, &esc_code, NULL);
00729
00730 if (status == CR_OK) {
00731 g_string_append_unichar
00732 (str->stryng,
00733 esc_code);
00734 }
00735 }
00736
00737 if (status != CR_OK) {
00738
00739
00740
00741
00742 READ_NEXT_CHAR (a_this, &cur_char);
00743
00744 status = cr_tknzr_parse_nl
00745 (a_this, &tmp_char_ptr1,
00746 &tmp_char_ptr2, NULL);
00747 }
00748
00749 CHECK_PARSING_STATUS (status, FALSE);
00750 } else if (strchr ("\t !#$%&", next_chars[0])
00751 || (next_chars[0] >= '(' && next_chars[0] <= '~')) {
00752 READ_NEXT_CHAR (a_this, &cur_char);
00753 g_string_append_unichar (str->stryng,
00754 cur_char);
00755 status = CR_OK;
00756 }
00757
00758 else if (cr_utils_is_nonascii (next_chars[0])) {
00759 READ_NEXT_CHAR (a_this, &cur_char);
00760 g_string_append_unichar (str->stryng, cur_char);
00761 } else if (next_chars[0] == delim) {
00762 READ_NEXT_CHAR (a_this, &cur_char);
00763 break;
00764 } else {
00765 status = CR_PARSING_ERROR;
00766 goto error;
00767 }
00768 }
00769
00770 if (status == CR_OK) {
00771 if (*a_str == NULL) {
00772 *a_str = str;
00773 str = NULL;
00774 } else {
00775 (*a_str)->stryng = g_string_append_len
00776 ((*a_str)->stryng,
00777 str->stryng->str,
00778 str->stryng->len);
00779 cr_string_destroy (str);
00780 }
00781 return CR_OK;
00782 }
00783
00784 error:
00785
00786 if (str) {
00787 cr_string_destroy (str) ;
00788 str = NULL;
00789 }
00790 cr_tknzr_set_cur_pos (a_this, &init_pos);
00791 return status;
00792 }
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 static enum CRStatus
00808 cr_tknzr_parse_nmstart (CRTknzr * a_this,
00809 guint32 * a_char,
00810 CRParsingLocation *a_location)
00811 {
00812 CRInputPos init_pos;
00813 enum CRStatus status = CR_OK;
00814 guint32 cur_char = 0,
00815 next_char = 0;
00816
00817 g_return_val_if_fail (a_this && PRIVATE (a_this)
00818 && PRIVATE (a_this)->input
00819 && a_char, CR_BAD_PARAM_ERROR);
00820
00821 RECORD_INITIAL_POS (a_this, &init_pos);
00822
00823 PEEK_NEXT_CHAR (a_this, &next_char);
00824
00825 if (next_char == '\\') {
00826 status = cr_tknzr_parse_escape (a_this, a_char,
00827 a_location);
00828
00829 if (status != CR_OK)
00830 goto error;
00831
00832 } else if (cr_utils_is_nonascii (next_char) == TRUE
00833 || ((next_char >= 'a') && (next_char <= 'z'))
00834 || ((next_char >= 'A') && (next_char <= 'Z'))
00835 ) {
00836 READ_NEXT_CHAR (a_this, &cur_char);
00837 if (a_location) {
00838 cr_tknzr_get_parsing_location (a_this,
00839 a_location) ;
00840 }
00841 *a_char = cur_char;
00842 status = CR_OK;
00843 } else {
00844 status = CR_PARSING_ERROR;
00845 goto error;
00846 }
00847
00848 return CR_OK;
00849
00850 error:
00851 cr_tknzr_set_cur_pos (a_this, &init_pos);
00852
00853 return status;
00854
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 static enum CRStatus
00875 cr_tknzr_parse_nmchar (CRTknzr * a_this, guint32 * a_char,
00876 CRParsingLocation *a_location)
00877 {
00878 guint32 cur_char = 0,
00879 next_char = 0;
00880 enum CRStatus status = CR_OK;
00881 CRInputPos init_pos;
00882
00883 g_return_val_if_fail (a_this && PRIVATE (a_this) && a_char,
00884 CR_BAD_PARAM_ERROR);
00885
00886 RECORD_INITIAL_POS (a_this, &init_pos);
00887
00888 status = cr_input_peek_char (PRIVATE (a_this)->input,
00889 &next_char) ;
00890 if (status != CR_OK)
00891 goto error;
00892
00893 if (next_char == '\\') {
00894 status = cr_tknzr_parse_escape (a_this, a_char,
00895 a_location);
00896
00897 if (status != CR_OK)
00898 goto error;
00899
00900 } else if (cr_utils_is_nonascii (next_char) == TRUE
00901 || ((next_char >= 'a') && (next_char <= 'z'))
00902 || ((next_char >= 'A') && (next_char <= 'Z'))
00903 || ((next_char >= '0') && (next_char <= '9'))
00904 || (next_char == '-')
00905 || (next_char == '_')
00906 ) {
00907 READ_NEXT_CHAR (a_this, &cur_char);
00908 *a_char = cur_char;
00909 status = CR_OK;
00910 if (a_location) {
00911 cr_tknzr_get_parsing_location
00912 (a_this, a_location) ;
00913 }
00914 } else {
00915 status = CR_PARSING_ERROR;
00916 goto error;
00917 }
00918 return CR_OK;
00919
00920 error:
00921 cr_tknzr_set_cur_pos (a_this, &init_pos);
00922 return status;
00923 }
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 static enum CRStatus
00942 cr_tknzr_parse_ident (CRTknzr * a_this, CRString ** a_str)
00943 {
00944 guint32 tmp_char = 0;
00945 CRString *stringue = NULL ;
00946 CRInputPos init_pos;
00947 enum CRStatus status = CR_OK;
00948 gboolean location_is_set = FALSE ;
00949
00950 g_return_val_if_fail (a_this && PRIVATE (a_this)
00951 && PRIVATE (a_this)->input
00952 && a_str, CR_BAD_PARAM_ERROR);
00953
00954 RECORD_INITIAL_POS (a_this, &init_pos);
00955 PEEK_NEXT_CHAR (a_this, &tmp_char) ;
00956 stringue = cr_string_new () ;
00957 g_return_val_if_fail (stringue,
00958 CR_OUT_OF_MEMORY_ERROR) ;
00959
00960 if (tmp_char == '-') {
00961 READ_NEXT_CHAR (a_this, &tmp_char) ;
00962 cr_tknzr_get_parsing_location
00963 (a_this, &stringue->location) ;
00964 location_is_set = TRUE ;
00965 g_string_append_unichar (stringue->stryng,
00966 tmp_char) ;
00967 }
00968 status = cr_tknzr_parse_nmstart (a_this, &tmp_char, NULL);
00969 if (status != CR_OK) {
00970 status = CR_PARSING_ERROR;
00971 goto end ;
00972 }
00973 if (location_is_set == FALSE) {
00974 cr_tknzr_get_parsing_location
00975 (a_this, &stringue->location) ;
00976 location_is_set = TRUE ;
00977 }
00978 g_string_append_unichar (stringue->stryng, tmp_char);
00979 for (;;) {
00980 status = cr_tknzr_parse_nmchar (a_this,
00981 &tmp_char,
00982 NULL);
00983 if (status != CR_OK) {
00984 status = CR_OK ;
00985 break;
00986 }
00987 g_string_append_unichar (stringue->stryng, tmp_char);
00988 }
00989 if (status == CR_OK) {
00990 if (!*a_str) {
00991 *a_str = stringue ;
00992
00993 } else {
00994 g_string_append_len ((*a_str)->stryng,
00995 stringue->stryng->str,
00996 stringue->stryng->len) ;
00997 cr_string_destroy (stringue) ;
00998 }
00999 stringue = NULL ;
01000 }
01001
01002 error:
01003 end:
01004 if (stringue) {
01005 cr_string_destroy (stringue) ;
01006 stringue = NULL ;
01007 }
01008 if (status != CR_OK ) {
01009 cr_tknzr_set_cur_pos (a_this, &init_pos) ;
01010 }
01011 return status ;
01012 }
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028 static enum CRStatus
01029 cr_tknzr_parse_name (CRTknzr * a_this,
01030 CRString ** a_str)
01031 {
01032 guint32 tmp_char = 0;
01033 CRInputPos init_pos;
01034 enum CRStatus status = CR_OK;
01035 gboolean str_needs_free = FALSE,
01036 is_first_nmchar=TRUE ;
01037 glong i = 0;
01038 CRParsingLocation loc = {0} ;
01039
01040 g_return_val_if_fail (a_this && PRIVATE (a_this)
01041 && PRIVATE (a_this)->input
01042 && a_str,
01043 CR_BAD_PARAM_ERROR) ;
01044
01045 RECORD_INITIAL_POS (a_this, &init_pos);
01046
01047 if (*a_str == NULL) {
01048 *a_str = cr_string_new ();
01049 str_needs_free = TRUE;
01050 }
01051 for (i = 0;; i++) {
01052 if (is_first_nmchar == TRUE) {
01053 status = cr_tknzr_parse_nmchar
01054 (a_this, &tmp_char,
01055 &loc) ;
01056 is_first_nmchar = FALSE ;
01057 } else {
01058 status = cr_tknzr_parse_nmchar
01059 (a_this, &tmp_char, NULL) ;
01060 }
01061 if (status != CR_OK)
01062 break;
01063 g_string_append_unichar ((*a_str)->stryng,
01064 tmp_char);
01065 }
01066 if (i > 0) {
01067 cr_parsing_location_copy
01068 (&(*a_str)->location, &loc) ;
01069 return CR_OK;
01070 }
01071 if (str_needs_free == TRUE && *a_str) {
01072 cr_string_destroy (*a_str);
01073 *a_str = NULL;
01074 }
01075 cr_tknzr_set_cur_pos (a_this, &init_pos);
01076 return CR_PARSING_ERROR;
01077 }
01078
01079
01080
01081
01082
01083 static enum CRStatus
01084 cr_tknzr_parse_hash (CRTknzr * a_this, CRString ** a_str)
01085 {
01086 guint32 cur_char = 0;
01087 CRInputPos init_pos;
01088 enum CRStatus status = CR_OK;
01089 gboolean str_needs_free = FALSE;
01090 CRParsingLocation loc = {0} ;
01091
01092 g_return_val_if_fail (a_this && PRIVATE (a_this)
01093 && PRIVATE (a_this)->input,
01094 CR_BAD_PARAM_ERROR);
01095
01096 RECORD_INITIAL_POS (a_this, &init_pos);
01097 READ_NEXT_CHAR (a_this, &cur_char);
01098 if (cur_char != '#') {
01099 status = CR_PARSING_ERROR;
01100 goto error;
01101 }
01102 if (*a_str == NULL) {
01103 *a_str = cr_string_new ();
01104 str_needs_free = TRUE;
01105 }
01106 cr_tknzr_get_parsing_location (a_this,
01107 &loc) ;
01108 status = cr_tknzr_parse_name (a_this, a_str);
01109 cr_parsing_location_copy (&(*a_str)->location, &loc) ;
01110 if (status != CR_OK) {
01111 goto error;
01112 }
01113 return CR_OK;
01114
01115 error:
01116 if (str_needs_free == TRUE && *a_str) {
01117 cr_string_destroy (*a_str);
01118 *a_str = NULL;
01119 }
01120
01121 cr_tknzr_set_cur_pos (a_this, &init_pos);
01122 return status;
01123 }
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134 static enum CRStatus
01135 cr_tknzr_parse_uri (CRTknzr * a_this,
01136 CRString ** a_str)
01137 {
01138 guint32 cur_char = 0;
01139 CRInputPos init_pos;
01140 enum CRStatus status = CR_PARSING_ERROR;
01141 guchar tab[4] = { 0 }, *tmp_ptr1 = NULL, *tmp_ptr2 = NULL;
01142 CRString *str = NULL;
01143 CRParsingLocation location = {0} ;
01144
01145 g_return_val_if_fail (a_this
01146 && PRIVATE (a_this)
01147 && PRIVATE (a_this)->input
01148 && a_str,
01149 CR_BAD_PARAM_ERROR);
01150
01151 RECORD_INITIAL_POS (a_this, &init_pos);
01152
01153 PEEK_BYTE (a_this, 1, &tab[0]);
01154 PEEK_BYTE (a_this, 2, &tab[1]);
01155 PEEK_BYTE (a_this, 3, &tab[2]);
01156 PEEK_BYTE (a_this, 4, &tab[3]);
01157
01158 if (tab[0] != 'u' || tab[1] != 'r' || tab[2] != 'l' || tab[3] != '(') {
01159 status = CR_PARSING_ERROR;
01160 goto error;
01161 }
01162
01163
01164
01165
01166
01167
01168 SKIP_CHARS (a_this, 1);
01169 cr_tknzr_get_parsing_location (a_this, &location) ;
01170 SKIP_CHARS (a_this, 3);
01171 cr_tknzr_try_to_skip_spaces (a_this);
01172 status = cr_tknzr_parse_string (a_this, a_str);
01173
01174 if (status == CR_OK) {
01175 guint32 next_char = 0;
01176 status = cr_tknzr_parse_w (a_this, &tmp_ptr1,
01177 &tmp_ptr2, NULL);
01178 cr_tknzr_try_to_skip_spaces (a_this);
01179 PEEK_NEXT_CHAR (a_this, &next_char);
01180 if (next_char == ')') {
01181 READ_NEXT_CHAR (a_this, &cur_char);
01182 status = CR_OK;
01183 } else {
01184 status = CR_PARSING_ERROR;
01185 }
01186 }
01187 if (status != CR_OK) {
01188 str = cr_string_new ();
01189 for (;;) {
01190 guint32 next_char = 0;
01191 PEEK_NEXT_CHAR (a_this, &next_char);
01192 if (strchr ("!#$%&", next_char)
01193 || (next_char >= '*' && next_char <= '~')
01194 || (cr_utils_is_nonascii (next_char) == TRUE)) {
01195 READ_NEXT_CHAR (a_this, &cur_char);
01196 g_string_append_unichar
01197 (str->stryng, cur_char);
01198 status = CR_OK;
01199 } else {
01200 guint32 esc_code = 0;
01201 status = cr_tknzr_parse_escape
01202 (a_this, &esc_code, NULL);
01203 if (status == CR_OK) {
01204 g_string_append_unichar
01205 (str->stryng,
01206 esc_code);
01207 } else {
01208 status = CR_OK;
01209 break;
01210 }
01211 }
01212 }
01213 cr_tknzr_try_to_skip_spaces (a_this);
01214 READ_NEXT_CHAR (a_this, &cur_char);
01215 if (cur_char == ')') {
01216 status = CR_OK;
01217 } else {
01218 status = CR_PARSING_ERROR;
01219 goto error;
01220 }
01221 if (str) {
01222 if (*a_str == NULL) {
01223 *a_str = str;
01224 str = NULL;
01225 } else {
01226 g_string_append_len
01227 ((*a_str)->stryng,
01228 str->stryng->str,
01229 str->stryng->len);
01230 cr_string_destroy (str);
01231 }
01232 }
01233 }
01234
01235 cr_parsing_location_copy
01236 (&(*a_str)->location,
01237 &location) ;
01238 return CR_OK ;
01239 error:
01240 if (str) {
01241 cr_string_destroy (str);
01242 str = NULL;
01243 }
01244 cr_tknzr_set_cur_pos (a_this, &init_pos);
01245 return status;
01246 }
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256 static enum CRStatus
01257 cr_tknzr_parse_rgb (CRTknzr * a_this, CRRgb ** a_rgb)
01258 {
01259 enum CRStatus status = CR_OK;
01260 CRInputPos init_pos;
01261 CRNum *num = NULL;
01262 guchar next_bytes[3] = { 0 }, cur_byte = 0;
01263 glong red = 0,
01264 green = 0,
01265 blue = 0,
01266 i = 0;
01267 gboolean is_percentage = FALSE;
01268 CRParsingLocation location = {0} ;
01269
01270 g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR);
01271
01272 RECORD_INITIAL_POS (a_this, &init_pos);
01273
01274 PEEK_BYTE (a_this, 1, &next_bytes[0]);
01275 PEEK_BYTE (a_this, 2, &next_bytes[1]);
01276 PEEK_BYTE (a_this, 3, &next_bytes[2]);
01277
01278 if (((next_bytes[0] == 'r') || (next_bytes[0] == 'R'))
01279 && ((next_bytes[1] == 'g') || (next_bytes[1] == 'G'))
01280 && ((next_bytes[2] == 'b') || (next_bytes[2] == 'B'))) {
01281 SKIP_CHARS (a_this, 1);
01282 cr_tknzr_get_parsing_location (a_this, &location) ;
01283 SKIP_CHARS (a_this, 2);
01284 } else {
01285 status = CR_PARSING_ERROR;
01286 goto error;
01287 }
01288 READ_NEXT_BYTE (a_this, &cur_byte);
01289 ENSURE_PARSING_COND (cur_byte == '(');
01290
01291 cr_tknzr_try_to_skip_spaces (a_this);
01292 status = cr_tknzr_parse_num (a_this, &num);
01293 ENSURE_PARSING_COND ((status == CR_OK) && (num != NULL));
01294
01295 red = num->val;
01296 cr_num_destroy (num);
01297 num = NULL;
01298
01299 PEEK_BYTE (a_this, 1, &next_bytes[0]);
01300 if (next_bytes[0] == '%') {
01301 SKIP_CHARS (a_this, 1);
01302 is_percentage = TRUE;
01303 }
01304 cr_tknzr_try_to_skip_spaces (a_this);
01305
01306 for (i = 0; i < 2; i++) {
01307 READ_NEXT_BYTE (a_this, &cur_byte);
01308 ENSURE_PARSING_COND (cur_byte == ',');
01309
01310 cr_tknzr_try_to_skip_spaces (a_this);
01311 status = cr_tknzr_parse_num (a_this, &num);
01312 ENSURE_PARSING_COND ((status == CR_OK) && (num != NULL));
01313
01314 PEEK_BYTE (a_this, 1, &next_bytes[0]);
01315 if (next_bytes[0] == '%') {
01316 SKIP_CHARS (a_this, 1);
01317 is_percentage = 1;
01318 }
01319
01320 if (i == 0) {
01321 green = num->val;
01322 } else if (i == 1) {
01323 blue = num->val;
01324 }
01325
01326 if (num) {
01327 cr_num_destroy (num);
01328 num = NULL;
01329 }
01330 cr_tknzr_try_to_skip_spaces (a_this);
01331 }
01332
01333 READ_NEXT_BYTE (a_this, &cur_byte);
01334 if (*a_rgb == NULL) {
01335 *a_rgb = cr_rgb_new_with_vals (red, green, blue,
01336 is_percentage);
01337
01338 if (*a_rgb == NULL) {
01339 status = CR_ERROR;
01340 goto error;
01341 }
01342 status = CR_OK;
01343 } else {
01344 (*a_rgb)->red = red;
01345 (*a_rgb)->green = green;
01346 (*a_rgb)->blue = blue;
01347 (*a_rgb)->is_percentage = is_percentage;
01348
01349 status = CR_OK;
01350 }
01351
01352 if (status == CR_OK) {
01353 if (a_rgb && *a_rgb) {
01354 cr_parsing_location_copy
01355 (&(*a_rgb)->location,
01356 &location) ;
01357 }
01358 return CR_OK;
01359 }
01360
01361 error:
01362 if (num) {
01363 cr_num_destroy (num);
01364 num = NULL;
01365 }
01366
01367 cr_tknzr_set_cur_pos (a_this, &init_pos);
01368 return CR_OK;
01369 }
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386 static enum CRStatus
01387 cr_tknzr_parse_atkeyword (CRTknzr * a_this,
01388 CRString ** a_str)
01389 {
01390 guint32 cur_char = 0;
01391 CRInputPos init_pos;
01392 gboolean str_needs_free = FALSE;
01393 enum CRStatus status = CR_OK;
01394
01395 g_return_val_if_fail (a_this && PRIVATE (a_this)
01396 && PRIVATE (a_this)->input
01397 && a_str, CR_BAD_PARAM_ERROR);
01398
01399 RECORD_INITIAL_POS (a_this, &init_pos);
01400
01401 READ_NEXT_CHAR (a_this, &cur_char);
01402
01403 if (cur_char != '@') {
01404 status = CR_PARSING_ERROR;
01405 goto error;
01406 }
01407
01408 if (*a_str == NULL) {
01409 *a_str = cr_string_new ();
01410 str_needs_free = TRUE;
01411 }
01412 status = cr_tknzr_parse_ident (a_this, a_str);
01413 if (status != CR_OK) {
01414 goto error;
01415 }
01416 return CR_OK;
01417 error:
01418
01419 if (str_needs_free == TRUE && *a_str) {
01420 cr_string_destroy (*a_str);
01421 *a_str = NULL;
01422 }
01423 cr_tknzr_set_cur_pos (a_this, &init_pos);
01424 return status;
01425 }
01426
01427 static enum CRStatus
01428 cr_tknzr_parse_important (CRTknzr * a_this,
01429 CRParsingLocation *a_location)
01430 {
01431 guint32 cur_char = 0;
01432 CRInputPos init_pos;
01433 enum CRStatus status = CR_OK;
01434
01435 g_return_val_if_fail (a_this && PRIVATE (a_this)
01436 && PRIVATE (a_this)->input,
01437 CR_BAD_PARAM_ERROR);
01438
01439 RECORD_INITIAL_POS (a_this, &init_pos);
01440 READ_NEXT_CHAR (a_this, &cur_char);
01441 ENSURE_PARSING_COND (cur_char == '!');
01442 if (a_location) {
01443 cr_tknzr_get_parsing_location (a_this,
01444 a_location) ;
01445 }
01446 cr_tknzr_try_to_skip_spaces (a_this);
01447
01448 if (BYTE (PRIVATE (a_this)->input, 1, NULL) == 'i'
01449 && BYTE (PRIVATE (a_this)->input, 2, NULL) == 'm'
01450 && BYTE (PRIVATE (a_this)->input, 3, NULL) == 'p'
01451 && BYTE (PRIVATE (a_this)->input, 4, NULL) == 'o'
01452 && BYTE (PRIVATE (a_this)->input, 5, NULL) == 'r'
01453 && BYTE (PRIVATE (a_this)->input, 6, NULL) == 't'
01454 && BYTE (PRIVATE (a_this)->input, 7, NULL) == 'a'
01455 && BYTE (PRIVATE (a_this)->input, 8, NULL) == 'n'
01456 && BYTE (PRIVATE (a_this)->input, 9, NULL) == 't') {
01457 SKIP_BYTES (a_this, 9);
01458 if (a_location) {
01459 cr_tknzr_get_parsing_location (a_this,
01460 a_location) ;
01461 }
01462 return CR_OK;
01463 } else {
01464 status = CR_PARSING_ERROR;
01465 }
01466
01467 error:
01468 cr_tknzr_set_cur_pos (a_this, &init_pos);
01469
01470 return status;
01471 }
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481 static enum CRStatus
01482 cr_tknzr_parse_num (CRTknzr * a_this,
01483 CRNum ** a_num)
01484 {
01485 enum CRStatus status = CR_PARSING_ERROR;
01486 enum CRNumType val_type = NUM_GENERIC;
01487 gboolean parsing_dec = FALSE,
01488 parsed = FALSE;
01489 guint32 cur_char = 0,
01490 int_part = 0,
01491 dec_part = 0,
01492 next_char = 0,
01493 decimal_places = 0;
01494 CRInputPos init_pos;
01495 CRParsingLocation location = {0} ;
01496
01497 g_return_val_if_fail (a_this && PRIVATE (a_this)
01498 && PRIVATE (a_this)->input,
01499 CR_BAD_PARAM_ERROR);
01500
01501 RECORD_INITIAL_POS (a_this, &init_pos);
01502 READ_NEXT_CHAR (a_this, &cur_char);
01503 if (IS_NUM (cur_char) == TRUE) {
01504 int_part = int_part * 10 + (cur_char - '0');
01505
01506 parsed = TRUE;
01507 } else if (cur_char == '.') {
01508 parsing_dec = TRUE;
01509 } else {
01510 status = CR_PARSING_ERROR;
01511 goto error;
01512 }
01513 cr_tknzr_get_parsing_location (a_this, &location) ;
01514
01515 for (;;) {
01516 status = cr_tknzr_peek_char (a_this, &next_char);
01517 if (status != CR_OK) {
01518 if (status == CR_END_OF_INPUT_ERROR)
01519 status = CR_OK;
01520 break;
01521 }
01522 if (next_char == '.') {
01523 if (parsing_dec == TRUE) {
01524 status = CR_PARSING_ERROR;
01525 goto error;
01526 }
01527
01528 READ_NEXT_CHAR (a_this, &cur_char);
01529 parsing_dec = TRUE;
01530 parsed = TRUE;
01531 } else if (IS_NUM (next_char) == TRUE) {
01532 READ_NEXT_CHAR (a_this, &cur_char);
01533 parsed = TRUE;
01534
01535 if (parsing_dec == FALSE) {
01536 int_part = int_part * 10 + (cur_char - '0');
01537 } else {
01538 decimal_places++;
01539 dec_part = dec_part * 10 + (cur_char - '0');
01540 }
01541 } else {
01542 break;
01543 }
01544 }
01545
01546 if (parsed == FALSE) {
01547 status = CR_PARSING_ERROR;
01548 }
01549
01550
01551
01552
01553 if (status == CR_OK) {
01554 gdouble val = 0.0;
01555
01556 val = int_part;
01557 val += cr_utils_n_to_0_dot_n (dec_part, decimal_places);
01558 if (*a_num == NULL) {
01559 *a_num = cr_num_new_with_val (val, val_type);
01560
01561 if (*a_num == NULL) {
01562 status = CR_ERROR;
01563 goto error;
01564 }
01565 } else {
01566 (*a_num)->val = val;
01567 (*a_num)->type = val_type;
01568 }
01569 cr_parsing_location_copy (&(*a_num)->location,
01570 &location) ;
01571 return CR_OK;
01572 }
01573
01574 error:
01575
01576 cr_tknzr_set_cur_pos (a_this, &init_pos);
01577
01578 return status;
01579 }
01580
01581
01582
01583
01584
01585 CRTknzr *
01586 cr_tknzr_new (CRInput * a_input)
01587 {
01588 CRTknzr *result = NULL;
01589
01590 result = g_try_malloc (sizeof (CRTknzr));
01591
01592 if (result == NULL) {
01593 cr_utils_trace_info ("Out of memory");
01594 return NULL;
01595 }
01596
01597 memset (result, 0, sizeof (CRTknzr));
01598
01599 result->priv = g_try_malloc (sizeof (CRTknzrPriv));
01600
01601 if (result->priv == NULL) {
01602 cr_utils_trace_info ("Out of memory");
01603
01604 if (result) {
01605 g_free (result);
01606 result = NULL;
01607 }
01608
01609 return NULL;
01610 }
01611 memset (result->priv, 0, sizeof (CRTknzrPriv));
01612 if (a_input)
01613 cr_tknzr_set_input (result, a_input);
01614 return result;
01615 }
01616
01617 CRTknzr *
01618 cr_tknzr_new_from_buf (guchar * a_buf, gulong a_len,
01619 enum CREncoding a_enc,
01620 gboolean a_free_at_destroy)
01621 {
01622 CRTknzr *result = NULL;
01623 CRInput *input = NULL;
01624
01625 input = cr_input_new_from_buf (a_buf, a_len, a_enc,
01626 a_free_at_destroy);
01627
01628 g_return_val_if_fail (input != NULL, NULL);
01629
01630 result = cr_tknzr_new (input);
01631
01632 return result;
01633 }
01634
01635 CRTknzr *
01636 cr_tknzr_new_from_uri (const guchar * a_file_uri,
01637 enum CREncoding a_enc)
01638 {
01639 CRTknzr *result = NULL;
01640 CRInput *input = NULL;
01641
01642 input = cr_input_new_from_uri (a_file_uri, a_enc);
01643 g_return_val_if_fail (input != NULL, NULL);
01644
01645 result = cr_tknzr_new (input);
01646
01647 return result;
01648 }
01649
01650 void
01651 cr_tknzr_ref (CRTknzr * a_this)
01652 {
01653 g_return_if_fail (a_this && PRIVATE (a_this));
01654
01655 PRIVATE (a_this)->ref_count++;
01656 }
01657
01658 gboolean
01659 cr_tknzr_unref (CRTknzr * a_this)
01660 {
01661 g_return_val_if_fail (a_this && PRIVATE (a_this), FALSE);
01662
01663 if (PRIVATE (a_this)->ref_count > 0) {
01664 PRIVATE (a_this)->ref_count--;
01665 }
01666
01667 if (PRIVATE (a_this)->ref_count == 0) {
01668 cr_tknzr_destroy (a_this);
01669 return TRUE;
01670 }
01671
01672 return FALSE;
01673 }
01674
01675 enum CRStatus
01676 cr_tknzr_set_input (CRTknzr * a_this, CRInput * a_input)
01677 {
01678 g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR);
01679
01680 if (PRIVATE (a_this)->input) {
01681 cr_input_unref (PRIVATE (a_this)->input);
01682 }
01683
01684 PRIVATE (a_this)->input = a_input;
01685
01686 cr_input_ref (PRIVATE (a_this)->input);
01687
01688 return CR_OK;
01689 }
01690
01691 enum CRStatus
01692 cr_tknzr_get_input (CRTknzr * a_this, CRInput ** a_input)
01693 {
01694 g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR);
01695
01696 *a_input = PRIVATE (a_this)->input;
01697
01698 return CR_OK;
01699 }
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714 enum CRStatus
01715 cr_tknzr_read_byte (CRTknzr * a_this, guchar * a_byte)
01716 {
01717 g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR);
01718
01719 return cr_input_read_byte (PRIVATE (a_this)->input, a_byte);
01720
01721 }
01722
01723
01724
01725
01726
01727
01728
01729
01730 enum CRStatus
01731 cr_tknzr_read_char (CRTknzr * a_this, guint32 * a_char)
01732 {
01733 g_return_val_if_fail (a_this && PRIVATE (a_this)
01734 && PRIVATE (a_this)->input
01735 && a_char, CR_BAD_PARAM_ERROR);
01736
01737 if (PRIVATE (a_this)->token_cache) {
01738 cr_input_set_cur_pos (PRIVATE (a_this)->input,
01739 &PRIVATE (a_this)->prev_pos);
01740 cr_token_destroy (PRIVATE (a_this)->token_cache);
01741 PRIVATE (a_this)->token_cache = NULL;
01742 }
01743
01744 return cr_input_read_char (PRIVATE (a_this)->input, a_char);
01745 }
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755 enum CRStatus
01756 cr_tknzr_peek_char (CRTknzr * a_this, guint32 * a_char)
01757 {
01758 g_return_val_if_fail (a_this && PRIVATE (a_this)
01759 && PRIVATE (a_this)->input
01760 && a_char, CR_BAD_PARAM_ERROR);
01761
01762 if (PRIVATE (a_this)->token_cache) {
01763 cr_input_set_cur_pos (PRIVATE (a_this)->input,
01764 &PRIVATE (a_this)->prev_pos);
01765 cr_token_destroy (PRIVATE (a_this)->token_cache);
01766 PRIVATE (a_this)->token_cache = NULL;
01767 }
01768
01769 return cr_input_peek_char (PRIVATE (a_this)->input, a_char);
01770 }
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781 enum CRStatus
01782 cr_tknzr_peek_byte (CRTknzr * a_this, gulong a_offset, guchar * a_byte)
01783 {
01784 g_return_val_if_fail (a_this && PRIVATE (a_this)
01785 && PRIVATE (a_this)->input && a_byte,
01786 CR_BAD_PARAM_ERROR);
01787
01788 if (PRIVATE (a_this)->token_cache) {
01789 cr_input_set_cur_pos (PRIVATE (a_this)->input,
01790 &PRIVATE (a_this)->prev_pos);
01791 cr_token_destroy (PRIVATE (a_this)->token_cache);
01792 PRIVATE (a_this)->token_cache = NULL;
01793 }
01794
01795 return cr_input_peek_byte (PRIVATE (a_this)->input,
01796 CR_SEEK_CUR, a_offset, a_byte);
01797 }
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809 guchar
01810 cr_tknzr_peek_byte2 (CRTknzr * a_this, gulong a_offset, gboolean * a_eof)
01811 {
01812 g_return_val_if_fail (a_this && PRIVATE (a_this)
01813 && PRIVATE (a_this)->input, 0);
01814
01815 return cr_input_peek_byte2 (PRIVATE (a_this)->input, a_offset, a_eof);
01816 }
01817
01818
01819
01820
01821
01822
01823
01824 glong
01825 cr_tknzr_get_nb_bytes_left (CRTknzr * a_this)
01826 {
01827 g_return_val_if_fail (a_this && PRIVATE (a_this)
01828 && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR);
01829
01830 if (PRIVATE (a_this)->token_cache) {
01831 cr_input_set_cur_pos (PRIVATE (a_this)->input,
01832 &PRIVATE (a_this)->prev_pos);
01833 cr_token_destroy (PRIVATE (a_this)->token_cache);
01834 PRIVATE (a_this)->token_cache = NULL;
01835 }
01836
01837 return cr_input_get_nb_bytes_left (PRIVATE (a_this)->input);
01838 }
01839
01840 enum CRStatus
01841 cr_tknzr_get_cur_pos (CRTknzr * a_this, CRInputPos * a_pos)
01842 {
01843 g_return_val_if_fail (a_this && PRIVATE (a_this)
01844 && PRIVATE (a_this)->input
01845 && a_pos, CR_BAD_PARAM_ERROR);
01846
01847 if (PRIVATE (a_this)->token_cache) {
01848 cr_input_set_cur_pos (PRIVATE (a_this)->input,
01849 &PRIVATE (a_this)->prev_pos);
01850 cr_token_destroy (PRIVATE (a_this)->token_cache);
01851 PRIVATE (a_this)->token_cache = NULL;
01852 }
01853
01854 return cr_input_get_cur_pos (PRIVATE (a_this)->input, a_pos);
01855 }
01856
01857 enum CRStatus
01858 cr_tknzr_get_parsing_location (CRTknzr *a_this,
01859 CRParsingLocation *a_loc)
01860 {
01861 g_return_val_if_fail (a_this
01862 && PRIVATE (a_this)
01863 && a_loc,
01864 CR_BAD_PARAM_ERROR) ;
01865
01866 return cr_input_get_parsing_location
01867 (PRIVATE (a_this)->input, a_loc) ;
01868 }
01869
01870 enum CRStatus
01871 cr_tknzr_get_cur_byte_addr (CRTknzr * a_this, guchar ** a_addr)
01872 {
01873 g_return_val_if_fail (a_this && PRIVATE (a_this)
01874 && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR);
01875 if (PRIVATE (a_this)->token_cache) {
01876 cr_input_set_cur_pos (PRIVATE (a_this)->input,
01877 &PRIVATE (a_this)->prev_pos);
01878 cr_token_destroy (PRIVATE (a_this)->token_cache);
01879 PRIVATE (a_this)->token_cache = NULL;
01880 }
01881
01882 return cr_input_get_cur_byte_addr (PRIVATE (a_this)->input, a_addr);
01883 }
01884
01885 enum CRStatus
01886 cr_tknzr_seek_index (CRTknzr * a_this, enum CRSeekPos a_origin, gint a_pos)
01887 {
01888 g_return_val_if_fail (a_this && PRIVATE (a_this)
01889 && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR);
01890
01891 if (PRIVATE (a_this)->token_cache) {
01892 cr_input_set_cur_pos (PRIVATE (a_this)->input,
01893 &PRIVATE (a_this)->prev_pos);
01894 cr_token_destroy (PRIVATE (a_this)->token_cache);
01895 PRIVATE (a_this)->token_cache = NULL;
01896 }
01897
01898 return cr_input_seek_index (PRIVATE (a_this)->input, a_origin, a_pos);
01899 }
01900
01901 enum CRStatus
01902 cr_tknzr_consume_chars (CRTknzr * a_this, guint32 a_char, glong * a_nb_char)
01903 {
01904 g_return_val_if_fail (a_this && PRIVATE (a_this)
01905 && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR);
01906
01907 if (PRIVATE (a_this)->token_cache) {
01908 cr_input_set_cur_pos (PRIVATE (a_this)->input,
01909 &PRIVATE (a_this)->prev_pos);
01910 cr_token_destroy (PRIVATE (a_this)->token_cache);
01911 PRIVATE (a_this)->token_cache = NULL;
01912 }
01913
01914 return cr_input_consume_chars (PRIVATE (a_this)->input,
01915 a_char, a_nb_char);
01916 }
01917
01918 enum CRStatus
01919 cr_tknzr_set_cur_pos (CRTknzr * a_this, CRInputPos * a_pos)
01920 {
01921 g_return_val_if_fail (a_this && PRIVATE (a_this)
01922 && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR);
01923
01924 if (PRIVATE (a_this)->token_cache) {
01925 cr_token_destroy (PRIVATE (a_this)->token_cache);
01926 PRIVATE (a_this)->token_cache = NULL;
01927 }
01928
01929 return cr_input_set_cur_pos (PRIVATE (a_this)->input, a_pos);
01930 }
01931
01932 enum CRStatus
01933 cr_tknzr_unget_token (CRTknzr * a_this, CRToken * a_token)
01934 {
01935 g_return_val_if_fail (a_this && PRIVATE (a_this)
01936 && PRIVATE (a_this)->token_cache == NULL,
01937 CR_BAD_PARAM_ERROR);
01938
01939 PRIVATE (a_this)->token_cache = a_token;
01940
01941 return CR_OK;
01942 }
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955 enum CRStatus
01956 cr_tknzr_get_next_token (CRTknzr * a_this, CRToken ** a_tk)
01957 {
01958 enum CRStatus status = CR_OK;
01959 CRToken *token = NULL;
01960 CRInputPos init_pos;
01961 guint32 next_char = 0;
01962 guchar next_bytes[4] = { 0 };
01963 gboolean reached_eof = FALSE;
01964 CRInput *input = NULL;
01965 CRString *str = NULL;
01966 CRRgb *rgb = NULL;
01967 CRParsingLocation location = {0} ;
01968
01969 g_return_val_if_fail (a_this && PRIVATE (a_this)
01970 && a_tk && *a_tk == NULL
01971 && PRIVATE (a_this)->input,
01972 CR_BAD_PARAM_ERROR);
01973
01974 if (PRIVATE (a_this)->token_cache) {
01975 *a_tk = PRIVATE (a_this)->token_cache;
01976 PRIVATE (a_this)->token_cache = NULL;
01977 return CR_OK;
01978 }
01979
01980 RECORD_INITIAL_POS (a_this, &init_pos);
01981
01982 status = cr_input_get_end_of_file
01983 (PRIVATE (a_this)->input, &reached_eof);
01984 ENSURE_PARSING_COND (status == CR_OK);
01985
01986 if (reached_eof == TRUE) {
01987 status = CR_END_OF_INPUT_ERROR;
01988 goto error;
01989 }
01990
01991 input = PRIVATE (a_this)->input;
01992
01993 PEEK_NEXT_CHAR (a_this, &next_char);
01994 token = cr_token_new ();
01995 ENSURE_PARSING_COND (token);
01996
01997 switch (next_char) {
01998 case '@':
01999 {
02000 if (BYTE (input, 2, NULL) == 'f'
02001 && BYTE (input, 3, NULL) == 'o'
02002 && BYTE (input, 4, NULL) == 'n'
02003 && BYTE (input, 5, NULL) == 't'
02004 && BYTE (input, 6, NULL) == '-'
02005 && BYTE (input, 7, NULL) == 'f'
02006 && BYTE (input, 8, NULL) == 'a'
02007 && BYTE (input, 9, NULL) == 'c'
02008 && BYTE (input, 10, NULL) == 'e') {
02009 SKIP_CHARS (a_this, 1);
02010 cr_tknzr_get_parsing_location
02011 (a_this, &location) ;
02012 SKIP_CHARS (a_this, 9);
02013 status = cr_token_set_font_face_sym (token);
02014 CHECK_PARSING_STATUS (status, TRUE);
02015 cr_parsing_location_copy (&token->location,
02016 &location) ;
02017 goto done;
02018 }
02019
02020 if (BYTE (input, 2, NULL) == 'c'
02021 && BYTE (input, 3, NULL) == 'h'
02022 && BYTE (input, 4, NULL) == 'a'
02023 && BYTE (input, 5, NULL) == 'r'
02024 && BYTE (input, 6, NULL) == 's'
02025 && BYTE (input, 7, NULL) == 'e'
02026 && BYTE (input, 8, NULL) == 't') {
02027 SKIP_CHARS (a_this, 1);
02028 cr_tknzr_get_parsing_location
02029 (a_this, &location) ;
02030 SKIP_CHARS (a_this, 7);
02031 status = cr_token_set_charset_sym (token);
02032 CHECK_PARSING_STATUS (status, TRUE);
02033 cr_parsing_location_copy (&token->location,
02034 &location) ;
02035 goto done;
02036 }
02037
02038 if (BYTE (input, 2, NULL) == 'i'
02039 && BYTE (input, 3, NULL) == 'm'
02040 && BYTE (input, 4, NULL) == 'p'
02041 && BYTE (input, 5, NULL) == 'o'
02042 && BYTE (input, 6, NULL) == 'r'
02043 && BYTE (input, 7, NULL) == 't') {
02044 SKIP_CHARS (a_this, 1);
02045 cr_tknzr_get_parsing_location
02046 (a_this, &location) ;
02047 SKIP_CHARS (a_this, 6);
02048 status = cr_token_set_import_sym (token);
02049 CHECK_PARSING_STATUS (status, TRUE);
02050 cr_parsing_location_copy (&token->location,
02051 &location) ;
02052 goto done;
02053 }
02054
02055 if (BYTE (input, 2, NULL) == 'm'
02056 && BYTE (input, 3, NULL) == 'e'
02057 && BYTE (input, 4, NULL) == 'd'
02058 && BYTE (input, 5, NULL) == 'i'
02059 && BYTE (input, 6, NULL) == 'a') {
02060 SKIP_CHARS (a_this, 1);
02061 cr_tknzr_get_parsing_location (a_this,
02062 &location) ;
02063 SKIP_CHARS (a_this, 5);
02064 status = cr_token_set_media_sym (token);
02065 CHECK_PARSING_STATUS (status, TRUE);
02066 cr_parsing_location_copy (&token->location,
02067 &location) ;
02068 goto done;
02069 }
02070
02071 if (BYTE (input, 2, NULL) == 'p'
02072 && BYTE (input, 3, NULL) == 'a'
02073 && BYTE (input, 4, NULL) == 'g'
02074 && BYTE (input, 5, NULL) == 'e') {
02075 SKIP_CHARS (a_this, 1);
02076 cr_tknzr_get_parsing_location (a_this,
02077 &location) ;
02078 SKIP_CHARS (a_this, 4);
02079 status = cr_token_set_page_sym (token);
02080 CHECK_PARSING_STATUS (status, TRUE);
02081 cr_parsing_location_copy (&token->location,
02082 &location) ;
02083 goto done;
02084 }
02085 status = cr_tknzr_parse_atkeyword (a_this, &str);
02086 if (status == CR_OK) {
02087 status = cr_token_set_atkeyword (token, str);
02088 CHECK_PARSING_STATUS (status, TRUE);
02089 if (str) {
02090 cr_parsing_location_copy (&token->location,
02091 &str->location) ;
02092 }
02093 goto done;
02094 }
02095 }
02096 break;
02097
02098 case 'u':
02099
02100 if (BYTE (input, 2, NULL) == 'r'
02101 && BYTE (input, 3, NULL) == 'l'
02102 && BYTE (input, 4, NULL) == '(') {
02103 CRString *str = NULL;
02104
02105 status = cr_tknzr_parse_uri (a_this, &str);
02106 if (status == CR_OK) {
02107 status = cr_token_set_uri (token, str);
02108 CHECK_PARSING_STATUS (status, TRUE);
02109 if (str) {
02110 cr_parsing_location_copy (&token->location,
02111 &str->location) ;
02112 }
02113 goto done;
02114 }
02115 } else {
02116 status = cr_tknzr_parse_ident (a_this, &str);
02117 if (status == CR_OK && str) {
02118 status = cr_token_set_ident (token, str);
02119 CHECK_PARSING_STATUS (status, TRUE);
02120 if (str) {
02121 cr_parsing_location_copy (&token->location,
02122 &str->location) ;
02123 }
02124 goto done;
02125 }
02126 }
02127 break;
02128
02129 case 'r':
02130 if (BYTE (input, 2, NULL) == 'g'
02131 && BYTE (input, 3, NULL) == 'b'
02132 && BYTE (input, 4, NULL) == '(') {
02133 status = cr_tknzr_parse_rgb (a_this, &rgb);
02134 if (status == CR_OK && rgb) {
02135 status = cr_token_set_rgb (token, rgb);
02136 CHECK_PARSING_STATUS (status, TRUE);
02137 if (rgb) {
02138 cr_parsing_location_copy (&token->location,
02139 &rgb->location) ;
02140 }
02141 rgb = NULL;
02142 goto done;
02143 }
02144
02145 } else {
02146 status = cr_tknzr_parse_ident (a_this, &str);
02147 if (status == CR_OK) {
02148 status = cr_token_set_ident (token, str);
02149 CHECK_PARSING_STATUS (status, TRUE);
02150 if (str) {
02151 cr_parsing_location_copy (&token->location,
02152 &str->location) ;
02153 }
02154 str = NULL;
02155 goto done;
02156 }
02157 }
02158 break;
02159
02160 case '<':
02161 if (BYTE (input, 2, NULL) == '-'
02162 && BYTE (input, 3, NULL) == '-') {
02163 SKIP_CHARS (a_this, 1);
02164 cr_tknzr_get_parsing_location (a_this,
02165 &location) ;
02166 SKIP_CHARS (a_this, 2);
02167 status = cr_token_set_cdo (token);
02168 CHECK_PARSING_STATUS (status, TRUE);
02169 cr_parsing_location_copy (&token->location,
02170 &location) ;
02171 goto done;
02172 }
02173 break;
02174
02175 case '-':
02176 if (BYTE (input, 2, NULL) == '-'
02177 && BYTE (input, 3, NULL) == '>') {
02178 SKIP_CHARS (a_this, 1);
02179 cr_tknzr_get_parsing_location (a_this,
02180 &location) ;
02181 SKIP_CHARS (a_this, 2);
02182 status = cr_token_set_cdc (token);
02183 CHECK_PARSING_STATUS (status, TRUE);
02184 cr_parsing_location_copy (&token->location,
02185 &location) ;
02186 goto done;
02187 } else {
02188 status = cr_tknzr_parse_ident
02189 (a_this, &str);
02190 if (status == CR_OK) {
02191 cr_token_set_ident
02192 (token, str);
02193 if (str) {
02194 cr_parsing_location_copy (&token->location,
02195 &str->location) ;
02196 }
02197 goto done;
02198 }
02199 }
02200 break;
02201
02202 case '~':
02203 if (BYTE (input, 2, NULL) == '=') {
02204 SKIP_CHARS (a_this, 1);
02205 cr_tknzr_get_parsing_location (a_this,
02206 &location) ;
02207 SKIP_CHARS (a_this, 1);
02208 status = cr_token_set_includes (token);
02209 CHECK_PARSING_STATUS (status, TRUE);
02210 cr_parsing_location_copy (&token->location,
02211 &location) ;
02212 goto done;
02213 }
02214 break;
02215
02216 case '|':
02217 if (BYTE (input, 2, NULL) == '=') {
02218 SKIP_CHARS (a_this, 1);
02219 cr_tknzr_get_parsing_location (a_this,
02220 &location) ;
02221 SKIP_CHARS (a_this, 1);
02222 status = cr_token_set_dashmatch (token);
02223 CHECK_PARSING_STATUS (status, TRUE);
02224 cr_parsing_location_copy (&token->location,
02225 &location) ;
02226 goto done;
02227 }
02228 break;
02229
02230 case '/':
02231 if (BYTE (input, 2, NULL) == '*') {
02232 status = cr_tknzr_parse_comment (a_this, &str);
02233
02234 if (status == CR_OK) {
02235 status = cr_token_set_comment (token, str);
02236 str = NULL;
02237 CHECK_PARSING_STATUS (status, TRUE);
02238 if (str) {
02239 cr_parsing_location_copy (&token->location,
02240 &str->location) ;
02241 }
02242 goto done;
02243 }
02244 }
02245 break ;
02246
02247 case ';':
02248 SKIP_CHARS (a_this, 1);
02249 cr_tknzr_get_parsing_location (a_this,
02250 &location) ;
02251 status = cr_token_set_semicolon (token);
02252 CHECK_PARSING_STATUS (status, TRUE);
02253 cr_parsing_location_copy (&token->location,
02254 &location) ;
02255 goto done;
02256
02257 case '{':
02258 SKIP_CHARS (a_this, 1);
02259 cr_tknzr_get_parsing_location (a_this,
02260 &location) ;
02261 status = cr_token_set_cbo (token);
02262 CHECK_PARSING_STATUS (status, TRUE);
02263 cr_tknzr_get_parsing_location (a_this,
02264 &location) ;
02265 goto done;
02266
02267 case '}':
02268 SKIP_CHARS (a_this, 1);
02269 cr_tknzr_get_parsing_location (a_this,
02270 &location) ;
02271 status = cr_token_set_cbc (token);
02272 CHECK_PARSING_STATUS (status, TRUE);
02273 cr_parsing_location_copy (&token->location,
02274 &location) ;
02275 goto done;
02276
02277 case '(':
02278 SKIP_CHARS (a_this, 1);
02279 cr_tknzr_get_parsing_location (a_this,
02280 &location) ;
02281 status = cr_token_set_po (token);
02282 CHECK_PARSING_STATUS (status, TRUE);
02283 cr_parsing_location_copy (&token->location,
02284 &location) ;
02285 goto done;
02286
02287 case ')':
02288 SKIP_CHARS (a_this, 1);
02289 cr_tknzr_get_parsing_location (a_this,
02290 &location) ;
02291 status = cr_token_set_pc (token);
02292 CHECK_PARSING_STATUS (status, TRUE);
02293 cr_parsing_location_copy (&token->location,
02294 &location) ;
02295 goto done;
02296
02297 case '[':
02298 SKIP_CHARS (a_this, 1);
02299 cr_tknzr_get_parsing_location (a_this,
02300 &location) ;
02301 status = cr_token_set_bo (token);
02302 CHECK_PARSING_STATUS (status, TRUE);
02303 cr_parsing_location_copy (&token->location,
02304 &location) ;
02305 goto done;
02306
02307 case ']':
02308 SKIP_CHARS (a_this, 1);
02309 cr_tknzr_get_parsing_location (a_this,
02310 &location) ;
02311 status = cr_token_set_bc (token);
02312 CHECK_PARSING_STATUS (status, TRUE);
02313 cr_parsing_location_copy (&token->location,
02314 &location) ;
02315 goto done;
02316
02317 case ' ':
02318 case '\t':
02319 case '\n':
02320 case '\f':
02321 case '\r':
02322 {
02323 guchar *start = NULL,
02324 *end = NULL;
02325
02326 status = cr_tknzr_parse_w (a_this, &start,
02327 &end, &location);
02328 if (status == CR_OK) {
02329 status = cr_token_set_s (token);
02330 CHECK_PARSING_STATUS (status, TRUE);
02331 cr_tknzr_get_parsing_location (a_this,
02332 &location) ;
02333 goto done;
02334 }
02335 }
02336 break;
02337
02338 case '#':
02339 {
02340 status = cr_tknzr_parse_hash (a_this, &str);
02341 if (status == CR_OK && str) {
02342 status = cr_token_set_hash (token, str);
02343 CHECK_PARSING_STATUS (status, TRUE);
02344 if (str) {
02345 cr_parsing_location_copy (&token->location,
02346 &str->location) ;
02347 }
02348 str = NULL;
02349 goto done;
02350 }
02351 }
02352 break;
02353
02354 case '\'':
02355 case '"':
02356 status = cr_tknzr_parse_string (a_this, &str);
02357 if (status == CR_OK && str) {
02358 status = cr_token_set_string (token, str);
02359 CHECK_PARSING_STATUS (status, TRUE);
02360 if (str) {
02361 cr_parsing_location_copy (&token->location,
02362 &str->location) ;
02363 }
02364 str = NULL;
02365 goto done;
02366 }
02367 break;
02368
02369 case '!':
02370 status = cr_tknzr_parse_important (a_this, &location);
02371 if (status == CR_OK) {
02372 status = cr_token_set_important_sym (token);
02373 CHECK_PARSING_STATUS (status, TRUE);
02374 cr_parsing_location_copy (&token->location,
02375 &location) ;
02376 goto done;
02377 }
02378 break;
02379
02380 case '0':
02381 case '1':
02382 case '2':
02383 case '3':
02384 case '4':
02385 case '5':
02386 case '6':
02387 case '7':
02388 case '8':
02389 case '9':
02390 case '.':
02391 {
02392 CRNum *num = NULL;
02393
02394 status = cr_tknzr_parse_num (a_this, &num);
02395 if (status == CR_OK && num) {
02396 next_bytes[0] = BYTE (input, 1, NULL);
02397 next_bytes[1] = BYTE (input, 2, NULL);
02398 next_bytes[2] = BYTE (input, 3, NULL);
02399 next_bytes[3] = BYTE (input, 3, NULL);
02400
02401 if (next_bytes[0] == 'e'
02402 && next_bytes[1] == 'm') {
02403 num->type = NUM_LENGTH_EM;
02404 status = cr_token_set_ems (token,
02405 num);
02406 num = NULL;
02407 SKIP_CHARS (a_this, 2);
02408 } else if (next_bytes[0] == 'e'
02409 && next_bytes[1] == 'x') {
02410 num->type = NUM_LENGTH_EX;
02411 status = cr_token_set_exs (token,
02412 num);
02413 num = NULL;
02414 SKIP_CHARS (a_this, 2);
02415 } else if (next_bytes[0] == 'p'
02416 && next_bytes[1] == 'x') {
02417 num->type = NUM_LENGTH_PX;
02418 status = cr_token_set_length
02419 (token, num, LENGTH_PX_ET);
02420 num = NULL;
02421 SKIP_CHARS (a_this, 2);
02422 } else if (next_bytes[0] == 'c'
02423 && next_bytes[1] == 'm') {
02424 num->type = NUM_LENGTH_CM;
02425 status = cr_token_set_length
02426 (token, num, LENGTH_CM_ET);
02427 num = NULL;
02428 SKIP_CHARS (a_this, 2);
02429 } else if (next_bytes[0] == 'm'
02430 && next_bytes[1] == 'm') {
02431 num->type = NUM_LENGTH_MM;
02432 status = cr_token_set_length
02433 (token, num, LENGTH_MM_ET);
02434 num = NULL;
02435 SKIP_CHARS (a_this, 2);
02436 } else if (next_bytes[0] == 'i'
02437 && next_bytes[1] == 'n') {
02438 num->type = NUM_LENGTH_IN;
02439 status = cr_token_set_length
02440 (token, num, LENGTH_IN_ET);
02441 num = NULL;
02442 SKIP_CHARS (a_this, 2);
02443 } else if (next_bytes[0] == 'p'
02444 && next_bytes[1] == 't') {
02445 num->type = NUM_LENGTH_PT;
02446 status = cr_token_set_length
02447 (token, num, LENGTH_PT_ET);
02448 num = NULL;
02449 SKIP_CHARS (a_this, 2);
02450 } else if (next_bytes[0] == 'p'
02451 && next_bytes[1] == 'c') {
02452 num->type = NUM_LENGTH_PC;
02453 status = cr_token_set_length
02454 (token, num, LENGTH_PC_ET);
02455 num = NULL;
02456 SKIP_CHARS (a_this, 2);
02457 } else if (next_bytes[0] == 'd'
02458 && next_bytes[1] == 'e'
02459 && next_bytes[2] == 'g') {
02460 num->type = NUM_ANGLE_DEG;
02461 status = cr_token_set_angle
02462 (token, num, ANGLE_DEG_ET);
02463 num = NULL;
02464 SKIP_CHARS (a_this, 3);
02465 } else if (next_bytes[0] == 'r'
02466 && next_bytes[1] == 'a'
02467 && next_bytes[2] == 'd') {
02468 num->type = NUM_ANGLE_RAD;
02469 status = cr_token_set_angle
02470 (token, num, ANGLE_RAD_ET);
02471 num = NULL;
02472 SKIP_CHARS (a_this, 3);
02473 } else if (next_bytes[0] == 'g'
02474 && next_bytes[1] == 'r'
02475 && next_bytes[2] == 'a'
02476 && next_bytes[3] == 'd') {
02477 num->type = NUM_ANGLE_GRAD;
02478 status = cr_token_set_angle
02479 (token, num, ANGLE_GRAD_ET);
02480 num = NULL;
02481 SKIP_CHARS (a_this, 4);
02482 } else if (next_bytes[0] == 'm'
02483 && next_bytes[1] == 's') {
02484 num->type = NUM_TIME_MS;
02485 status = cr_token_set_time
02486 (token, num, TIME_MS_ET);
02487 num = NULL;
02488 SKIP_CHARS (a_this, 2);
02489 } else if (next_bytes[0] == 's') {
02490 num->type = NUM_TIME_S;
02491 status = cr_token_set_time
02492 (token, num, TIME_S_ET);
02493 num = NULL;
02494 SKIP_CHARS (a_this, 1);
02495 } else if (next_bytes[0] == 'H'
02496 && next_bytes[1] == 'z') {
02497 num->type = NUM_FREQ_HZ;
02498 status = cr_token_set_freq
02499 (token, num, FREQ_HZ_ET);
02500 num = NULL;
02501 SKIP_CHARS (a_this, 2);
02502 } else if (next_bytes[0] == 'k'
02503 && next_bytes[1] == 'H'
02504 && next_bytes[2] == 'z') {
02505 num->type = NUM_FREQ_KHZ;
02506 status = cr_token_set_freq
02507 (token, num, FREQ_KHZ_ET);
02508 num = NULL;
02509 SKIP_CHARS (a_this, 3);
02510 } else if (next_bytes[0] == '%') {
02511 num->type = NUM_PERCENTAGE;
02512 status = cr_token_set_percentage
02513 (token, num);
02514 num = NULL;
02515 SKIP_CHARS (a_this, 1);
02516 } else {
02517 status = cr_tknzr_parse_ident (a_this,
02518 &str);
02519 if (status == CR_OK && str) {
02520 num->type = NUM_UNKNOWN_TYPE;
02521 status = cr_token_set_dimen
02522 (token, num, str);
02523 num = NULL;
02524 CHECK_PARSING_STATUS (status,
02525 TRUE);
02526 str = NULL;
02527 } else {
02528 status = cr_token_set_number
02529 (token, num);
02530 num = NULL;
02531 CHECK_PARSING_STATUS (status, CR_OK);
02532 str = NULL;
02533 }
02534 }
02535 if (token && token->u.num) {
02536 cr_parsing_location_copy (&token->location,
02537 &token->u.num->location) ;
02538 } else {
02539 status = CR_ERROR ;
02540 }
02541 goto done ;
02542 }
02543 }
02544 break;
02545
02546 default:
02547
02548
02549 if (next_char == '\\'
02550 || (cr_utils_is_nonascii (next_bytes[0]) == TRUE)
02551 || ((next_char >= 'a') && (next_char <= 'z'))
02552 || ((next_char >= 'A') && (next_char <= 'Z'))) {
02553 status = cr_tknzr_parse_ident (a_this, &str);
02554 if (status == CR_OK && str) {
02555 guint32 next_c = 0;
02556
02557 status = cr_input_peek_char
02558 (PRIVATE (a_this)->input, &next_c);
02559
02560 if (status == CR_OK && next_c == '(') {
02561
02562 SKIP_CHARS (a_this, 1);
02563 status = cr_token_set_function
02564 (token, str);
02565 CHECK_PARSING_STATUS (status, TRUE);
02566
02567
02568
02569 if (str) {
02570 cr_parsing_location_copy (&token->location,
02571 &str->location) ;
02572 }
02573 str = NULL;
02574 } else {
02575 status = cr_token_set_ident (token,
02576 str);
02577 CHECK_PARSING_STATUS (status, TRUE);
02578 if (str) {
02579 cr_parsing_location_copy (&token->location,
02580 &str->location) ;
02581 }
02582 str = NULL;
02583 }
02584 goto done;
02585 } else {
02586 if (str) {
02587 cr_string_destroy (str);
02588 str = NULL;
02589 }
02590 }
02591 }
02592 break;
02593 }
02594
02595 READ_NEXT_CHAR (a_this, &next_char);
02596 cr_tknzr_get_parsing_location (a_this,
02597 &location) ;
02598 status = cr_token_set_delim (token, next_char);
02599 CHECK_PARSING_STATUS (status, TRUE);
02600 cr_parsing_location_copy (&token->location,
02601 &location) ;
02602 done:
02603
02604 if (status == CR_OK && token) {
02605 *a_tk = token;
02606
02607
02608
02609 memmove (&PRIVATE (a_this)->prev_pos,
02610 &init_pos, sizeof (CRInputPos));
02611 return CR_OK;
02612 }
02613
02614 error:
02615 if (token) {
02616 cr_token_destroy (token);
02617 token = NULL;
02618 }
02619
02620 if (str) {
02621 cr_string_destroy (str);
02622 str = NULL;
02623 }
02624 cr_tknzr_set_cur_pos (a_this, &init_pos);
02625 return status;
02626
02627 }
02628
02629 enum CRStatus
02630 cr_tknzr_parse_token (CRTknzr * a_this, enum CRTokenType a_type,
02631 enum CRTokenExtraType a_et, gpointer a_res,
02632 gpointer a_extra_res)
02633 {
02634 enum CRStatus status = CR_OK;
02635 CRToken *token = NULL;
02636
02637 g_return_val_if_fail (a_this && PRIVATE (a_this)
02638 && PRIVATE (a_this)->input
02639 && a_res, CR_BAD_PARAM_ERROR);
02640
02641 status = cr_tknzr_get_next_token (a_this, &token);
02642 if (status != CR_OK)
02643 return status;
02644 if (token == NULL)
02645 return CR_PARSING_ERROR;
02646
02647 if (token->type == a_type) {
02648 switch (a_type) {
02649 case NO_TK:
02650 case S_TK:
02651 case CDO_TK:
02652 case CDC_TK:
02653 case INCLUDES_TK:
02654 case DASHMATCH_TK:
02655 case IMPORT_SYM_TK:
02656 case PAGE_SYM_TK:
02657 case MEDIA_SYM_TK:
02658 case FONT_FACE_SYM_TK:
02659 case CHARSET_SYM_TK:
02660 case IMPORTANT_SYM_TK:
02661 status = CR_OK;
02662 break;
02663
02664 case STRING_TK:
02665 case IDENT_TK:
02666 case HASH_TK:
02667 case ATKEYWORD_TK:
02668 case FUNCTION_TK:
02669 case COMMENT_TK:
02670 case URI_TK:
02671 *((CRString **) a_res) = token->u.str;
02672 token->u.str = NULL;
02673 status = CR_OK;
02674 break;
02675
02676 case EMS_TK:
02677 case EXS_TK:
02678 case PERCENTAGE_TK:
02679 case NUMBER_TK:
02680 *((CRNum **) a_res) = token->u.num;
02681 token->u.num = NULL;
02682 status = CR_OK;
02683 break;
02684
02685 case LENGTH_TK:
02686 case ANGLE_TK:
02687 case TIME_TK:
02688 case FREQ_TK:
02689 if (token->extra_type == a_et) {
02690 *((CRNum **) a_res) = token->u.num;
02691 token->u.num = NULL;
02692 status = CR_OK;
02693 }
02694 break;
02695
02696 case DIMEN_TK:
02697 *((CRNum **) a_res) = token->u.num;
02698 if (a_extra_res == NULL) {
02699 status = CR_BAD_PARAM_ERROR;
02700 goto error;
02701 }
02702
02703 *((CRString **) a_extra_res) = token->dimen;
02704 token->u.num = NULL;
02705 token->dimen = NULL;
02706 status = CR_OK;
02707 break;
02708
02709 case DELIM_TK:
02710 *((guint32 *) a_res) = token->u.unichar;
02711 status = CR_OK;
02712 break;
02713
02714 case UNICODERANGE_TK:
02715 default:
02716 status = CR_PARSING_ERROR;
02717 break;
02718 }
02719
02720 cr_token_destroy (token);
02721 token = NULL;
02722 } else {
02723 cr_tknzr_unget_token (a_this, token);
02724 token = NULL;
02725 status = CR_PARSING_ERROR;
02726 }
02727
02728 return status;
02729
02730 error:
02731
02732 if (token) {
02733 cr_tknzr_unget_token (a_this, token);
02734 token = NULL;
02735 }
02736
02737 return status;
02738 }
02739
02740 void
02741 cr_tknzr_destroy (CRTknzr * a_this)
02742 {
02743 g_return_if_fail (a_this);
02744
02745 if (PRIVATE (a_this) && PRIVATE (a_this)->input) {
02746 if (cr_input_unref (PRIVATE (a_this)->input)
02747 == TRUE) {
02748 PRIVATE (a_this)->input = NULL;
02749 }
02750 }
02751
02752 if (PRIVATE (a_this)->token_cache) {
02753 cr_token_destroy (PRIVATE (a_this)->token_cache);
02754 PRIVATE (a_this)->token_cache = NULL;
02755 }
02756
02757 if (PRIVATE (a_this)) {
02758 g_free (PRIVATE (a_this));
02759 PRIVATE (a_this) = NULL;
02760 }
02761
02762 g_free (a_this);
02763 }