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