Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /* 00002 * syck.h 00003 * 00004 * $Author: naruse $ 00005 * 00006 * Copyright (C) 2003 why the lucky stiff 00007 */ 00008 00009 #ifndef SYCK_H 00010 #define SYCK_H 00011 00012 #define SYCK_YAML_MAJOR 1 00013 #define SYCK_YAML_MINOR 0 00014 00015 #define YAML_DOMAIN "yaml.org,2002" 00016 00017 #include <stdio.h> 00018 #include <stdlib.h> 00019 #include <ctype.h> 00020 #include "ruby/st.h" 00021 00022 #if defined(__cplusplus) 00023 extern "C" { 00024 #endif 00025 00026 /* 00027 * Memory Allocation 00028 */ 00029 #if defined(HAVE_ALLOCA_H) && !defined(__GNUC__) 00030 #include <alloca.h> 00031 #endif 00032 00033 #ifdef DEBUG 00034 void syck_assert( const char *, unsigned, const char * ); 00035 # define ASSERT(f) \ 00036 (( f ) ? (void)0 : syck_assert( __FILE__, __LINE__, #f )) 00037 #else 00038 # define ASSERT(f) ((void)0) 00039 #endif 00040 00041 #ifndef NULL 00042 # define NULL (void *)0 00043 #endif 00044 00045 #define ALLOC_CT 8 00046 #define SYCK_BUFFERSIZE 4096 00047 #define S_ALLOC_N(type,n) (type*)malloc(sizeof(type)*(n)) 00048 #define S_ALLOC(type) (type*)malloc(sizeof(type)) 00049 #define S_REALLOC_N(var,type,n) (var)=(type*)realloc((char*)(var),sizeof(type)*(n)) 00050 #define S_FREE(n) if (n) { free(n); n = NULL; } 00051 00052 #define S_ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n)) 00053 00054 #define S_MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n)) 00055 #define S_MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n)) 00056 #define S_MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n)) 00057 #define S_MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n)) 00058 00059 #define BLOCK_FOLD 10 00060 #define BLOCK_LIT 20 00061 #define BLOCK_PLAIN 30 00062 #define NL_CHOMP 40 00063 #define NL_KEEP 50 00064 00065 /* 00066 * Node definitions 00067 */ 00068 #ifndef ST_DATA_T_DEFINED 00069 typedef long st_data_t; 00070 #endif 00071 00072 #define SYMID st_data_t 00073 00074 typedef struct _syck_node SyckNode; 00075 00076 enum syck_kind_tag { 00077 syck_map_kind, 00078 syck_seq_kind, 00079 syck_str_kind 00080 }; 00081 00082 enum map_part { 00083 map_key, 00084 map_value 00085 }; 00086 00087 enum map_style { 00088 map_none, 00089 map_inline 00090 }; 00091 00092 enum seq_style { 00093 seq_none, 00094 seq_inline 00095 }; 00096 00097 enum scalar_style { 00098 scalar_none, 00099 scalar_1quote, 00100 scalar_2quote, 00101 scalar_fold, 00102 scalar_literal, 00103 scalar_plain 00104 }; 00105 00106 /* 00107 * Node metadata struct 00108 */ 00109 struct _syck_node { 00110 /* Symbol table ID */ 00111 SYMID id; 00112 /* Underlying kind */ 00113 enum syck_kind_tag kind; 00114 /* Fully qualified tag-uri for type */ 00115 char *type_id; 00116 /* Anchor name */ 00117 char *anchor; 00118 union { 00119 /* Storage for map data */ 00120 struct SyckMap { 00121 enum map_style style; 00122 SYMID *keys; 00123 SYMID *values; 00124 long capa; 00125 long idx; 00126 } *pairs; 00127 /* Storage for sequence data */ 00128 struct SyckSeq { 00129 enum seq_style style; 00130 SYMID *items; 00131 long capa; 00132 long idx; 00133 } *list; 00134 /* Storage for string data */ 00135 struct SyckStr { 00136 enum scalar_style style; 00137 char *ptr; 00138 long len; 00139 } *str; 00140 } data; 00141 /* Shortcut node */ 00142 void *shortcut; 00143 }; 00144 00145 /* 00146 * Parser definitions 00147 */ 00148 typedef struct _syck_parser SyckParser; 00149 typedef struct _syck_file SyckIoFile; 00150 typedef struct _syck_str SyckIoStr; 00151 typedef struct _syck_level SyckLevel; 00152 00153 typedef SYMID (*SyckNodeHandler)(SyckParser *, SyckNode *); 00154 typedef void (*SyckErrorHandler)(SyckParser *, const char *); 00155 typedef SyckNode * (*SyckBadAnchorHandler)(SyckParser *, char *); 00156 typedef long (*SyckIoFileRead)(char *, SyckIoFile *, long, long); 00157 typedef long (*SyckIoStrRead)(char *, SyckIoStr *, long, long); 00158 00159 enum syck_io_type { 00160 syck_io_str, 00161 syck_io_file 00162 }; 00163 00164 enum syck_parser_input { 00165 syck_yaml_utf8, 00166 syck_yaml_utf16, 00167 syck_yaml_utf32, 00168 syck_bytecode_utf8 00169 }; 00170 00171 enum syck_level_status { 00172 syck_lvl_header, 00173 syck_lvl_doc, 00174 syck_lvl_open, 00175 syck_lvl_seq, 00176 syck_lvl_map, 00177 syck_lvl_block, 00178 syck_lvl_str, 00179 syck_lvl_iseq, 00180 syck_lvl_imap, 00181 syck_lvl_end, 00182 syck_lvl_pause, 00183 syck_lvl_anctag, 00184 syck_lvl_mapx, 00185 syck_lvl_seqx 00186 }; 00187 00188 /* 00189 * Parser structs 00190 */ 00191 struct _syck_file { 00192 /* File pointer */ 00193 FILE *ptr; 00194 /* Function which FILE -> buffer */ 00195 SyckIoFileRead read; 00196 }; 00197 00198 struct _syck_str { 00199 /* String buffer pointers */ 00200 char *beg, *ptr, *end; 00201 /* Function which string -> buffer */ 00202 SyckIoStrRead read; 00203 }; 00204 00205 struct _syck_level { 00206 /* Indent */ 00207 int spaces; 00208 /* Counts nodes emitted at this level, useful for parsing 00209 * keys and pairs in bytecode */ 00210 int ncount; 00211 /* Does node have anchors or tags? */ 00212 int anctag; 00213 /* Domain prefixing at the given level */ 00214 char *domain; 00215 /* Keeps a node status */ 00216 enum syck_level_status status; 00217 }; 00218 00219 struct _syck_parser { 00220 /* Root node */ 00221 SYMID root, root_on_error; 00222 /* Implicit typing flag */ 00223 int implicit_typing, taguri_expansion; 00224 /* Scripting language function to handle nodes */ 00225 SyckNodeHandler handler; 00226 /* Error handler */ 00227 SyckErrorHandler error_handler; 00228 /* InvalidAnchor handler */ 00229 SyckBadAnchorHandler bad_anchor_handler; 00230 /* Parser input type */ 00231 enum syck_parser_input input_type; 00232 /* IO type */ 00233 enum syck_io_type io_type; 00234 /* Custom buffer size */ 00235 size_t bufsize; 00236 /* Buffer pointers */ 00237 char *buffer, *linectptr, *lineptr, *toktmp, *token, *cursor, *marker, *limit; 00238 /* Line counter */ 00239 int linect; 00240 /* Last token from yylex() */ 00241 int last_token; 00242 /* Force a token upon next call to yylex() */ 00243 int force_token; 00244 /* EOF flag */ 00245 int eof; 00246 union { 00247 SyckIoFile *file; 00248 SyckIoStr *str; 00249 } io; 00250 /* Symbol table for anchors */ 00251 st_table *anchors, *bad_anchors; 00252 /* Optional symbol table for SYMIDs */ 00253 st_table *syms; 00254 /* Levels of indentation */ 00255 SyckLevel *levels; 00256 int lvl_idx; 00257 int lvl_capa; 00258 /* Pointer for extension's use */ 00259 void *bonus; 00260 }; 00261 00262 /* 00263 * Emitter definitions 00264 */ 00265 typedef struct _syck_emitter SyckEmitter; 00266 typedef struct _syck_emitter_node SyckEmitterNode; 00267 00268 typedef void (*SyckOutputHandler)(SyckEmitter *, char *, long); 00269 typedef void (*SyckEmitterHandler)(SyckEmitter *, st_data_t); 00270 00271 enum doc_stage { 00272 doc_open, 00273 doc_processing 00274 }; 00275 00276 /* 00277 * Emitter struct 00278 */ 00279 struct _syck_emitter { 00280 /* Headerless doc flag */ 00281 int headless; 00282 /* Force header? */ 00283 int use_header; 00284 /* Force version? */ 00285 int use_version; 00286 /* Sort hash keys */ 00287 int sort_keys; 00288 /* Anchor format */ 00289 char *anchor_format; 00290 /* Explicit typing on all collections? */ 00291 int explicit_typing; 00292 /* Best width on folded scalars */ 00293 int best_width; 00294 /* Use literal[1] or folded[2] blocks on all text? */ 00295 enum scalar_style style; 00296 /* Stage of written document */ 00297 enum doc_stage stage; 00298 /* Level counter */ 00299 int level; 00300 /* Default indentation */ 00301 int indent; 00302 /* Object ignore ID */ 00303 SYMID ignore_id; 00304 /* Symbol table for anchors */ 00305 st_table *markers, *anchors, *anchored; 00306 /* Custom buffer size */ 00307 size_t bufsize; 00308 /* Buffer */ 00309 char *buffer, *marker; 00310 /* Absolute position of the buffer */ 00311 long bufpos; 00312 /* Handler for emitter nodes */ 00313 SyckEmitterHandler emitter_handler; 00314 /* Handler for output */ 00315 SyckOutputHandler output_handler; 00316 /* Levels of indentation */ 00317 SyckLevel *levels; 00318 int lvl_idx; 00319 int lvl_capa; 00320 /* Pointer for extension's use */ 00321 void *bonus; 00322 }; 00323 00324 /* 00325 * Emitter node metadata struct 00326 */ 00327 struct _syck_emitter_node { 00328 /* Node buffer position */ 00329 long pos; 00330 /* Current indent */ 00331 long indent; 00332 /* Collection? */ 00333 int is_shortcut; 00334 }; 00335 00336 /* 00337 * Handler prototypes 00338 */ 00339 SYMID syck_hdlr_add_node( SyckParser *, SyckNode * ); 00340 SyckNode *syck_hdlr_add_anchor( SyckParser *, char *, SyckNode * ); 00341 void syck_hdlr_remove_anchor( SyckParser *, char * ); 00342 SyckNode *syck_hdlr_get_anchor( SyckParser *, char * ); 00343 void syck_add_transfer( char *, SyckNode *, int ); 00344 char *syck_xprivate( const char *, int ); 00345 char *syck_taguri( const char *, const char *, int ); 00346 int syck_tagcmp( const char *, const char * ); 00347 int syck_add_sym( SyckParser *, void * ); 00348 int syck_lookup_sym( SyckParser *, SYMID, void ** ); 00349 int syck_try_implicit( SyckNode * ); 00350 char *syck_type_id_to_uri( const char * ); 00351 void try_tag_implicit( SyckNode *, int ); 00352 const char *syck_match_implicit( const char *, size_t ); 00353 00354 /* 00355 * API prototypes 00356 */ 00357 char *syck_strndup( const char *, long ); 00358 long syck_io_file_read( char *, SyckIoFile *, long, long ); 00359 long syck_io_str_read( char *, SyckIoStr *, long, long ); 00360 char *syck_base64enc( char *, long ); 00361 char *syck_base64dec( char *, long ); 00362 SyckEmitter *syck_new_emitter(void); 00363 SYMID syck_emitter_mark_node( SyckEmitter *, st_data_t ); 00364 void syck_emitter_ignore_id( SyckEmitter *, SYMID ); 00365 void syck_output_handler( SyckEmitter *, SyckOutputHandler ); 00366 void syck_emitter_handler( SyckEmitter *, SyckEmitterHandler ); 00367 void syck_free_emitter( SyckEmitter * ); 00368 void syck_emitter_clear( SyckEmitter * ); 00369 void syck_emitter_write( SyckEmitter *, const char *, long ); 00370 void syck_emitter_escape( SyckEmitter *, const char *, long ); 00371 void syck_emitter_flush( SyckEmitter *, long ); 00372 void syck_emit( SyckEmitter *, st_data_t ); 00373 void syck_emit_scalar( SyckEmitter *, const char *, enum scalar_style, int, int, char, const char *, long ); 00374 void syck_emit_1quoted( SyckEmitter *, int, const char *, long ); 00375 void syck_emit_2quoted( SyckEmitter *, int, const char *, long ); 00376 void syck_emit_folded( SyckEmitter *, int, char, const char *, long ); 00377 void syck_emit_literal( SyckEmitter *, char, const char *, long ); 00378 void syck_emit_seq( SyckEmitter *, const char *, enum seq_style ); 00379 void syck_emit_item( SyckEmitter *, st_data_t ); 00380 void syck_emit_map( SyckEmitter *, const char *, enum map_style ); 00381 void syck_emit_end( SyckEmitter * ); 00382 void syck_emit_tag( SyckEmitter *, const char *, const char * ); 00383 void syck_emit_indent( SyckEmitter * ); 00384 SyckLevel *syck_emitter_current_level( SyckEmitter * ); 00385 SyckLevel *syck_emitter_parent_level( SyckEmitter * ); 00386 void syck_emitter_pop_level( SyckEmitter * ); 00387 void syck_emitter_add_level( SyckEmitter *, int, enum syck_level_status ); 00388 void syck_emitter_reset_levels( SyckEmitter * ); 00389 SyckParser *syck_new_parser(void); 00390 void syck_free_parser( SyckParser * ); 00391 void syck_parser_set_root_on_error( SyckParser *, SYMID ); 00392 void syck_parser_implicit_typing( SyckParser *, int ); 00393 void syck_parser_taguri_expansion( SyckParser *, int ); 00394 int syck_scan_scalar( int, const char *, long ); 00395 void syck_parser_handler( SyckParser *, SyckNodeHandler ); 00396 void syck_parser_error_handler( SyckParser *, SyckErrorHandler ); 00397 void syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler ); 00398 void syck_parser_set_input_type( SyckParser *, enum syck_parser_input ); 00399 void syck_parser_file( SyckParser *, FILE *, SyckIoFileRead ); 00400 void syck_parser_str( SyckParser *, char *, long, SyckIoStrRead ); 00401 void syck_parser_str_auto( SyckParser *, char *, SyckIoStrRead ); 00402 SyckLevel *syck_parser_current_level( SyckParser * ); 00403 void syck_parser_add_level( SyckParser *, int, enum syck_level_status ); 00404 void syck_parser_pop_level( SyckParser * ); 00405 void free_any_io( SyckParser * ); 00406 long syck_parser_read( SyckParser * ); 00407 long syck_parser_readlen( SyckParser *, long ); 00408 SYMID syck_parse( SyckParser * ); 00409 void syck_default_error_handler( SyckParser *, const char * ); 00410 SYMID syck_yaml2byte_handler( SyckParser *, SyckNode * ); 00411 char *syck_yaml2byte( char * ); 00412 00413 /* 00414 * Allocation prototypes 00415 */ 00416 SyckNode *syck_alloc_map(void); 00417 SyckNode *syck_alloc_seq(void); 00418 SyckNode *syck_alloc_str(void); 00419 void syck_free_node( SyckNode * ); 00420 void syck_free_members( SyckNode * ); 00421 SyckNode *syck_new_str( const char *, enum scalar_style ); 00422 SyckNode *syck_new_str2( const char *, long, enum scalar_style ); 00423 void syck_replace_str( SyckNode *, char *, enum scalar_style ); 00424 void syck_replace_str2( SyckNode *, char *, long, enum scalar_style ); 00425 void syck_str_blow_away_commas( SyckNode * ); 00426 char *syck_str_read( SyckNode * ); 00427 SyckNode *syck_new_map( SYMID, SYMID ); 00428 void syck_map_empty( SyckNode * ); 00429 void syck_map_add( SyckNode *, SYMID, SYMID ); 00430 SYMID syck_map_read( SyckNode *, enum map_part, long ); 00431 void syck_map_assign( SyckNode *, enum map_part, long, SYMID ); 00432 long syck_map_count( SyckNode * ); 00433 void syck_map_update( SyckNode *, SyckNode * ); 00434 SyckNode *syck_new_seq( SYMID ); 00435 void syck_seq_empty( SyckNode * ); 00436 void syck_seq_add( SyckNode *, SYMID ); 00437 void syck_seq_assign( SyckNode *, long, SYMID ); 00438 SYMID syck_seq_read( SyckNode *, long ); 00439 long syck_seq_count( SyckNode * ); 00440 00441 /* 00442 * Lexer prototypes 00443 */ 00444 void syckerror( const char * ); 00445 int syckparse( void * ); 00446 union YYSTYPE; 00447 int sycklex( union YYSTYPE *, SyckParser * ); 00448 00449 #if defined(__cplusplus) 00450 } /* extern "C" { */ 00451 #endif 00452 00453 #endif /* ifndef SYCK_H */ 00454