extracting the concept a meta unit
parent
4a415a83ac
commit
6205e4f3de
|
@ -2454,6 +2454,7 @@ Coming Soon</i><div>
|
|||
<li><a href='#file_extension_str_doc'>file_extension</a></li>
|
||||
<li><a href='#remove_extension_str_doc'>remove_extension</a></li>
|
||||
<li><a href='#remove_last_folder_str_doc'>remove_last_folder</a></li>
|
||||
<li><a href='#string_set_match_table_str_doc'>string_set_match_table</a></li>
|
||||
<li><a href='#string_set_match_str_doc'>string_set_match</a></li>
|
||||
</ul>
|
||||
<h3>§4.3 String Function Descriptions</h3>
|
||||
|
@ -3471,7 +3472,30 @@ fstr_bool remove_last_folder(
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call attemps to delete a folder or filename off the end of a path string.
|
||||
This call returns non-zero on success.</div></div><hr>
|
||||
<div id='string_set_match_str_doc'><h4>§4.3.114: string_set_match</h4>
|
||||
<div id='string_set_match_table_str_doc'><h4>§4.3.114: string_set_match_table</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>
|
||||
fstr_bool string_set_match_table(
|
||||
<div style='margin-left: 4mm;'>void *str_set,<br>int32_t item_size,<br>int32_t count,<br>String str,<br>int32_t *match_index<br></div>)
|
||||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div>
|
||||
<div style='font-weight: 600;'>str_set</div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The str_set parameter is an array of String structs specifying matchable strings.</div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div style='font-weight: 600;'>count</div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The count parameter specifies the number of String structs in the str_set array.</div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div style='font-weight: 600;'>str</div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The str parameter specifies the string to match against the str_set.</div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div style='font-weight: 600;'>match_index</div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>If this call succeeds match_index is filled with the index into str_set where the match occurred.</div></div>
|
||||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call tries to see if str matches any of the strings in str_set. If there is a match the call
|
||||
succeeds and returns non-zero. The matching rule is equivalent to the matching rule for match.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#match_doc'>match</a></div></div><hr>
|
||||
<div id='string_set_match_str_doc'><h4>§4.3.115: string_set_match</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>
|
||||
fstr_bool string_set_match(
|
||||
<div style='margin-left: 4mm;'>String *str_set,<br>int32_t count,<br>String str,<br>int32_t *match_index<br></div>)
|
||||
|
|
|
@ -166,6 +166,7 @@ FSTRING_LINK fstr_bool set_last_folder_ss(String *dir, String folder_name
|
|||
FSTRING_LINK String file_extension(String str);
|
||||
FSTRING_LINK fstr_bool remove_extension(String *str);
|
||||
FSTRING_LINK fstr_bool remove_last_folder(String *str);
|
||||
FSTRING_LINK fstr_bool string_set_match_table(void *str_set, int32_t item_size, int32_t count, String str, int32_t *match_index);
|
||||
FSTRING_LINK fstr_bool string_set_match(String *str_set, int32_t count, String str, int32_t *match_index);
|
||||
|
||||
#if !defined(FSTRING_C)
|
||||
|
@ -241,6 +242,7 @@ FSTRING_INLINE int32_t str_to_int(String str);
|
|||
FSTRING_INLINE int32_t reverse_seek_slash(String str, int32_t pos);
|
||||
FSTRING_INLINE fstr_bool set_last_folder(String *dir, char *folder_name, char slash);
|
||||
FSTRING_INLINE fstr_bool set_last_folder(String *dir, String folder_name, char slash);
|
||||
FSTRING_INLINE fstr_bool string_set_match(void *str_set, int32_t item_size, int32_t count, String str, int32_t *match_index);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -384,6 +386,8 @@ FSTRING_INLINE fstr_bool
|
|||
set_last_folder(String *dir, char *folder_name, char slash){return(set_last_folder_sc(dir,folder_name,slash));}
|
||||
FSTRING_INLINE fstr_bool
|
||||
set_last_folder(String *dir, String folder_name, char slash){return(set_last_folder_ss(dir,folder_name,slash));}
|
||||
FSTRING_INLINE fstr_bool
|
||||
string_set_match(void *str_set, int32_t item_size, int32_t count, String str, int32_t *match_index){return(string_set_match_table(str_set,item_size,count,str,match_index));}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -2021,13 +2025,15 @@ remove_last_folder(String *str){
|
|||
#endif
|
||||
|
||||
// TODO(allen): Add hash-table extension to string sets.
|
||||
|
||||
#if defined(FSTRING_IMPLEMENTATION)
|
||||
FSTRING_LINK fstr_bool
|
||||
string_set_match(String *str_set, int32_t count, String str, int32_t *match_index){
|
||||
string_set_match_table(void *str_set, int32_t item_size, int32_t count, String str, int32_t *match_index){
|
||||
fstr_bool result = 0;
|
||||
int32_t i = 0;
|
||||
for (; i < count; ++i, ++str_set){
|
||||
if (match_ss(*str_set, str)){
|
||||
uint8_t *ptr = (uint8_t*)str_set;
|
||||
for (; i < count; ++i, ptr += item_size){
|
||||
if (match_ss(*(String*)ptr, str)){
|
||||
*match_index = i;
|
||||
result = 1;
|
||||
break;
|
||||
|
@ -2037,6 +2043,15 @@ string_set_match(String *str_set, int32_t count, String str, int32_t *match_inde
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(FSTRING_IMPLEMENTATION)
|
||||
FSTRING_LINK fstr_bool
|
||||
string_set_match(String *str_set, int32_t count, String str, int32_t *match_index){
|
||||
fstr_bool result = string_set_match_table(str_set, sizeof(String), count, str, match_index);
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef FSTRING_EXPERIMENTAL
|
||||
#define FSTRING_EXPERIMENTAL
|
||||
|
||||
|
|
487
4ed_metagen.cpp
487
4ed_metagen.cpp
|
@ -333,6 +333,14 @@ generate_style(){
|
|||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Parse_Context{
|
||||
Cpp_Token *token_s;
|
||||
Cpp_Token *token_e;
|
||||
Cpp_Token *token;
|
||||
char *data;
|
||||
} Parse_Context;
|
||||
|
||||
typedef struct Argument{
|
||||
String param_string;
|
||||
String param_name;
|
||||
|
@ -387,6 +395,7 @@ typedef struct Item_Node{
|
|||
|
||||
typedef struct Item_Set{
|
||||
Item_Node *items;
|
||||
int32_t count;
|
||||
} Item_Set;
|
||||
|
||||
typedef struct Parse{
|
||||
|
@ -394,8 +403,97 @@ typedef struct Parse{
|
|||
Cpp_Token_Stack tokens;
|
||||
} Parse;
|
||||
|
||||
typedef struct Meta_Unit{
|
||||
Item_Set set;
|
||||
|
||||
Parse *parse;
|
||||
int32_t count;
|
||||
} Meta_Unit;
|
||||
|
||||
typedef struct Meta_Keywords{
|
||||
String key;
|
||||
Item_Type type;
|
||||
} Meta_Keywords;
|
||||
|
||||
static Item_Node null_item_node = {0};
|
||||
|
||||
static String
|
||||
get_lexeme(Cpp_Token token, char *code){
|
||||
String str = make_string(code + token.start, token.size);
|
||||
return(str);
|
||||
}
|
||||
|
||||
static Parse_Context
|
||||
setup_parse_context(char *data, Cpp_Token_Stack stack){
|
||||
Parse_Context context;
|
||||
context.token_s = stack.tokens;
|
||||
context.token_e = stack.tokens + stack.count;
|
||||
context.token = context.token_s;
|
||||
context.data = data;
|
||||
return(context);
|
||||
}
|
||||
|
||||
static Parse_Context
|
||||
setup_parse_context(Parse parse){
|
||||
Parse_Context context;
|
||||
context.token_s = parse.tokens.tokens;
|
||||
context.token_e = parse.tokens.tokens + parse.tokens.count;
|
||||
context.token = context.token_s;
|
||||
context.data = parse.code.str;
|
||||
return(context);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
get_token(Parse_Context *context){
|
||||
Cpp_Token *result = context->token;
|
||||
if (result >= context->token_e){
|
||||
result = 0;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
get_next_token(Parse_Context *context){
|
||||
Cpp_Token *result = context->token+1;
|
||||
context->token = result;
|
||||
if (result >= context->token_e){
|
||||
result = 0;
|
||||
context->token = context->token_e;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
get_prev_token(Parse_Context *context){
|
||||
Cpp_Token *result = context->token-1;
|
||||
if (result < context->token_s){
|
||||
result = 0;
|
||||
}
|
||||
else{
|
||||
context->token = result;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
can_back_step(Parse_Context *context){
|
||||
Cpp_Token *result = context->token-1;
|
||||
if (result < context->token_s){
|
||||
result = 0;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
set_token(Parse_Context *context, Cpp_Token *token){
|
||||
Cpp_Token *result = 0;
|
||||
if (token >= context->token_s && token < context->token_e){
|
||||
context->token = token;
|
||||
result = token;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static String
|
||||
file_dump(char *filename){
|
||||
String result = {0};
|
||||
|
@ -419,7 +517,7 @@ file_dump(char *filename){
|
|||
}
|
||||
|
||||
static Parse
|
||||
meta_parse(char *filename){
|
||||
meta_lex(char *filename){
|
||||
Parse result = {0};
|
||||
result.code = file_dump(filename);
|
||||
result.tokens = cpp_make_token_stack(1024);
|
||||
|
@ -427,6 +525,52 @@ meta_parse(char *filename){
|
|||
return(result);
|
||||
}
|
||||
|
||||
static Meta_Unit
|
||||
compile_meta_unit(Partition *part, char **files, int32_t file_count,
|
||||
Meta_Keywords *keywords, int32_t key_count){
|
||||
Meta_Unit unit = {0};
|
||||
int32_t i = 0;
|
||||
|
||||
unit.count = file_count;
|
||||
unit.parse = push_array(part, Parse, file_count);
|
||||
|
||||
for (i = 0; i < file_count; ++i){
|
||||
unit.parse[i] = meta_lex(files[i]);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO(allen): This stage counts nested structs
|
||||
// and unions which is not correct. Luckily it only
|
||||
// means we over allocate by a few items, but fixing it
|
||||
// to be exactly correct would be nice.
|
||||
for (int32_t J = 0; J < unit.count; ++J){
|
||||
Cpp_Token *token = 0;
|
||||
Parse_Context context_ = setup_parse_context(unit.parse[J]);
|
||||
Parse_Context *context = &context_;
|
||||
|
||||
for (; (token = get_token(context)) != 0; get_next_token(context)){
|
||||
if (!(token->flags & CPP_TFLAG_PP_BODY) &&
|
||||
((token->flags & CPP_TFLAG_IS_KEYWORD) ||
|
||||
token->type == CPP_TOKEN_IDENTIFIER)){
|
||||
|
||||
String lexeme = get_lexeme(*token, context->data);
|
||||
int32_t match_index = 0;
|
||||
if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){
|
||||
switch (match_index){
|
||||
case 0: //typedef
|
||||
case 1: case 2: //struct/union
|
||||
case 3: //ENUM
|
||||
++unit.set.count; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return(unit);
|
||||
}
|
||||
|
||||
static String
|
||||
get_first_line(String source){
|
||||
String line = {0};
|
||||
|
@ -474,17 +618,17 @@ typedef enum Doc_Note_Type{
|
|||
} Doc_Note_Type;
|
||||
|
||||
static int32_t
|
||||
check_and_fix_docs(String *lexeme){
|
||||
check_and_fix_docs(String *doc_string){
|
||||
int32_t result = false;
|
||||
|
||||
if (lexeme->size > 4){
|
||||
if (lexeme->str[0] == '/'){
|
||||
if (lexeme->str[1] == '*'){
|
||||
if (lexeme->str[lexeme->size - 2] == '*'){
|
||||
if (lexeme->str[lexeme->size - 1] == '/'){
|
||||
if (doc_string->size > 4){
|
||||
if (doc_string->str[0] == '/'){
|
||||
if (doc_string->str[1] == '*'){
|
||||
if (doc_string->str[doc_string->size - 2] == '*'){
|
||||
if (doc_string->str[doc_string->size - 1] == '/'){
|
||||
result = true;
|
||||
lexeme->str += 2;
|
||||
lexeme->size -= 4;
|
||||
doc_string->str += 2;
|
||||
doc_string->size -= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -494,6 +638,23 @@ check_and_fix_docs(String *lexeme){
|
|||
return(result);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
get_doc_string_from_prev(Parse_Context *context, String *doc_string){
|
||||
int32_t result = false;
|
||||
|
||||
if (can_back_step(context)){
|
||||
Cpp_Token *prev_token = get_token(context) - 1;
|
||||
if (prev_token->type == CPP_TOKEN_COMMENT){
|
||||
*doc_string = get_lexeme(*prev_token, context->data);
|
||||
if (check_and_fix_docs(doc_string)){
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static String
|
||||
doc_note_string[] = {
|
||||
make_lit_string("DOC_PARAM"),
|
||||
|
@ -688,107 +849,17 @@ perform_doc_parse(Partition *part, String doc_string, Documentation *doc){
|
|||
}while(keep_parsing);
|
||||
}
|
||||
|
||||
static String
|
||||
get_lexeme(Cpp_Token token, char *code){
|
||||
String str = make_string(code + token.start, token.size);
|
||||
return(str);
|
||||
}
|
||||
|
||||
static Item_Set
|
||||
allocate_item_set(Partition *part, int32_t count){
|
||||
Item_Set item_set = {0};
|
||||
if (count > 0){
|
||||
item_set.items = push_array(part, Item_Node, count);
|
||||
item_set.count = count;
|
||||
memset(item_set.items, 0, sizeof(Item_Node)*count);
|
||||
}
|
||||
return(item_set);
|
||||
}
|
||||
|
||||
typedef struct Parse_Context{
|
||||
Cpp_Token *token_s;
|
||||
Cpp_Token *token_e;
|
||||
Cpp_Token *token;
|
||||
char *data;
|
||||
} Parse_Context;
|
||||
|
||||
static Parse_Context
|
||||
setup_parse_context(char *data, Cpp_Token_Stack stack){
|
||||
Parse_Context context;
|
||||
context.token_s = stack.tokens;
|
||||
context.token_e = stack.tokens + stack.count;
|
||||
context.token = context.token_s;
|
||||
context.data = data;
|
||||
return(context);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
get_token(Parse_Context *context){
|
||||
Cpp_Token *result = context->token;
|
||||
if (result >= context->token_e){
|
||||
result = 0;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
get_next_token(Parse_Context *context){
|
||||
Cpp_Token *result = context->token+1;
|
||||
context->token = result;
|
||||
if (result >= context->token_e){
|
||||
result = 0;
|
||||
context->token = context->token_e;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
get_prev_token(Parse_Context *context){
|
||||
Cpp_Token *result = context->token-1;
|
||||
if (result < context->token_s){
|
||||
result = 0;
|
||||
}
|
||||
else{
|
||||
context->token = result;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
can_back_step(Parse_Context *context){
|
||||
Cpp_Token *result = context->token-1;
|
||||
if (result < context->token_s){
|
||||
result = 0;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Cpp_Token*
|
||||
set_token(Parse_Context *context, Cpp_Token *token){
|
||||
Cpp_Token *result = 0;
|
||||
if (token >= context->token_s && token < context->token_e){
|
||||
context->token = token;
|
||||
result = token;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
get_doc_string_from_prev(Parse_Context *context, String *doc_string){
|
||||
int32_t result = false;
|
||||
|
||||
if (can_back_step(context)){
|
||||
Cpp_Token *prev_token = get_token(context) - 1;
|
||||
if (prev_token->type == CPP_TOKEN_COMMENT){
|
||||
*doc_string = get_lexeme(*prev_token, context->data);
|
||||
if (check_and_fix_docs(doc_string)){
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Meta Parse Rules
|
||||
|
@ -1993,7 +2064,7 @@ generate_custom_headers(){
|
|||
Partition part_ = make_part(mem, size);
|
||||
Partition *part = &part_;
|
||||
|
||||
Parse string_parse = meta_parse("internal_4coder_string.cpp");
|
||||
Parse string_parse = meta_lex("internal_4coder_string.cpp");
|
||||
|
||||
int32_t string_function_count = 0;
|
||||
|
||||
|
@ -2083,8 +2154,8 @@ generate_custom_headers(){
|
|||
//
|
||||
|
||||
Parse parses[2];
|
||||
parses[0] = meta_parse("4ed_api_implementation.cpp");
|
||||
parses[1] = meta_parse("win32_api_impl.cpp");
|
||||
parses[0] = meta_lex("4ed_api_implementation.cpp");
|
||||
parses[1] = meta_lex("win32_api_impl.cpp");
|
||||
|
||||
int32_t line_count = 0;
|
||||
|
||||
|
@ -2258,128 +2329,126 @@ generate_custom_headers(){
|
|||
|
||||
// NOTE(allen): Documentation
|
||||
{
|
||||
Item_Set typedef_set = {0};
|
||||
Item_Set struct_set = {0};
|
||||
Item_Set enum_set = {0};
|
||||
|
||||
Parse type_parse[1];
|
||||
type_parse[0] = meta_parse("4coder_types.h");
|
||||
|
||||
int32_t file_count = ArrayCount(type_parse);
|
||||
|
||||
int32_t typedef_count = 0;
|
||||
int32_t struct_count = 0;
|
||||
int32_t enum_count = 0;
|
||||
|
||||
static String type_spec_keys[] = {
|
||||
make_lit_string("typedef"),
|
||||
make_lit_string("struct"),
|
||||
make_lit_string("union"),
|
||||
make_lit_string("ENUM")
|
||||
static char *type_files[] = {
|
||||
"4coder_types.h"
|
||||
};
|
||||
|
||||
for (int32_t J = 0; J < file_count; ++J){
|
||||
char *data = type_parse[J].code.str;
|
||||
|
||||
int32_t count = type_parse[J].tokens.count;
|
||||
Cpp_Token *tokens = type_parse[J].tokens.tokens;
|
||||
Cpp_Token *token = tokens;
|
||||
|
||||
for (int32_t i = 0; i < count; ++i, ++token){
|
||||
if (!(token->flags & CPP_TFLAG_PP_BODY) &&
|
||||
(token->type == CPP_TOKEN_KEY_TYPE_DECLARATION ||
|
||||
token->type == CPP_TOKEN_IDENTIFIER)){
|
||||
|
||||
String lexeme = make_string(data + token->start, token->size);
|
||||
int32_t match_index = 0;
|
||||
if (string_set_match(type_spec_keys, ArrayCount(type_spec_keys),
|
||||
lexeme, &match_index)){
|
||||
switch (match_index){
|
||||
case 0: //typedef
|
||||
++typedef_count; break;
|
||||
|
||||
case 1: case 2: //struct/union
|
||||
++struct_count; break;
|
||||
|
||||
case 3: //ENUM
|
||||
++enum_count; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
static Meta_Keywords type_spec_keys[] = {
|
||||
{make_lit_string("typedef") , Item_Typedef } ,
|
||||
{make_lit_string("struct") , Item_Struct } ,
|
||||
{make_lit_string("union") , Item_Union } ,
|
||||
{make_lit_string("ENUM") , Item_Enum } ,
|
||||
};
|
||||
#endif
|
||||
|
||||
if (typedef_count > 0){
|
||||
typedef_set = allocate_item_set(part, typedef_count);
|
||||
}
|
||||
static String type_spec_keys[] = {
|
||||
make_lit_string("typedef") ,
|
||||
make_lit_string("struct") ,
|
||||
make_lit_string("union") ,
|
||||
make_lit_string("ENUM") ,
|
||||
};
|
||||
|
||||
if (struct_count > 0){
|
||||
struct_set = allocate_item_set(part, struct_count);
|
||||
}
|
||||
Meta_Unit unit = compile_meta_unit(part, type_files, ArrayCount(type_files),
|
||||
0,0);
|
||||
//type_spec_keys, ArrayCount(type_spec_keys));
|
||||
|
||||
if (enum_count > 0){
|
||||
enum_set = allocate_item_set(part, enum_count);
|
||||
}
|
||||
|
||||
int32_t typedef_index = 0;
|
||||
int32_t struct_index = 0;
|
||||
int32_t enum_index = 0;
|
||||
|
||||
for (int32_t J = 0; J < file_count; ++J){
|
||||
char *data = type_parse[J].code.str;
|
||||
Cpp_Token_Stack types_tokens = type_parse[J].tokens;
|
||||
|
||||
Cpp_Token *token = types_tokens.tokens;
|
||||
|
||||
Parse_Context context_ = setup_parse_context(data, types_tokens);
|
||||
// TODO(allen): This stage counts nested structs
|
||||
// and unions which is not correct. Luckily it only
|
||||
// means we over allocate by a few items, but fixing it
|
||||
// to be exactly correct would be nice.
|
||||
for (int32_t J = 0; J < unit.count; ++J){
|
||||
Cpp_Token *token = 0;
|
||||
Parse_Context context_ = setup_parse_context(unit.parse[J]);
|
||||
Parse_Context *context = &context_;
|
||||
|
||||
for (; (token = get_token(context)) != 0; get_next_token(context)){
|
||||
if (!(token->flags & CPP_TFLAG_PP_BODY) &&
|
||||
(token->type == CPP_TOKEN_KEY_TYPE_DECLARATION ||
|
||||
((token->flags & CPP_TFLAG_IS_KEYWORD) ||
|
||||
token->type == CPP_TOKEN_IDENTIFIER)){
|
||||
|
||||
String lexeme = get_lexeme(*token, data);
|
||||
String lexeme = get_lexeme(*token, context->data);
|
||||
int32_t match_index = 0;
|
||||
if (string_set_match(type_spec_keys, ArrayCount(type_spec_keys),
|
||||
lexeme, &match_index)){
|
||||
switch (match_index){
|
||||
case 0: //typedef
|
||||
case 1: case 2: //struct/union
|
||||
case 3: //ENUM
|
||||
++unit.set.count; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unit.set.count > 0){
|
||||
unit.set = allocate_item_set(part, unit.set.count);
|
||||
}
|
||||
|
||||
int32_t index = 0;
|
||||
|
||||
for (int32_t J = 0; J < unit.count; ++J){
|
||||
Cpp_Token *token = 0;
|
||||
Parse_Context context_ = setup_parse_context(unit.parse[J]);
|
||||
Parse_Context *context = &context_;
|
||||
|
||||
for (; (token = get_token(context)) != 0; get_next_token(context)){
|
||||
if (!(token->flags & CPP_TFLAG_PP_BODY) &&
|
||||
((token->flags & CPP_TFLAG_IS_KEYWORD) ||
|
||||
token->type == CPP_TOKEN_IDENTIFIER)){
|
||||
|
||||
#define InvalidPath Assert(!"Invalid path of execution")
|
||||
|
||||
String lexeme = get_lexeme(*token, context->data);
|
||||
int32_t match_index = 0;
|
||||
if (string_set_match(type_spec_keys, ArrayCount(type_spec_keys),
|
||||
lexeme, &match_index)){
|
||||
switch (match_index){
|
||||
case 0: //typedef
|
||||
{
|
||||
set_token(context, token);
|
||||
if (typedef_parse(context, typedef_set.items + typedef_index)){
|
||||
Assert(typedef_set.items[typedef_index].t == Item_Typedef);
|
||||
++typedef_index;
|
||||
if (typedef_parse(context, unit.set.items + index)){
|
||||
Assert(unit.set.items[index].t == Item_Typedef);
|
||||
++index;
|
||||
}
|
||||
else{
|
||||
InvalidPath;
|
||||
}
|
||||
}break;
|
||||
|
||||
case 1: case 2: //struct/union
|
||||
{
|
||||
set_token(context, token);
|
||||
if (struct_parse(part, (match_index == 1),
|
||||
context, struct_set.items + struct_index)){
|
||||
Assert(struct_set.items[struct_index].t == Item_Struct ||
|
||||
struct_set.items[struct_index].t == Item_Union);
|
||||
++struct_index;
|
||||
context, unit.set.items + index)){
|
||||
Assert(unit.set.items[index].t == Item_Struct ||
|
||||
unit.set.items[index].t == Item_Union);
|
||||
++index;
|
||||
}
|
||||
else{
|
||||
InvalidPath;
|
||||
}
|
||||
}break;
|
||||
|
||||
case 3: //ENUM
|
||||
{
|
||||
set_token(context, token);
|
||||
if (enum_parse(part, context, enum_set.items + enum_index)){
|
||||
Assert(enum_set.items[enum_index].t == Item_Enum);
|
||||
++enum_index;
|
||||
if (enum_parse(part, context, unit.set.items + index)){
|
||||
Assert(unit.set.items[index].t == Item_Enum);
|
||||
++index;
|
||||
}
|
||||
else{
|
||||
InvalidPath;
|
||||
}
|
||||
}break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef_count = typedef_index;
|
||||
struct_count = struct_index;
|
||||
enum_count = enum_index;
|
||||
// NOTE(allen): This is necessary for now because
|
||||
// the original count is slightly overestimated thanks
|
||||
// to nested structs and unions.
|
||||
unit.set.count = index;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2818,30 +2887,8 @@ generate_custom_headers(){
|
|||
"<ul>\n"
|
||||
);
|
||||
|
||||
for (int32_t i = 0; i < typedef_count; ++i){
|
||||
String name = typedef_set.items[i].name;
|
||||
fprintf(file,
|
||||
"<li>"
|
||||
"<a href='#%.*s_doc'>%.*s</a>"
|
||||
"</li>\n",
|
||||
name.size, name.str,
|
||||
name.size, name.str
|
||||
);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < enum_count; ++i){
|
||||
String name = enum_set.items[i].name;
|
||||
fprintf(file,
|
||||
"<li>"
|
||||
"<a href='#%.*s_doc'>%.*s</a>"
|
||||
"</li>\n",
|
||||
name.size, name.str,
|
||||
name.size, name.str
|
||||
);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < struct_count; ++i){
|
||||
String name = struct_set.items[i].name;
|
||||
for (int32_t i = 0; i < unit.set.count; ++i){
|
||||
String name = unit.set.items[i].name;
|
||||
fprintf(file,
|
||||
"<li>"
|
||||
"<a href='#%.*s_doc'>%.*s</a>"
|
||||
|
@ -2881,16 +2928,8 @@ generate_custom_headers(){
|
|||
|
||||
fprintf(file, "<h3>§"SECTION" Type Descriptions</h3>\n");
|
||||
int32_t I = 1;
|
||||
for (int32_t i = 0; i < typedef_count; ++i, ++I){
|
||||
print_item(part, file, typedef_set.items + i, SECTION, I);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < enum_count; ++i, ++I){
|
||||
print_item(part, file, enum_set.items + i, SECTION, I);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < struct_count; ++i, ++I){
|
||||
print_item(part, file, struct_set.items + i, SECTION, I);
|
||||
for (int32_t i = 0; i < unit.set.count; ++i, ++I){
|
||||
print_item(part, file, unit.set.items + i, SECTION, I);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1742,8 +1742,9 @@ This call returns non-zero on success.) */{
|
|||
}
|
||||
|
||||
// TODO(allen): Add hash-table extension to string sets.
|
||||
CPP_NAME(string_set_match)
|
||||
FSTRING_LINK fstr_bool
|
||||
string_set_match(String *str_set, int32_t count, String str, int32_t *match_index)/*
|
||||
string_set_match_table(void *str_set, int32_t item_size, int32_t count, String str, int32_t *match_index)/*
|
||||
DOC_PARAM(str_set, The str_set parameter is an array of String structs specifying matchable strings.)
|
||||
DOC_PARAM(count, The count parameter specifies the number of String structs in the str_set array.)
|
||||
DOC_PARAM(str, The str parameter specifies the string to match against the str_set.)
|
||||
|
@ -1753,8 +1754,9 @@ succeeds and returns non-zero. The matching rule is equivalent to the matching
|
|||
DOC_SEE(match) */{
|
||||
fstr_bool result = 0;
|
||||
int32_t i = 0;
|
||||
for (; i < count; ++i, ++str_set){
|
||||
if (match_ss(*str_set, str)){
|
||||
uint8_t *ptr = (uint8_t*)str_set;
|
||||
for (; i < count; ++i, ptr += item_size){
|
||||
if (match_ss(*(String*)ptr, str)){
|
||||
*match_index = i;
|
||||
result = 1;
|
||||
break;
|
||||
|
@ -1763,6 +1765,20 @@ DOC_SEE(match) */{
|
|||
return(result);
|
||||
}
|
||||
|
||||
FSTRING_LINK fstr_bool
|
||||
string_set_match(String *str_set, int32_t count, String str, int32_t *match_index)/*
|
||||
DOC_PARAM(str_set, The str_set parameter is an array of String structs specifying matchable strings.)
|
||||
DOC_PARAM(count, The count parameter specifies the number of String structs in the str_set array.)
|
||||
DOC_PARAM(str, The str parameter specifies the string to match against the str_set.)
|
||||
DOC_PARAM(match_index, If this call succeeds match_index is filled with the index into str_set where the match occurred.)
|
||||
DOC(This call tries to see if str matches any of the strings in str_set. If there is a match the call
|
||||
succeeds and returns non-zero. The matching rule is equivalent to the matching rule for match.)
|
||||
DOC_SEE(match) */{
|
||||
fstr_bool result = string_set_match_table(str_set, sizeof(String), count, str, match_index);
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
#ifndef FSTRING_EXPERIMENTAL
|
||||
#define FSTRING_EXPERIMENTAL
|
||||
|
||||
|
|
Loading…
Reference in New Issue