mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/syck/yamlbyte.h: Ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4800 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
71a8bebf5a
commit
9e2f9cf233
2 changed files with 172 additions and 0 deletions
|
@ -6,6 +6,8 @@ Sat Oct 18 05:48:59 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net>
|
|||
|
||||
* ext/syck/yaml2byte.c: YAML to bytecode converter.
|
||||
|
||||
* ext/syck/yamlbyte.h: Ditto.
|
||||
|
||||
* ext/syck/bytecode.c: Bytecode parser fixes to empty collections
|
||||
and empty strings.
|
||||
|
||||
|
|
170
ext/syck/yamlbyte.h
Normal file
170
ext/syck/yamlbyte.h
Normal file
|
@ -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
|
Loading…
Reference in a new issue