/* * This source file is part of the bbcode library. * Written and maintained by Xavier De Cock 2006-2007 * Licensed under the BSD License Terms * Refer to the accompanying documentation for details on usage and license. * See also: Company Website: http://www.bmco.be/ * See also: Hosted on pecl: http://pecl.php.net/ * Leave this header As Is, add your name as maintainer, and please, contribute * enhancement back to the community * Revision : $Id: bbcode2.h,v 1.13 2007/10/25 11:42:43 void Exp $ */ #ifndef BBCODE_H_ #define BBCODE_H_ #include "bstrlib.h" #define BBCODE_LIB_VERSION "2.0" #define BBCODE_BUFFER 4 #define BBCODE_TYPE_NOARG 1 #define BBCODE_TYPE_SINGLE 2 #define BBCODE_TYPE_ARG 3 #define BBCODE_TYPE_OPTARG 4 #define BBCODE_TYPE_ROOT 5 #define BBCODE_FLAGS_ARG_PARSING 0x1 #define BBCODE_FLAGS_CDATA_NOT_ALLOWED 0x2 #define BBCODE_FLAGS_SMILEYS_ON 0x4 #define BBCODE_FLAGS_SMILEYS_OFF 0x8 #define BBCODE_FLAGS_ONE_OPEN_PER_LEVEL 0x10 #define BBCODE_FLAGS_REMOVE_IF_EMPTY 0x20 #define BBCODE_FLAGS_DENY_REOPEN_CHILD 0x40 #define BBCODE_ARG_DOUBLE_QUOTE 0x1 #define BBCODE_ARG_SINGLE_QUOTE 0x2 #define BBCODE_ARG_HTML_QUOTE 0x4 #define BBCODE_AUTO_CORRECT 0x100 #define BBCODE_CORRECT_REOPEN_TAGS 0x200 #define BBCODE_DEFAULT_SMILEYS_ON 0x400 #define BBCODE_DEFAULT_SMILEYS_OFF 0x800 #define BBCODE_FORCE_SMILEYS_OFF 0x1000 #define BBCODE_DISABLE_TREE_BUILD 0x2000 #define BBCODE_SMILEYS_CASE_INSENSITIVE 0x4000 #define BBCODE_CACHE_ACCEPT_ARG 0x01 #define BBCODE_CACHE_ACCEPT_NOARG 0x02 #define BBCODE_CACHE_START_HAS_BRACKET_OPEN 0x04 #define BBCODE_CACHE_END_HAS_BRACKET_OPEN 0x08 #define BBCODE_CACHE_ACCEPT_SMILEYS 0x10 #define BBCODE_ALLOW_LIST_TYPE_ALL 0 #define BBCODE_ALLOW_LIST_TYPE_NONE 1 #define BBCODE_ALLOW_LIST_TYPE_LISTED 2 #define BBCODE_ALLOW_LIST_TYPE_EXCLUDE 3 #define BBCODE_TREE_CHILD_TYPE_TREE 0 #define BBCODE_TREE_CHILD_TYPE_STRING 1 #define BBCODE_LIST_IS_READY 1 #define BBCODE_LIST_HAS_ROOT 2 #define BBCODE_TREE_FLAGS_PAIRED 0x1 #define BBCODE_TREE_FLAGS_MULTIPART 0x2 #define BBCODE_TREE_FLAGS_MULTIPART_FIRST_NODE 0x4 #define BBCODE_TREE_FLAGS_MULTIPART_LAST_NODE 0x8 #define BBCODE_TREE_FLAGS_MULTIPART_DONE 0x10 #define BBCODE_TREE_FLAGS_ROOT 0x20 #define BBCODE_TREE_ROOT_TAGID -1 #define BBCODE_ERR -2 #define bbcode_get_bbcode(parser, pos) ((pos == BBCODE_TREE_ROOT_TAGID)?(parser)->bbcodes->root : (parser)->bbcodes->bbcodes->element[(pos)]) #define bbcode_get_cn(parser) ((parser)->current_node) #define bbcode_array_length(array) (((array) == (void *)0 || (array)->size < 0) ? (int)0 : ((int)(array)->size)) #define bbcode_array_element(array, pos) ((((unsigned)(pos)) < (unsigned)bbcode_array_length(array)) ? ((array)->element[(pos)]) : NULL) #define bbcode_find_next(to_update,string,offset,char) if (to_update <= offset){ if (0>(to_update = bstrchrp( string, char, offset))){ to_update = blength( string )+5; } } #define BBCODE_SPECIAL_CASE_NO_CHILD(argument) \ bstring close_tag=bfromcstr("[/"); \ bconcat(close_tag,tag); \ bcatcstr(close_tag,"]"); \ int sc_offset=binstrcaseless(string, next_close, close_tag); \ if (sc_offset!=BSTR_ERR){ \ bbcode_tree_push_tree_child(parser, bbcode_get_cn(parser), work_stack, close_stack, bmidstr(string, offset, end-offset+1),tag_id, argument, offset); \ bbcode_tree_push_string_child(bbcode_get_cn(parser), bmidstr(string,next_close+1,sc_offset-next_close-1), offset+next_close+1); \ bbcode_close_tag(parser, bbcode_get_cn(parser), work_stack, close_stack, tag_id, bmidstr(string, sc_offset, blength(close_tag)),1, sc_offset); \ added=1; \ end=next_close=sc_offset+blength(close_tag)-1; \ } \ bdestroy(close_tag); #define bbcode_apply_flag_to_parts(multipart, flag, add) { \ int i; \ if (multipart!=NULL) { \ if (add) { \ for (i=0; isize; i++) { \ multipart->element[i]->flags |= flag; \ } \ } else { \ for (i=0; isize; i++) { \ multipart->element[i]->flags &= ~flag; \ } \ } \ } \ } typedef struct _bbcode_smiley bbcode_smiley; typedef struct _bbcode_smiley * bbcode_smiley_p; typedef struct _bbcode_smiley_array bbcode_smiley_list; typedef struct _bbcode_smiley_array * bbcode_smiley_list_p; typedef struct _bbcode_allow_list bbcode_allow_list; typedef struct _bbcode_allow_list * bbcode_allow_list_p; typedef struct _bbcode bbcode; typedef struct _bbcode * bbcode_p; typedef struct _bbcode ** bbcode_pp; typedef struct _bbcode_search bbcode_search; typedef struct _bbcode_search * bbcode_search_p; typedef struct _bbcode_search ** bbcode_search_pp; typedef struct _bbcode_array bbcode_array; typedef struct _bbcode_array * bbcode_array_p; typedef struct _bbcode_list bbcode_list; typedef struct _bbcode_list * bbcode_list_p; typedef struct _bbcode_parser bbcode_parser; typedef struct _bbcode_parser * bbcode_parser_p; typedef struct _bbcode_parse_tree bbcode_parse_tree; typedef struct _bbcode_parse_tree * bbcode_parse_tree_p; typedef struct _bbcode_parse_tree ** bbcode_parse_tree_pp; typedef struct _bbcode_parse_tree_array bbcode_parse_tree_array; typedef struct _bbcode_parse_tree_array* bbcode_parse_tree_array_p; typedef struct _bbcode_parse_tree_child bbcode_parse_tree_child; typedef struct _bbcode_parse_tree_child * bbcode_parse_tree_child_p; typedef struct _bbcode_parse_tree_child ** bbcode_parse_tree_child_pp; typedef struct _bbcode_parse_tree_child_array bbcode_parse_tree_child_array; typedef struct _bbcode_tag_id_search bbcode_tag_id_search; typedef struct _bbcode_tag_id_search * bbcode_tag_id_search_p; typedef struct _bbcode_validation bbcode_validation; typedef struct _bbcode_validation * bbcode_validation_p; typedef struct _bbcode_validation_array bbcode_validation_array; typedef struct _bbcode_validation_array * bbcode_validation_array_p; /* This represent a smiley list */ struct _bbcode_smiley_array { int size; int msize; bbcode_smiley_p smileys; char ci; }; /* Represents a set of bbcode rules */ struct _bbcode_array { int size; int msize; bbcode_pp element; }; /* Represent an array of parse tree */ struct _bbcode_parse_tree_array { int size; int msize; bbcode_parse_tree_pp element; }; /* Represents an array of parse_tree_child */ struct _bbcode_parse_tree_child_array { int size; int msize; bbcode_parse_tree_child_pp element; }; /* This represent a single smiley with search / replace */ struct _bbcode_smiley { bstring search; bstring replace; }; /* This represent a list of allowed tags */ struct _bbcode_allow_list { int *id_list; char type; int size; int msize; }; /* This represent a BBCode Tag Rule Set */ struct _bbcode { char type; int flags; char speed_cache; bstring tag; bstring open_tag; bstring close_tag; bstring default_arg; bstring parent_list; bstring child_list; bbcode_allow_list_p parents; bbcode_allow_list_p childs; void *param_handling_func_data; void *content_handling_func_data; int (*param_handling_func)(bstring content, bstring param, void *func_data); int (*content_handling_func)(bstring content, bstring param, void *func_data); }; /* This represent a complete BBCode Parsing Rule Set */ struct _bbcode_list { int options; int bbcode_max_size; bbcode_array_p bbcodes; bbcode_p root; bbcode_search_pp search_cache; int *num_cache; }; /* This is the bbcode parser */ struct _bbcode_parser { bbcode_parser_p argument_parser; bbcode_smiley_list_p smileys; bbcode_list_p bbcodes; bbcode_parse_tree_p current_node; bstring content_replace; bstring arg_replace; int options; }; /* This is the parse tree temporary data store */ struct _bbcode_parse_tree { int tag_id; int flags; bbcode_parse_tree_child_array childs; bbcode_parse_tree_array_p multiparts; bbcode_parse_tree_array_p conditions; bbcode_parse_tree_p parent_node; bstring open_string; bstring close_string; bstring argument; }; /* This is a single token found by parsing (in fact a token is often splitted with partial matches) */ struct _bbcode_parse_tree_child { union { bbcode_parse_tree_p tree; bstring string; }; int offset; char type; }; /* The tagId search cache */ struct _bbcode_search { bstring tag_name; int tag_id; }; /* BBCode Validation error entries */ struct _bbcode_validation { char error_type; int tag_id_1; int tag_id_2; int offset_1; int offset_2; }; /* BBCode Validation array entries */ struct _bbcode_validation_entry { int msize; int size; bbcode_validation_p element; }; /*--------------------------- Public API ---------------------------*/ /* Create and init a parser */ bbcode_parser_p bbcode_parser_create(); /* Destroy a parser and associated ressources */ void bbcode_parser_free(bbcode_parser_p parser); /* Destroy a parser and associated ressources */ void bbcode_parser_set_arg_parser(bbcode_parser_p parser, bbcode_parser_p arg_parser); /* Constructs and add a bbcode_element to the parser */ void bbcode_parser_add_ruleset(bbcode_parser_p parser, char type, int flags, char *tag, int tag_size, char *open_tag, int open_tag_size, char *close_tag, int close_tag_size, char *default_arg, int default_arg_size, char *parent_list, int parent_list_size, char *child_list, int child_list_size, int (*param_handling_func)(bstring content, bstring param, void *func_data), int (*content_handling_func)(bstring content, bstring param, void *func_data), void *param_handling_func_data, void *content_handling_func_data); /* Construct and add a smiley to the parser */ void bbcode_parser_add_smiley(bbcode_parser_p parser, char *smiley_search, int smiley_search_size, char *smiley_replace, int smiley_replace_size); /* Parse a BBCoded string to is treated equivalent */ char *bbcode_parse(bbcode_parser_p parser, unsigned char *string, unsigned int string_size, int *result_size); /* Get current options of the bbcode_parser */ int bbcode_parser_get_flags(bbcode_parser_p parser); /* Set options for the bbcode_parser */ void bbcode_parser_set_flags(bbcode_parser_p parser, int flags); /*--------------------------- Internal API ---------------------------*/ /* Parse nesting rules and optimize datas */ void bbcode_prepare_tag_list(bbcode_parser_p parser); /* This reparse nesting rules and optimize datas */ void bbcode_build_tree(bbcode_parser_p parser, bstring string, bbcode_parse_tree_p tree); /* This closes an active tag */ void bbcode_close_tag(bbcode_parser_p parser, bbcode_parse_tree_p tree, bbcode_parse_tree_array_p work, bbcode_parse_tree_array_p close, int tag_id, bstring close_string, int true_close, int offset); /* This make some basic corrections to a given tree */ int bbcode_correct_tree(bbcode_parser_p parser, bbcode_parse_tree_p tree, int parent_id, char force_false); /* This apply the BBCode rules to generate the final string */ void bbcode_apply_rules(bbcode_parser_p parser, bbcode_parse_tree_p tree, bstring parsed); /* Search a tag_id from the string */ int bbcode_get_tag_id(bbcode_parser_p parser, bstring value, int has_arg); /* Translate Smileys */ void bbcode_parse_smileys(bstring string, bbcode_smiley_list_p list); /*--------------------------- Smiley Manipulation API ---------------------------*/ /* Initialize a smiley list */ bbcode_smiley_list_p bbcode_smileys_list_create(); /* Free a smiley list */ void bbcode_smileys_list_free(bbcode_smiley_list_p list); /* Check if we can add an entry */ void bbcode_smiley_list_check_size(bbcode_smiley_list_p list, int size); /* adds a smiley to the list */ void bbcode_smileys_add(bbcode_smiley_list_p list, bstring search, bstring replacement); /*--------------------------- BBCode List Manipulation API ---------------------------*/ /* creates a BBcode list and init it */ bbcode_list_p bbcode_list_create(); /* free ressources for a BBCode list */ void bbcode_list_free(bbcode_list_p list); /* Check if there is room for a bbcode entry */ void bbcode_list_check_size(bbcode_list_p list, int size); /* Insert the special entry "Root" */ void bbcode_list_set_root(bbcode_list_p list, bbcode_p root); /* add a bbcode to a list */ void bbcode_list_add(bbcode_list_p list, bbcode_p to_add); /*--------------------------- BBCode Array Manipulation API ---------------------------*/ /* creates a BBcode array and init it */ bbcode_array_p bbcode_array_create(); /* Free a BBCode array */ void bbcode_array_free(bbcode_array_p array); /* Check if we can add an entry */ void bbcode_array_check_size(bbcode_array_p array, int size); /* adds a bbcode_rule to the list */ void bbcode_array_add(bbcode_array_p array, bbcode_p bbcode); /*--------------------------- BBCode Entry Manipulation API ---------------------------*/ /* Malloc a bbcode entry and init it */ bbcode_p bbcode_entry_create(); /* Free a bbcode entry ressources */ void bbcode_entry_free(bbcode_p entry); /*--------------------------- BBCode Allow Manipulation API ---------------------------*/ /* Malloc a bbcode_allow_list and init it */ bbcode_allow_list_p bbcode_allow_list_create(); /* Free the ressources taken by an allow list */ void bbcode_allow_list_free(bbcode_allow_list_p list); /* Check for the size of an allow list */ void bbcode_allow_list_check_size(bbcode_allow_list_p list, int size); /* Add an element to the list */ void bbcode_allow_list_add(bbcode_allow_list_p list, int element); /* Check if a given id is autorized */ int bbcode_allow_list_check_access(bbcode_allow_list_p list, int tag_id); /* Check if a list does accept any child */ int bbcode_allow_list_no_child(bbcode_allow_list_p list); /*--------------------------- Tree Manipulation API ---------------------------*/ /* Malloc and init a bbcode tree */ bbcode_parse_tree_p bbcode_tree_create(); /* Free the ressources taken by a tree */ void bbcode_tree_free(bbcode_parse_tree_p tree); /* Check if there is sufficient space in child array */ void bbcode_tree_check_child_size(bbcode_parse_tree_p tree, int size); /* adds a child to the current list (sub_tree) */ void bbcode_tree_push_tree_child(bbcode_parser_p parser, bbcode_parse_tree_p tree, bbcode_parse_tree_array_p work, bbcode_parse_tree_array_p close, bstring open_string, int tag_id, bstring argument, int offset); /* adds a child to the current list (string_leaf) */ void bbcode_tree_push_string_child(bbcode_parse_tree_p tree, bstring string, int offset); /* adds a tree to the current list (raw) */ void bbcode_tree_push_tree_raw(bbcode_parser_p parser, bbcode_parse_tree_p tree, bbcode_parse_tree_p tmp_tree, bbcode_parse_tree_array_p work); /* Get the last child and removes it from the list */ void bbcode_tree_pop_child(bbcode_parse_tree_p tree, bbcode_parse_tree_child_p bbcode_parse_tree_child); /* Insert a given child on a given position */ void bbcode_tree_insert_child_at(bbcode_parse_tree_p tree, bbcode_parse_tree_child_p bbcode_parse_tree_child, int pos); /* Mark an element closed, (and also multipart elements) */ void bbcode_tree_mark_element_closed(bbcode_parse_tree_p tree); /* Move a child set from a parent to another */ void bbcode_tree_move_childs(bbcode_parse_tree_p from, bbcode_parse_tree_p to, int offset_from, int count, int offset_to); /*--------------------------- Parse Stack Manipulation API ---------------------------*/ /* Create a Tree array */ bbcode_parse_tree_array_p bbcode_parse_stack_create(); /* Free ressource used by a Tree array */ void bbcode_parse_stack_free(bbcode_parse_tree_array_p stack); /* Check if there is room for adding elements */ void bbcode_parse_stack_check_size(bbcode_parse_tree_array_p stack, int size); /* Add element to the Tree array */ void bbcode_parse_stack_push_element(bbcode_parse_tree_array_p stack, bbcode_parse_tree_p element); /* Remove element from the Tree array without giving it back */ void bbcode_parse_stack_pop_element_loose(bbcode_parse_tree_array_p stack); /* Remove element from the Tree array @ index */ void bbcode_parse_drop_element_at(bbcode_parse_tree_array_p stack, int index); /* Init a tree child */ bbcode_parse_tree_child_p bbcode_tree_child_create(); /* Free a tree child */ void bbcode_tree_child_destroy(bbcode_parse_tree_child_p child); /*--------------------------- Built-in callbacks ---------------------------*/ #endif /*BBCODE_H_*/