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