HsSyck 0.2 → 0.3
raw patch · 6 files changed
+847/−26 lines, 6 files
Files
- Data/Yaml/Syck.hsc +69/−25
- HsSyck.cabal +2/−1
- syck/gram.h +79/−0
- syck/syck.h +481/−0
- syck/syck_st.h +46/−0
- syck/yamlbyte.h +170/−0
Data/Yaml/Syck.hsc view
@@ -11,6 +11,7 @@ import Control.Exception (bracket) import Data.IORef+import Data.Maybe (fromJust) import Data.Generics import Foreign.Ptr import Foreign.StablePtr@@ -19,6 +20,7 @@ import Foreign.Marshal.Alloc import Foreign.Marshal.Utils import Foreign.Storable+import System.IO.Unsafe import GHC.Ptr (Ptr(..)) import qualified Data.HashTable as Hash import qualified Data.ByteString.Char8 as Buf@@ -60,7 +62,7 @@ type SyckParser = Ptr () type SyckNodeHandler = SyckParser -> SyckNode -> IO SYMID type SyckErrorHandler = SyckParser -> CString -> IO ()-type SyckBadAnchorHandler = SyckParser -> CString -> IO SyckNode+type SyckBadAnchorHandler = SyckParser -> CString -> IO SyckNodePtr type SyckNodePtr = Ptr CString type SyckEmitter = Ptr () type SyckEmitterHandler = SyckEmitter -> Ptr () -> IO ()@@ -68,8 +70,11 @@ data SyckKind = SyckMap | SyckSeq | SyckStr deriving (Show, Ord, Eq, Enum) +maxId :: SYMID+maxId = maxBound+ nilNode :: YamlNode-nilNode = MkNode 0 ENil Nothing ASingleton+nilNode = MkNode maxId ENil Nothing ASingleton {-# INLINE unpackBuf #-} unpackBuf :: Buf -> String@@ -84,10 +89,10 @@ tagNode tag node = node{n_tag = tag} mkNode :: YamlElem -> YamlNode-mkNode x = MkNode 0 x Nothing ASingleton+mkNode x = MkNode maxId x Nothing ASingleton mkTagNode :: String -> YamlElem -> YamlNode-mkTagNode tag e = MkNode 0 e (Just $! packBuf tag) ASingleton+mkTagNode tag e = MkNode maxId e (Just $! packBuf tag) ASingleton mkTagStrNode :: String -> String -> YamlNode mkTagStrNode tag str = mkTagNode tag (EStr $! packBuf str)@@ -182,12 +187,14 @@ emitNode freeze e n | ESeq sq <- n_elem n = do withTag n (Ptr "array"##) $ \tag ->+-- syck_emit_seq e tag seqInline syck_emit_seq e tag seqNone mapM_ (syck_emit_item e) =<< mapM freeze sq syck_emit_end e emitNode freeze e n | EMap m <- n_elem n = do withTag n (Ptr "map"##) $ \tag ->+-- syck_emit_map e tag mapInline syck_emit_map e tag mapNone flip mapM_ m (\(k,v) -> do syck_emit_item e =<< freeze k@@ -209,11 +216,12 @@ parseYamlCStr :: CString -> IO YamlNode parseYamlCStr cstr = do bracket syck_new_parser syck_free_parser $ \parser -> do- err <- newIORef Nothing+ err <- newIORef Nothing+ badancs <- Hash.new (==) Hash.hashInt syck_parser_str_auto parser cstr nullFunPtr- syck_parser_handler parser =<< mkNodeCallback nodeCallback+ syck_parser_handler parser =<< mkNodeCallback (nodeCallback badancs) syck_parser_error_handler parser =<< mkErrorCallback (errorCallback err)- syck_parser_bad_anchor_handler parser =<< mkBadHandlerCallback badAnchorHandlerCallback+ syck_parser_bad_anchor_handler parser =<< mkBadHandlerCallback (badAnchorHandlerCallback badancs) syck_parser_implicit_typing parser 0 syck_parser_taguri_expansion parser 0 symId <- syck_parse parser@@ -223,19 +231,50 @@ Nothing -> return nilNode Just e -> fail e -nodeCallback :: SyckParser -> SyckNode -> IO SYMID-nodeCallback parser syckNode = do+type BadAnchorTable = Hash.HashTable Int YamlNode+++nodeCallback :: BadAnchorTable -> SyckParser -> SyckNode -> IO SYMID+nodeCallback badancs parser syckNode = mdo+ nodeId <- #{peek SyckNode, id} syckNode kind <- syckNodeKind syckNode- len <- syckNodeLength kind syckNode- node <- parseNode kind parser syckNode len++ let makeRegularNode = do+ len <- syckNodeLength kind syckNode+ parseNode kind parser syckNode len symId++ node <- case kind of+ SyckMap -> do+ rv <- Hash.lookup badancs (syckNode `minusPtr` nullPtr)+ case rv of+ Just{} -> do+ -- print ("bad anchor wanted", syckNode)+ unsafeInterleaveIO (fmap fromJust (Hash.lookup badancs (nodePtr `minusPtr` nullPtr)))+ _ -> makeRegularNode+ _ -> makeRegularNode nodePtr <- writeNode node- symId <- syck_add_sym parser nodePtr- return (fromIntegral symId) -badAnchorHandlerCallback :: SyckBadAnchorHandler-badAnchorHandlerCallback _parser _cstr = do- fail "moose!"+ -- Do something here about circular refs.+ case nodeId :: SYMID of+ 0 -> return False+ _ -> alloca $ \origPtr -> do+ syck_lookup_sym parser nodeId origPtr+ ptr <- peek origPtr+ -- print ("bad anchor handled", nodeId, ptr)+ Hash.update badancs (ptr `minusPtr` nullPtr) node + symId <- fmap fromIntegral (syck_add_sym parser nodePtr)++ return symId++badAnchorHandlerCallback :: BadAnchorTable -> SyckBadAnchorHandler+badAnchorHandlerCallback badancs parser cstr = do+ syckNode <- syck_alloc_map+ -- msg <- peekCString cstr+ -- print ("bad anchor encountered", syckNode)+ Hash.insert badancs (syckNode `minusPtr` nullPtr) (error "unhandled bad anchor")+ return syckNode+ errorCallback :: IORef (Maybe String) -> SyckErrorHandler errorCallback err parser cstr = do msg <- peekCString cstr@@ -250,8 +289,10 @@ freezeNode :: Hash.HashTable Int (Ptr a) -> YamlNode -> IO (Ptr a) freezeNode nodes MkNode{ n_anchor = AReference n } = do- Just ptr <- Hash.lookup nodes n- return ptr+ rv <- Hash.lookup nodes n+ case rv of+ Just ptr -> return ptr+ _ -> fail $ "Failed to resolve reference: " ++ show n freezeNode nodes node = do ptr <- newStablePtr node case n_anchor node of@@ -308,8 +349,8 @@ syckNodeLength SyckSeq = (#{peek struct SyckSeq, idx} =<<) . #{peek SyckNode, data} syckNodeLength SyckStr = (#{peek struct SyckStr, len} =<<) . #{peek SyckNode, data} -parseNode :: SyckKind -> SyckParser -> SyckNode -> CLong -> IO YamlNode-parseNode SyckMap parser syckNode len = do+parseNode :: SyckKind -> SyckParser -> SyckNode -> CLong -> SYMID -> IO YamlNode+parseNode SyckMap parser syckNode len nid = do tag <- syckNodeTag syckNode pairs <- (`mapM` [0..len-1]) $ \idx -> do keyId <- syck_map_read syckNode 0 idx@@ -317,20 +358,20 @@ valId <- syck_map_read syckNode 1 idx val <- readNode parser valId return (key, val)- return $ nilNode{ n_elem = EMap pairs, n_tag = tag}+ return $ nilNode{ n_elem = EMap pairs, n_tag = tag, n_id = nid } -parseNode SyckSeq parser syckNode len = do+parseNode SyckSeq parser syckNode len nid = do tag <- syckNodeTag syckNode nodes <- (`mapM` [0..len-1]) $ \idx -> do symId <- syck_seq_read syckNode idx readNode parser symId- return $ nilNode{ n_elem = ESeq nodes, n_tag = tag }+ return $ nilNode{ n_elem = ESeq nodes, n_tag = tag, n_id = nid } -parseNode SyckStr _ syckNode len = do+parseNode SyckStr _ syckNode len nid = do tag <- syckNodeTag syckNode cstr <- syck_str_read syckNode buf <- copyCStringLen (cstr, fromEnum len)- let node = nilNode{ n_elem = EStr buf, n_tag = tag }+ let node = nilNode{ n_elem = EStr buf, n_tag = tag, n_id = nid } if tag == Nothing && Buf.length buf == 1 && Buf.index buf 0 == '~' then do style <- syck_str_style syckNode@@ -356,6 +397,9 @@ foreign import ccall syck_new_parser :: IO SyckParser++foreign import ccall+ syck_alloc_map :: IO SyckNodePtr foreign import ccall syck_parser_str_auto :: SyckParser -> CString -> FunPtr () -> IO ()
HsSyck.cabal view
@@ -1,5 +1,5 @@ Name: HsSyck-Version: 0.2+Version: 0.3 Category: Data Synopsis: Fast, lightweight YAML loader and dumper Description: Fast, lightweight YAML loader and dumper@@ -15,4 +15,5 @@ c-sources: syck/bytecode.c syck/emitter.c syck/gram.c syck/handler.c syck/implicit.c syck/node.c syck/syck.c syck/syck_st.c syck/token.c syck/yaml2byte.c +extra-source-files: syck/syck.h syck/syck_st.h syck/gram.h syck/yamlbyte.h include-dirs: syck
+ syck/gram.h view
@@ -0,0 +1,79 @@+/* A Bison parser, made by GNU Bison 1.875d. */++/* Skeleton parser for Yacc-like parsing with Bison,+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.++ This program is free software; you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation; either version 2, or (at your option)+ any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program; if not, write to the Free Software+ Foundation, Inc., 59 Temple Place - Suite 330,+ Boston, MA 02111-1307, USA. */++/* As a special exception, when this file is copied by Bison into a+ Bison output file, you may use that output file without restriction.+ This special exception was added by the Free Software Foundation+ in version 1.24 of Bison. */++/* Tokens. */+#ifndef YYTOKENTYPE+# define YYTOKENTYPE+ /* Put the tokens into the symbol table, so that GDB and other debuggers+ know about them. */+ enum yytokentype {+ YAML_ANCHOR = 258,+ YAML_ALIAS = 259,+ YAML_TRANSFER = 260,+ YAML_TAGURI = 261,+ YAML_ITRANSFER = 262,+ YAML_WORD = 263,+ YAML_PLAIN = 264,+ YAML_BLOCK = 265,+ YAML_DOCSEP = 266,+ YAML_IOPEN = 267,+ YAML_INDENT = 268,+ YAML_IEND = 269+ };+#endif+#define YAML_ANCHOR 258+#define YAML_ALIAS 259+#define YAML_TRANSFER 260+#define YAML_TAGURI 261+#define YAML_ITRANSFER 262+#define YAML_WORD 263+#define YAML_PLAIN 264+#define YAML_BLOCK 265+#define YAML_DOCSEP 266+#define YAML_IOPEN 267+#define YAML_INDENT 268+#define YAML_IEND 269+++++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)+#line 35 "gram.y"+typedef union YYSTYPE {+ SYMID nodeId;+ SyckNode *nodeData;+ char *name;+} YYSTYPE;+/* Line 1285 of yacc.c. */+#line 71 "gram.h"+# define yystype YYSTYPE /* obsolescent; will be withdrawn */+# define YYSTYPE_IS_DECLARED 1+# define YYSTYPE_IS_TRIVIAL 1+#endif+++++
+ syck/syck.h view
@@ -0,0 +1,481 @@+/*+ * syck.h+ *+ * $Author: why $+ * $Date: 2005-11-14 07:43:56 +0800 (一, 14 11 2005) $+ *+ * Copyright (C) 2003 why the lucky stiff+ */++#ifndef SYCK_H+#define SYCK_H++#ifndef HAVE_STDLIB_H+#define HAVE_STDLIB_H+#endif++#ifndef HAVE_STRING_H+#define HAVE_STRING_H+#endif++#define SYCK_YAML_MAJOR 1+#define SYCK_YAML_MINOR 0++#define SYCK_VERSION "0.61"+#define YAML_DOMAIN "yaml.org,2002"++#ifdef HAVE_STDLIB_H+# include <stdlib.h>+#endif++#ifdef HAVE_STRING_H+# include <string.h>+#else+# include <strings.h>+#endif++#ifdef HAVE_INTRINSICS_H+# include <intrinsics.h>+#endif++#include <stddef.h>+#include <stdio.h>+#include <ctype.h>+#ifdef HAVE_ST_H+#include <st.h>+#else+#include "syck_st.h"+#endif++#if defined(__cplusplus)+extern "C" {+#endif++/*+ * Memory Allocation+ */+#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)+#include <alloca.h>+#endif++#if DEBUG+ void syck_assert( char *, unsigned );+# define ASSERT(f) \+ if ( f ) \+ {} \+ else \+ syck_assert( __FILE__, __LINE__ )+#else+# define ASSERT(f)+#endif++#ifndef NULL+# define NULL (void *)0+#endif++#define ALLOC_CT 8+#define SYCK_BUFFERSIZE 4096+#define S_ALLOC_N(type,n) (type*)malloc(sizeof(type)*(n))+#define S_ALLOC(type) (type*)malloc(sizeof(type))+#define S_REALLOC_N(var,type,n) (var)=(type*)realloc((char*)(var),sizeof(type)*(n))+#define S_FREE(n) free(n); n = NULL;++#define S_ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n))++#define S_MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n))+#define S_MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n))+#define S_MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))+#define S_MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n))++#define BLOCK_FOLD 10+#define BLOCK_LIT 20+#define BLOCK_PLAIN 30+#define NL_CHOMP 40+#define NL_KEEP 50++/*+ * Node definitions+ */+#ifndef ST_DATA_T_DEFINED+typedef long st_data_t;+#endif++#define SYMID unsigned long++typedef struct _syck_node SyckNode;++enum syck_kind_tag {+ syck_map_kind,+ syck_seq_kind,+ syck_str_kind+};++enum map_part {+ map_key,+ map_value+};++enum map_style {+ map_none,+ map_inline+};++enum seq_style {+ seq_none,+ seq_inline+};++enum scalar_style {+ scalar_none,+ scalar_1quote,+ scalar_2quote,+ scalar_fold,+ scalar_literal,+ scalar_plain+};++/*+ * Node metadata struct+ */+struct _syck_node {+ /* Symbol table ID */+ SYMID id;+ /* Underlying kind */+ enum syck_kind_tag kind;+ /* Fully qualified tag-uri for type */+ char *type_id;+ /* Anchor name */+ char *anchor;+ union {+ /* Storage for map data */+ struct SyckMap {+ enum map_style style;+ SYMID *keys;+ SYMID *values;+ long capa;+ long idx;+ } *pairs;+ /* Storage for sequence data */+ struct SyckSeq {+ enum seq_style style;+ SYMID *items;+ long capa;+ long idx;+ } *list;+ /* Storage for string data */+ struct SyckStr {+ enum scalar_style style;+ char *ptr;+ long len;+ } *str;+ } data;+ /* Shortcut node */+ void *shortcut;+};++/*+ * Parser definitions+ */+typedef struct _syck_parser SyckParser;+typedef struct _syck_file SyckIoFile;+typedef struct _syck_str SyckIoStr;+typedef struct _syck_level SyckLevel;++typedef SYMID (*SyckNodeHandler)(SyckParser *, SyckNode *);+typedef void (*SyckErrorHandler)(SyckParser *, char *);+typedef SyckNode * (*SyckBadAnchorHandler)(SyckParser *, char *);+typedef long (*SyckIoFileRead)(char *, SyckIoFile *, long, long); +typedef long (*SyckIoStrRead)(char *, SyckIoStr *, long, long);++enum syck_io_type {+ syck_io_str,+ syck_io_file+};++enum syck_parser_input {+ syck_yaml_utf8,+ syck_yaml_utf16,+ syck_yaml_utf32,+ syck_bytecode_utf8+};++enum syck_level_status {+ syck_lvl_header,+ syck_lvl_doc,+ syck_lvl_open,+ syck_lvl_seq,+ syck_lvl_map,+ syck_lvl_block,+ syck_lvl_str,+ syck_lvl_iseq,+ syck_lvl_imap,+ syck_lvl_end,+ syck_lvl_pause,+ syck_lvl_anctag,+ syck_lvl_mapx,+ syck_lvl_seqx+};++/*+ * Parser structs+ */+struct _syck_file {+ /* File pointer */+ FILE *ptr;+ /* Function which FILE -> buffer */+ SyckIoFileRead read;+};++struct _syck_str {+ /* String buffer pointers */+ char *beg, *ptr, *end;+ /* Function which string -> buffer */+ SyckIoStrRead read;+};++struct _syck_level {+ /* Indent */+ int spaces;+ /* Counts nodes emitted at this level, useful for parsing + * keys and pairs in bytecode */+ int ncount;+ /* Does node have anchors or tags? */+ int anctag;+ /* Domain prefixing at the given level */+ char *domain;+ /* Keeps a node status */+ enum syck_level_status status;+};++struct _syck_parser {+ /* Root node */+ SYMID root, root_on_error;+ /* Implicit typing flag */+ int implicit_typing, taguri_expansion;+ /* Scripting language function to handle nodes */+ SyckNodeHandler handler;+ /* Error handler */+ SyckErrorHandler error_handler;+ /* InvalidAnchor handler */+ SyckBadAnchorHandler bad_anchor_handler;+ /* Parser input type */+ enum syck_parser_input input_type;+ /* IO type */+ enum syck_io_type io_type;+ /* Custom buffer size */+ size_t bufsize;+ /* Buffer pointers */+ char *buffer, *linectptr, *lineptr, *toktmp, *token, *cursor, *marker, *limit;+ /* Line counter */+ int linect;+ /* Last token from yylex() */+ int last_token;+ /* Force a token upon next call to yylex() */+ int force_token;+ /* EOF flag */+ int eof;+ union {+ SyckIoFile *file;+ SyckIoStr *str;+ } io;+ /* Symbol table for anchors */+ st_table *anchors, *bad_anchors;+ /* Optional symbol table for SYMIDs */+ st_table *syms;+ /* Levels of indentation */+ SyckLevel *levels;+ int lvl_idx;+ int lvl_capa;+ /* Pointer for extension's use */+ void *bonus;+};++/*+ * Emitter definitions+ */+typedef struct _syck_emitter SyckEmitter;+typedef struct _syck_emitter_node SyckEmitterNode;++typedef void (*SyckOutputHandler)(SyckEmitter *, char *, long); +typedef void (*SyckEmitterHandler)(SyckEmitter *, st_data_t); ++enum doc_stage {+ doc_open,+ doc_processing+};++/*+ * Emitter struct+ */+struct _syck_emitter {+ /* Headerless doc flag */+ int headless;+ /* Force header? */+ int use_header;+ /* Force version? */+ int use_version;+ /* Sort hash keys */+ int sort_keys;+ /* Anchor format */+ char *anchor_format;+ /* Explicit typing on all collections? */+ int explicit_typing;+ /* Best width on folded scalars */+ int best_width;+ /* Use literal[1] or folded[2] blocks on all text? */+ enum scalar_style style;+ /* Stage of written document */+ enum doc_stage stage;+ /* Level counter */+ int level;+ /* Default indentation */+ int indent;+ /* Object ignore ID */+ SYMID ignore_id;+ /* Symbol table for anchors */+ st_table *markers, *anchors, *anchored;+ /* Custom buffer size */+ size_t bufsize;+ /* Buffer */+ char *buffer, *marker;+ /* Absolute position of the buffer */+ long bufpos;+ /* Handler for emitter nodes */+ SyckEmitterHandler emitter_handler;+ /* Handler for output */+ SyckOutputHandler output_handler;+ /* Levels of indentation */+ SyckLevel *levels;+ int lvl_idx;+ int lvl_capa;+ /* Pointer for extension's use */+ void *bonus;+};++/*+ * Emitter node metadata struct+ */+struct _syck_emitter_node {+ /* Node buffer position */+ long pos;+ /* Current indent */+ long indent;+ /* Collection? */+ int is_shortcut;+};++/*+ * Handler prototypes+ */+SYMID syck_hdlr_add_node( SyckParser *, SyckNode * );+SyckNode *syck_hdlr_add_anchor( SyckParser *, char *, SyckNode * );+void syck_hdlr_remove_anchor( SyckParser *, char * );+SyckNode *syck_hdlr_get_anchor( SyckParser *, char * );+void syck_add_transfer( char *, SyckNode *, int );+char *syck_xprivate( char *, int );+char *syck_taguri( char *, char *, int );+int syck_tagcmp( char *, char * );+int syck_add_sym( SyckParser *, char * );+int syck_lookup_sym( SyckParser *, SYMID, char ** );+int syck_try_implicit( SyckNode * );+char *syck_type_id_to_uri( char * );+void try_tag_implicit( SyckNode *, int );+char *syck_match_implicit( char *, size_t );++/*+ * API prototypes+ */+char *syck_strndup( char *, long );+long syck_io_file_read( char *, SyckIoFile *, long, long );+long syck_io_str_read( char *, SyckIoStr *, long, long );+char *syck_base64enc( char *, long );+char *syck_base64dec( char *, long, long * );+SyckEmitter *syck_new_emitter();+SYMID syck_emitter_mark_node( SyckEmitter *, st_data_t );+void syck_emitter_ignore_id( SyckEmitter *, SYMID );+void syck_output_handler( SyckEmitter *, SyckOutputHandler );+void syck_emitter_handler( SyckEmitter *, SyckEmitterHandler );+void syck_free_emitter( SyckEmitter * );+void syck_emitter_clear( SyckEmitter * );+void syck_emitter_write( SyckEmitter *, char *, long );+void syck_emitter_escape( SyckEmitter *, char *, long );+void syck_emitter_flush( SyckEmitter *, long );+void syck_emit( SyckEmitter *, st_data_t );+void syck_emit_scalar( SyckEmitter *, char *, enum scalar_style, int, int, char, char *, long );+void syck_emit_1quoted( SyckEmitter *, int, char *, long );+void syck_emit_2quoted( SyckEmitter *, int, char *, long );+void syck_emit_folded( SyckEmitter *, int, char, char *, long );+void syck_emit_literal( SyckEmitter *, char, char *, long );+void syck_emit_seq( SyckEmitter *, char *, enum seq_style );+void syck_emit_item( SyckEmitter *, st_data_t );+void syck_emit_map( SyckEmitter *, char *, enum map_style );+void syck_emit_end( SyckEmitter * );+void syck_emit_tag( SyckEmitter *, char *, char * );+void syck_emit_indent( SyckEmitter * );+SyckLevel *syck_emitter_current_level( SyckEmitter * );+SyckLevel *syck_emitter_parent_level( SyckEmitter * );+void syck_emitter_pop_level( SyckEmitter * );+void syck_emitter_add_level( SyckEmitter *, int, enum syck_level_status );+void syck_emitter_reset_levels( SyckEmitter * );+SyckParser *syck_new_parser();+void syck_free_parser( SyckParser * );+void syck_parser_set_root_on_error( SyckParser *, SYMID );+void syck_parser_implicit_typing( SyckParser *, int );+void syck_parser_taguri_expansion( SyckParser *, int );+int syck_scan_scalar( int, char *, long );+void syck_parser_handler( SyckParser *, SyckNodeHandler );+void syck_parser_error_handler( SyckParser *, SyckErrorHandler );+void syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler );+void syck_parser_file( SyckParser *, FILE *, SyckIoFileRead );+void syck_parser_str( SyckParser *, char *, long, SyckIoStrRead );+void syck_parser_str_auto( SyckParser *, char *, SyckIoStrRead );+SyckLevel *syck_parser_current_level( SyckParser * );+void syck_parser_add_level( SyckParser *, int, enum syck_level_status );+void syck_parser_pop_level( SyckParser * );+void free_any_io( SyckParser * );+long syck_parser_read( SyckParser * );+long syck_parser_readlen( SyckParser *, long );+SYMID syck_parse( SyckParser * );+void syck_default_error_handler( SyckParser *, char * );+SYMID syck_yaml2byte_handler( SyckParser *, SyckNode * );+char *syck_yaml2byte( char * );++/*+ * Allocation prototypes+ */+SyckNode *syck_alloc_map();+SyckNode *syck_alloc_seq();+SyckNode *syck_alloc_str();+void syck_free_node( SyckNode * );+void syck_free_members( SyckNode * );+SyckNode *syck_new_str( char *, enum scalar_style );+SyckNode *syck_new_str2( char *, long, enum scalar_style );+void syck_replace_str( SyckNode *, char *, enum scalar_style );+void syck_replace_str2( SyckNode *, char *, long, enum scalar_style );+void syck_str_blow_away_commas( SyckNode * );+char *syck_str_read( SyckNode * );+SyckNode *syck_new_map( SYMID, SYMID );+void syck_map_empty( SyckNode * );+void syck_map_add( SyckNode *, SYMID, SYMID );+SYMID syck_map_read( SyckNode *, enum map_part, long );+void syck_map_assign( SyckNode *, enum map_part, long, SYMID );+long syck_map_count( SyckNode * );+void syck_map_update( SyckNode *, SyckNode * );+SyckNode *syck_new_seq( SYMID );+void syck_seq_empty( SyckNode * );+void syck_seq_add( SyckNode *, SYMID );+void syck_seq_assign( SyckNode *, long, SYMID );+SYMID syck_seq_read( SyckNode *, long );+long syck_seq_count( SyckNode * );++/*+ * Lexer prototypes+ */+void syckerror( char * );+int syckparse( void * );++#if defined(__cplusplus)+} /* extern "C" { */+#endif++#endif /* ifndef SYCK_H */
+ syck/syck_st.h view
@@ -0,0 +1,46 @@+/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */++/* @(#) st.h 5.1 89/12/14 */++#ifndef ST_INCLUDED++#define ST_INCLUDED++typedef struct st_table st_table;++struct st_hash_type {+ int (*compare)();+ int (*hash)();+};++struct st_table {+ struct st_hash_type *type;+ int num_bins;+ int num_entries;+ struct st_table_entry **bins;+};++#define st_is_member(table,key) st_lookup(table,key,(char **)0)++enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE};++st_table *st_init_table();+st_table *st_init_table_with_size();+st_table *st_init_numtable();+st_table *st_init_numtable_with_size();+st_table *st_init_strtable();+st_table *st_init_strtable_with_size();+int st_delete(), st_delete_safe();+int st_insert(), st_lookup();+void st_foreach(), st_add_direct(), st_free_table(), st_cleanup_safe();+st_table *st_copy();++#define ST_NUMCMP ((int (*)()) 0)+#define ST_NUMHASH ((int (*)()) -2)++#define st_numcmp ST_NUMCMP+#define st_numhash ST_NUMHASH++int st_strhash();++#endif /* ST_INCLUDED */
+ syck/yamlbyte.h view
@@ -0,0 +1,170 @@+/* yamlbyte.h+ *+ * The YAML bytecode "C" interface header file. See the YAML bytecode+ * reference for bytecode sequence rules and for the meaning of each+ * bytecode.+ */++#ifndef YAMLBYTE_H+#define YAMLBYTE_H+#include <stddef.h>++/* define what a character is */+typedef unsigned char yamlbyte_utf8_t;+typedef unsigned short yamlbyte_utf16_t;+#ifdef YAMLBYTE_UTF8+ #ifdef YAMLBYTE_UTF16+ #error Must only define YAMLBYTE_UTF8 or YAMLBYTE_UTF16+ #endif+ typedef yamlbyte_utf8_t yamlbyte_char_t;+#else+ #ifdef YAMLBYTE_UTF16+ typedef yamlbyte_utf16_t yamlbyte_char_t;+ #else+ #error Must define YAMLBYTE_UTF8 or YAMLBYTE_UTF16+ #endif+#endif++/* specify list of bytecodes */+#define YAMLBYTE_FINISH ((yamlbyte_char_t) 0)+#define YAMLBYTE_DOCUMENT ((yamlbyte_char_t)'D')+#define YAMLBYTE_DIRECTIVE ((yamlbyte_char_t)'V')+#define YAMLBYTE_PAUSE ((yamlbyte_char_t)'P')+#define YAMLBYTE_MAPPING ((yamlbyte_char_t)'M')+#define YAMLBYTE_SEQUENCE ((yamlbyte_char_t)'Q')+#define YAMLBYTE_END_BRANCH ((yamlbyte_char_t)'E')+#define YAMLBYTE_SCALAR ((yamlbyte_char_t)'S')+#define YAMLBYTE_CONTINUE ((yamlbyte_char_t)'C')+#define YAMLBYTE_NEWLINE ((yamlbyte_char_t)'N')+#define YAMLBYTE_NULLCHAR ((yamlbyte_char_t)'Z')+#define YAMLBYTE_ANCHOR ((yamlbyte_char_t)'A')+#define YAMLBYTE_ALIAS ((yamlbyte_char_t)'R')+#define YAMLBYTE_TRANSFER ((yamlbyte_char_t)'T')+/* formatting bytecodes */+#define YAMLBYTE_COMMENT ((yamlbyte_char_t)'c')+#define YAMLBYTE_INDENT ((yamlbyte_char_t)'i')+#define YAMLBYTE_STYLE ((yamlbyte_char_t)'s')+/* other bytecodes */+#define YAMLBYTE_LINE_NUMBER ((yamlbyte_char_t)'#')+#define YAMLBYTE_WHOLE_SCALAR ((yamlbyte_char_t)'<')+#define YAMLBYTE_NOTICE ((yamlbyte_char_t)'!')+#define YAMLBYTE_SPAN ((yamlbyte_char_t)')')+#define YAMLBYTE_ALLOC ((yamlbyte_char_t)'@')++/* second level style bytecodes, ie "s>" */+#define YAMLBYTE_FLOW ((yamlbyte_char_t)'>')+#define YAMLBYTE_LITERAL ((yamlbyte_char_t)'|')+#define YAMLBYTE_BLOCK ((yamlbyte_char_t)'b')+#define YAMLBYTE_PLAIN ((yamlbyte_char_t)'p')+#define YAMLBYTE_INLINE_MAPPING ((yamlbyte_char_t)'{')+#define YAMLBYTE_INLINE_SEQUENCE ((yamlbyte_char_t)'[')+#define YAMLBYTE_SINGLE_QUOTED ((yamlbyte_char_t)39)+#define YAMLBYTE_DOUBLE_QUOTED ((yamlbyte_char_t)'"')++/*+ * The "C" API has two variants, one based on instructions,+ * with events delivered via pointers; and the other one+ * is character based where one or more instructions are+ * serialized into a buffer.+ *+ * Note: In the instruction based API, WHOLE_SCALAR does+ * not have the '<here' marshalling stuff.+ */++typedef void * yamlbyte_consumer_t;+typedef void * yamlbyte_producer_t;++/* push and pull APIs need a way to communicate results */+typedef enum {+ YAMLBYTE_OK = 0, /* proceed */+ YAMLBYTE_E_MEMORY = 'M', /* could not allocate memory */+ YAMLBYTE_E_READ = 'R', /* input stream read error */+ YAMLBYTE_E_WRITE = 'W', /* output stream write error */+ YAMLBYTE_E_OTHER = '?', /* some other error condition */+ YAMLBYTE_E_PARSE = 'P', /* parse error, check bytecodes */+} yamlbyte_result_t;+ +typedef const yamlbyte_char_t *yamlbyte_buff_t; ++/* + * The "Instruction" API + */++typedef struct yaml_instruction {+ yamlbyte_char_t bytecode;+ yamlbyte_buff_t start;+ yamlbyte_buff_t finish; /* open range, *finish is _not_ part */+} *yamlbyte_inst_t;++/* producer pushes the instruction with one bytecode event to the + * consumer; if the consumer's result is not YAMLBYTE_OK, then+ * the producer should stop */+typedef+ yamlbyte_result_t+ (*yamlbyte_push_t)(+ yamlbyte_consumer_t self,+ yamlbyte_inst_t inst+ );++/* consumer pulls a bytecode instruction from the producer; in this+ * case the instruction (and is buffer) are owned by the producer and+ * will remain valid till the pull function is called once again;+ * if the instruction is NULL, then there are no more results; and+ * it is important to call the pull function till it returns NULL so + * that the producer can clean up its memory allocations */+typedef + yamlbyte_result_t+ (*yamlbyte_pull_t)(+ yamlbyte_producer_t self,+ yamlbyte_inst_t *inst /* to be filled in by the producer */+ ); ++/*+ * Buffer based API+ */++/* producer pushes a null terminated buffer filled with one or more+ * bytecode events to the consumer; if the consumer's result is not+ * YAMLBYTE_OK, then the producer should stop */+typedef+ yamlbyte_result_t+ (*yamlbyte_pushbuff_t)(+ yamlbyte_consumer_t self,+ yamlbyte_buff_t buff+ );++/* consumer pulls bytecode events from the producer; in this case+ * the buffer is owned by the producer, and will remain valid till+ * the pull function is called once again; if the buffer pointer+ * is set to NULL, then there are no more results; it is important+ * to call the pull function till it returns NULL so that the+ * producer can clean up its memory allocations */+typedef + yamlbyte_result_t+ (*yamlbyte_pullbuff_t)(+ yamlbyte_producer_t self,+ yamlbyte_buff_t *buff /* to be filled in by the producer */+ ); ++/* convert a pull interface to a push interface; the reverse process+ * requires threads and thus is language dependent */+#define YAMLBYTE_PULL2PUSH(pull,producer,push,consumer,result) \+ do { \+ yamlbyte_pullbuff_t _pull = (pull); \+ yamlbyte_pushbuff_t _push = (push); \+ yamlbyte_result_t _result = YAMLBYTE_OK; \+ yamlbyte_producer_t _producer = (producer); \+ yamlbyte_consumer_t _consumer = (consumer); \+ while(1) { \+ yamlbyte_buff_t buff = NULL; \+ _result = _pull(_producer,&buff); \+ if(YAMLBYTE_OK != result || NULL == buff) \+ break; \+ _result = _push(_consumer,buff); \+ if(YAMLBYTE_OK != result) \+ break; \+ } \+ (result) = _result; \+ } while(0)++#endif