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