1 /* 2 * syck.h 3 * 4 * $Author$ 5 * $Date$ 6 * 7 * Copyright (C) 2003 why the lucky stiff 8 */ 9 10 #ifndef SYCK_H 11 #define SYCK_H 12 13 #ifdef HAVE_CONFIG_H 14 # include "config.h" 15 #endif 16 17 #define SYCK_YAML_MAJOR 1 18 #define SYCK_YAML_MINOR 0 19 20 #define SYCK_VERSION "0.70" 21 #define YAML_DOMAIN "yaml.org,2002" 22 23 #ifdef HAVE_STDLIB_H 24 # include <stdlib.h> 25 #endif 26 27 #ifdef HAVE_STRING_H 28 # include <string.h> 29 #else 30 # include <strings.h> 31 #endif 32 33 #ifdef HAVE_INTRINSICS_H 34 # include <intrinsics.h> 35 #endif 36 37 #include <stddef.h> 38 #include <stdio.h> 39 #include <ctype.h> 40 #ifdef HAVE_ST_H 41 #include <st.h> 42 #else 43 #include "syck_st.h" 44 #endif 45 46 #if defined(__cplusplus) 47 extern "C" { 48 #endif 49 50 /* 51 * Memory Allocation 52 */ 53 #if defined(HAVE_ALLOCA_H) && !defined(__GNUC__) 54 #include <alloca.h> 55 #endif 56 57 #if DEBUG 58 void syck_assert( const char *, unsigned ); 59 # define ASSERT(f) \ 60 if ( f ) \ 61 {} \ 62 else \ 63 syck_assert( __FILE__, __LINE__ ) 64 #else 65 # define ASSERT(f) 66 #endif 67 68 #ifndef NULL 69 # define NULL (void *)0 70 #endif 71 72 #define ALLOC_CT 8 73 #define SYCK_BUFFERSIZE 4096 74 #define S_ALLOC_N(type,n) (type*)malloc(sizeof(type)*(n)) 75 #define S_ALLOC(type) (type*)malloc(sizeof(type)) 76 #define S_REALLOC_N(var,type,n) (var)=(type*)realloc((char*)(var),sizeof(type)*(n)) 77 #define S_FREE(n) free(n); n = NULL; 78 79 #define S_ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n)) 80 81 #define S_MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n)) 82 #define S_MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n)) 83 #define S_MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n)) 84 #define S_MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n)) 85 86 #define BLOCK_FOLD 10 87 #define BLOCK_LIT 20 88 #define BLOCK_PLAIN 30 89 #define NL_CHOMP 40 90 #define NL_KEEP 50 91 92 /* 93 * Node definitions 94 */ 95 #ifndef ST_DATA_T_DEFINED 96 typedef long st_data_t; 97 #endif 98 99 #define SYMID unsigned long 100 101 typedef struct _syck_node SyckNode; 102 103 enum syck_kind_tag { 104 syck_map_kind, 105 syck_seq_kind, 106 syck_str_kind 107 }; 108 109 enum map_part { 110 map_key, 111 map_value 112 }; 113 114 enum map_style { 115 map_none, 116 map_inline 117 }; 118 119 enum seq_style { 120 seq_none, 121 seq_inline 122 }; 123 124 enum scalar_style { 125 scalar_none, 126 scalar_1quote, 127 scalar_2quote, 128 scalar_fold, 129 scalar_literal, 130 scalar_plain 131 }; 132 133 /* 134 * Node metadata struct 135 */ 136 struct _syck_node { 137 /* Symbol table ID */ 138 SYMID id; 139 /* Underlying kind */ 140 enum syck_kind_tag kind; 141 /* Fully qualified tag-uri for type */ 142 char *type_id; 143 /* Anchor name */ 144 char *anchor; 145 union { 146 /* Storage for map data */ 147 struct SyckMap { 148 enum map_style style; 149 SYMID *keys; 150 SYMID *values; 151 long capa; 152 long idx; 153 } *pairs; 154 /* Storage for sequence data */ 155 struct SyckSeq { 156 enum seq_style style; 157 SYMID *items; 158 long capa; 159 long idx; 160 } *list; 161 /* Storage for string data */ 162 struct SyckStr { 163 enum scalar_style style; 164 char *ptr; 165 long len; 166 } *str; 167 } data; 168 /* Shortcut node */ 169 void *shortcut; 170 }; 171 172 /* 173 * Parser definitions 174 */ 175 typedef struct _syck_parser SyckParser; 176 typedef struct _syck_file SyckIoFile; 177 typedef struct _syck_str SyckIoStr; 178 typedef struct _syck_level SyckLevel; 179 180 typedef SYMID (*SyckNodeHandler)(SyckParser *, SyckNode *); 181 typedef void (*SyckErrorHandler)(SyckParser *, const char *); 182 typedef SyckNode * (*SyckBadAnchorHandler)(SyckParser *, const char *); 183 typedef long (*SyckIoFileRead)(char *, SyckIoFile *, long, long); 184 typedef long (*SyckIoStrRead)(char *, SyckIoStr *, long, long); 185 186 enum syck_io_type { 187 syck_io_str, 188 syck_io_file 189 }; 190 191 enum syck_parser_input { 192 syck_yaml_utf8, 193 syck_yaml_utf16, 194 syck_yaml_utf32, 195 syck_bytecode_utf8 196 }; 197 198 enum syck_level_status { 199 syck_lvl_header, 200 syck_lvl_doc, 201 syck_lvl_open, 202 syck_lvl_seq, 203 syck_lvl_map, 204 syck_lvl_block, 205 syck_lvl_str, 206 syck_lvl_iseq, 207 syck_lvl_imap, 208 syck_lvl_end, 209 syck_lvl_pause, 210 syck_lvl_anctag, 211 syck_lvl_mapx, 212 syck_lvl_seqx 213 }; 214 215 /* 216 * Parser structs 217 */ 218 struct _syck_file { 219 /* File pointer */ 220 FILE *ptr; 221 /* Function which FILE -> buffer */ 222 SyckIoFileRead read; 223 }; 224 225 struct _syck_str { 226 /* String buffer pointers */ 227 const char *beg, *ptr, *end; 228 /* Function which string -> buffer */ 229 SyckIoStrRead read; 230 }; 231 232 struct _syck_level { 233 /* Indent */ 234 int spaces; 235 /* Counts nodes emitted at this level, useful for parsing 236 * keys and pairs in bytecode */ 237 int ncount; 238 /* Does node have anchors or tags? */ 239 int anctag; 240 /* Domain prefixing at the given level */ 241 char *domain; 242 /* Keeps a node status */ 243 enum syck_level_status status; 244 }; 245 246 struct _syck_parser { 247 /* Root node */ 248 SYMID root, root_on_error; 249 /* Implicit typing flag */ 250 int implicit_typing, taguri_expansion; 251 /* Scripting language function to handle nodes */ 252 SyckNodeHandler handler; 253 /* Error handler */ 254 SyckErrorHandler error_handler; 255 /* InvalidAnchor handler */ 256 SyckBadAnchorHandler bad_anchor_handler; 257 /* Parser input type */ 258 enum syck_parser_input input_type; 259 /* IO type */ 260 enum syck_io_type io_type; 261 /* Custom buffer size */ 262 size_t bufsize; 263 /* Buffer pointers */ 264 char *buffer, *linectptr, *lineptr, *toktmp, *token, *cursor, *marker, *limit; 265 /* Line counter */ 266 int linect; 267 /* Last token from yylex() */ 268 int last_token; 269 /* Force a token upon next call to yylex() */ 270 int force_token; 271 /* EOF flag */ 272 int eof; 273 union { 274 SyckIoFile *file; 275 SyckIoStr *str; 276 } io; 277 /* Symbol table for anchors */ 278 st_table *anchors, *bad_anchors; 279 /* Optional symbol table for SYMIDs */ 280 st_table *syms; 281 /* Levels of indentation */ 282 SyckLevel *levels; 283 int lvl_idx; 284 int lvl_capa; 285 /* Pointer for extension's use */ 286 void *bonus; 287 }; 288 289 /* 290 * Emitter definitions 291 */ 292 typedef struct _syck_emitter SyckEmitter; 293 typedef struct _syck_emitter_node SyckEmitterNode; 294 295 typedef void (*SyckOutputHandler)(SyckEmitter *, const char *, long); 296 typedef void (*SyckEmitterHandler)(SyckEmitter *, st_data_t); 297 298 enum doc_stage { 299 doc_open, 300 doc_processing 301 }; 302 303 /* 304 * Emitter struct 305 */ 306 struct _syck_emitter { 307 /* Headerless doc flag */ 308 int headless; 309 /* Force header? */ 310 int use_header; 311 /* Force version? */ 312 int use_version; 313 /* Sort hash keys */ 314 int sort_keys; 315 /* Anchor format */ 316 char *anchor_format; 317 /* Explicit typing on all collections? */ 318 int explicit_typing; 319 /* Best width on folded scalars */ 320 int best_width; 321 /* Use literal[1] or folded[2] blocks on all text? */ 322 enum scalar_style style; 323 /* Stage of written document */ 324 enum doc_stage stage; 325 /* Level counter */ 326 int level; 327 /* Default indentation */ 328 int indent; 329 /* Object ignore ID */ 330 SYMID ignore_id; 331 /* Symbol table for anchors */ 332 st_table *markers, *anchors, *anchored; 333 /* Custom buffer size */ 334 size_t bufsize; 335 /* Buffer */ 336 char *buffer, *marker; 337 /* Absolute position of the buffer */ 338 long bufpos; 339 /* Handler for emitter nodes */ 340 SyckEmitterHandler emitter_handler; 341 /* Handler for output */ 342 SyckOutputHandler output_handler; 343 /* Levels of indentation */ 344 SyckLevel *levels; 345 int lvl_idx; 346 int lvl_capa; 347 /* Pointer for extension's use */ 348 void *bonus; 349 }; 350 351 /* 352 * Emitter node metadata struct 353 */ 354 struct _syck_emitter_node { 355 /* Node buffer position */ 356 long pos; 357 /* Current indent */ 358 long indent; 359 /* Collection? */ 360 int is_shortcut; 361 }; 362 363 /* 364 * Handler prototypes 365 */ 366 SYMID syck_hdlr_add_node( SyckParser *, SyckNode * ); 367 SyckNode *syck_hdlr_add_anchor( SyckParser *, char *, SyckNode * ); 368 void syck_hdlr_remove_anchor( SyckParser *, char * ); 369 SyckNode *syck_hdlr_get_anchor( SyckParser *, char * ); 370 void syck_add_transfer( char *, SyckNode *, int ); 371 char *syck_xprivate( char *, int ); 372 char *syck_taguri( const char *, const char *, int ); 373 int syck_tagcmp( const char *, const char * ); 374 int syck_add_sym( SyckParser *, char * ); 375 int syck_lookup_sym( SyckParser *, SYMID, char ** ); 376 int syck_try_implicit( SyckNode * ); 377 char *syck_type_id_to_uri( char * ); 378 void try_tag_implicit( SyckNode *, int ); 379 char *syck_match_implicit( const char *, size_t ); 380 381 /* 382 * API prototypes 383 */ 384 char *syck_strndup( const char *, long ); 385 long syck_io_file_read( char *, SyckIoFile *, long, long ); 386 long syck_io_str_read( char *, SyckIoStr *, long, long ); 387 char *syck_base64enc( const char *, long ); 388 char *syck_base64dec( const char *, long ); 389 SyckEmitter *syck_new_emitter( void ); 390 SYMID syck_emitter_mark_node( SyckEmitter *, st_data_t ); 391 void syck_emitter_ignore_id( SyckEmitter *, SYMID ); 392 void syck_output_handler( SyckEmitter *, SyckOutputHandler ); 393 void syck_emitter_handler( SyckEmitter *, SyckEmitterHandler ); 394 void syck_free_emitter( SyckEmitter * ); 395 void syck_emitter_clear( SyckEmitter * ); 396 void syck_emitter_write( SyckEmitter *, const char *, long ); 397 void syck_emitter_escape( SyckEmitter *, const char *, long ); 398 void syck_emitter_flush( SyckEmitter *, long ); 399 void syck_emit( SyckEmitter *, st_data_t ); 400 void syck_emit_scalar( SyckEmitter *, const char *, enum scalar_style, int, int, char, const char *, long ); 401 void syck_emit_1quoted( SyckEmitter *, int, const char *, long ); 402 void syck_emit_2quoted( SyckEmitter *, int, const char *, long ); 403 void syck_emit_folded( SyckEmitter *, int, char, const char *, long ); 404 void syck_emit_literal( SyckEmitter *, char, const char *, long ); 405 void syck_emit_seq( SyckEmitter *, const char *, enum seq_style ); 406 void syck_emit_item( SyckEmitter *, st_data_t ); 407 void syck_emit_map( SyckEmitter *, const char *, enum map_style ); 408 void syck_emit_end( SyckEmitter * ); 409 void syck_emit_tag( SyckEmitter *, const char *, const char * ); 410 void syck_emit_indent( SyckEmitter * ); 411 SyckLevel *syck_emitter_current_level( SyckEmitter * ); 412 SyckLevel *syck_emitter_parent_level( SyckEmitter * ); 413 void syck_emitter_pop_level( SyckEmitter * ); 414 void syck_emitter_add_level( SyckEmitter *, int, enum syck_level_status ); 415 void syck_emitter_reset_levels( SyckEmitter * ); 416 SyckParser *syck_new_parser(); 417 void syck_free_parser( SyckParser * ); 418 void syck_parser_set_root_on_error( SyckParser *, SYMID ); 419 void syck_parser_implicit_typing( SyckParser *, int ); 420 void syck_parser_taguri_expansion( SyckParser *, int ); 421 int syck_scan_scalar( int, const char *, long ); 422 void syck_parser_handler( SyckParser *, SyckNodeHandler ); 423 void syck_parser_error_handler( SyckParser *, SyckErrorHandler ); 424 void syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler ); 425 void syck_parser_file( SyckParser *, FILE *, SyckIoFileRead ); 426 void syck_parser_str( SyckParser *, const char *, long, SyckIoStrRead ); 427 void syck_parser_str_auto( SyckParser *, const char *, SyckIoStrRead ); 428 SyckLevel *syck_parser_current_level( SyckParser * ); 429 void syck_parser_add_level( SyckParser *, int, enum syck_level_status ); 430 void syck_parser_pop_level( SyckParser * ); 431 void free_any_io( SyckParser * ); 432 long syck_parser_read( SyckParser * ); 433 long syck_parser_readlen( SyckParser *, long ); 434 SYMID syck_parse( SyckParser * ); 435 void syck_default_error_handler( SyckParser *, const char * ); 436 SYMID syck_yaml2byte_handler( SyckParser *, SyckNode * ); 437 char *syck_yaml2byte( const char * ); 438 439 /* 440 * Allocation prototypes 441 */ 442 SyckNode *syck_alloc_map(); 443 SyckNode *syck_alloc_seq(); 444 SyckNode *syck_alloc_str(); 445 void syck_free_node( SyckNode * ); 446 void syck_free_members( SyckNode * ); 447 SyckNode *syck_new_str( const char *, enum scalar_style ); 448 SyckNode *syck_new_str2( const char *, long, enum scalar_style ); 449 void syck_replace_str( SyckNode *, const char *, enum scalar_style ); 450 void syck_replace_str2( SyckNode *, const char *, long, enum scalar_style ); 451 void syck_str_blow_away_commas( SyckNode * ); 452 char *syck_str_read( SyckNode * ); 453 SyckNode *syck_new_map( SYMID, SYMID ); 454 void syck_map_empty( SyckNode * ); 455 void syck_map_add( SyckNode *, SYMID, SYMID ); 456 SYMID syck_map_read( SyckNode *, enum map_part, long ); 457 void syck_map_assign( SyckNode *, enum map_part, long, SYMID ); 458 long syck_map_count( SyckNode * ); 459 void syck_map_update( SyckNode *, SyckNode * ); 460 SyckNode *syck_new_seq( SYMID ); 461 void syck_seq_empty( SyckNode * ); 462 void syck_seq_add( SyckNode *, SYMID ); 463 void syck_seq_assign( SyckNode *, long, SYMID ); 464 SYMID syck_seq_read( SyckNode *, long ); 465 long syck_seq_count( SyckNode * ); 466 467 /* 468 * Lexer prototypes 469 */ 470 void syckerror( void *, const char * ); 471 int syckparse( void * ); 472 473 #if defined(__cplusplus) 474 } /* extern "C" { */ 475 #endif 476 477 #endif /* ifndef SYCK_H */ 478