finished setting up new doc generator which now 100 replecates the direct generator
This commit is contained in:
parent
2ec3b7348b
commit
1b38d319dc
|
@ -113,7 +113,7 @@ parse_jump_location(String line, Name_Based_Jump_Location *location,
|
||||||
int32_t colon_pos2 = find_s_char(line, colon_pos1+1, ':');
|
int32_t colon_pos2 = find_s_char(line, colon_pos1+1, ':');
|
||||||
int32_t colon_pos3 = find_s_char(line, colon_pos2+1, ':');
|
int32_t colon_pos3 = find_s_char(line, colon_pos2+1, ':');
|
||||||
|
|
||||||
if (colon_pos3+1 < line.size && line.str[colon_pos3+1] == ' '){
|
if (colon_pos3+1 <= line.size){
|
||||||
String filename = substr(line, 0, colon_pos1);
|
String filename = substr(line, 0, colon_pos1);
|
||||||
String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1);
|
String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1);
|
||||||
String column_number = substr(line, colon_pos2+1, colon_pos3 - colon_pos2 - 1);
|
String column_number = substr(line, colon_pos2+1, colon_pos3 - colon_pos2 - 1);
|
||||||
|
@ -129,16 +129,7 @@ parse_jump_location(String line, Name_Based_Jump_Location *location,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
colon_pos1 = find_s_char(line, 0, ':');
|
if (colon_pos2+1 <= line.size){
|
||||||
if (line.size > colon_pos1+1){
|
|
||||||
if (char_is_slash(line.str[colon_pos1+1])){
|
|
||||||
colon_pos1 = find_s_char(line, colon_pos1+1, ':');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
colon_pos2 = find_s_char(line, colon_pos1+1, ':');
|
|
||||||
|
|
||||||
if (colon_pos2+1 < line.size && line.str[colon_pos2+1] == ' '){
|
|
||||||
String filename = substr(line, 0, colon_pos1);
|
String filename = substr(line, 0, colon_pos1);
|
||||||
String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1);
|
String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1);
|
||||||
|
|
||||||
|
|
3
TODO.txt
3
TODO.txt
|
@ -76,6 +76,7 @@
|
||||||
; [X] killing compilation panel changes active panel
|
; [X] killing compilation panel changes active panel
|
||||||
; [X] make panel resizing not whacky with child panels
|
; [X] make panel resizing not whacky with child panels
|
||||||
; [X] visual studio file saves aren't picked up by the file track system
|
; [X] visual studio file saves aren't picked up by the file track system
|
||||||
|
; [X] findstr format not quite working
|
||||||
;
|
;
|
||||||
; [] indication on failure to save
|
; [] indication on failure to save
|
||||||
; [] history is broken, revist the entire system
|
; [] history is broken, revist the entire system
|
||||||
|
@ -85,6 +86,8 @@
|
||||||
; [] view fails to follow cursor when the view is shrunk
|
; [] view fails to follow cursor when the view is shrunk
|
||||||
; [] view fails to follow cursor after deleting long line
|
; [] view fails to follow cursor after deleting long line
|
||||||
;
|
;
|
||||||
|
; [] over left-shifting the view?
|
||||||
|
;
|
||||||
|
|
||||||
; BEFORE I SHIP
|
; BEFORE I SHIP
|
||||||
;
|
;
|
||||||
|
|
Binary file not shown.
|
@ -47,6 +47,21 @@ enum{
|
||||||
Doc_Table_Of_Contents
|
Doc_Table_Of_Contents
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct Alternate_Name{
|
||||||
|
String macro;
|
||||||
|
String public_name;
|
||||||
|
} Alternate_Name;
|
||||||
|
|
||||||
|
typedef struct Alternate_Names_Array{
|
||||||
|
Alternate_Name *names;
|
||||||
|
} Alternate_Names_Array;
|
||||||
|
|
||||||
|
enum{
|
||||||
|
AltName_Standard,
|
||||||
|
AltName_Macro,
|
||||||
|
AltName_Public_Name,
|
||||||
|
};
|
||||||
|
|
||||||
struct Document_Item{
|
struct Document_Item{
|
||||||
Document_Item *next;
|
Document_Item *next;
|
||||||
Document_Item *parent;
|
Document_Item *parent;
|
||||||
|
@ -61,6 +76,8 @@ struct Document_Item{
|
||||||
|
|
||||||
struct{
|
struct{
|
||||||
Meta_Unit *unit;
|
Meta_Unit *unit;
|
||||||
|
Alternate_Names_Array *alt_names;
|
||||||
|
int32_t alt_name_type;
|
||||||
} unit_elements;
|
} unit_elements;
|
||||||
|
|
||||||
struct{
|
struct{
|
||||||
|
@ -174,6 +191,19 @@ add_element_list(Abstract_Document *doc, Meta_Unit *unit){
|
||||||
append_child(parent, item);
|
append_child(parent, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_element_list(Abstract_Document *doc, Meta_Unit *unit, Alternate_Names_Array *alt_names, int32_t alt_name_type){
|
||||||
|
Document_Item *parent = doc->section_stack[doc->section_top];
|
||||||
|
Document_Item *item = push_struct(doc->part, Document_Item);
|
||||||
|
*item = null_document_item;
|
||||||
|
item->type = Doc_Element_List;
|
||||||
|
item->unit_elements.unit = unit;
|
||||||
|
item->unit_elements.alt_names = alt_names;
|
||||||
|
item->unit_elements.alt_name_type = alt_name_type;
|
||||||
|
|
||||||
|
append_child(parent, item);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_full_elements(Abstract_Document *doc, Meta_Unit *unit){
|
add_full_elements(Abstract_Document *doc, Meta_Unit *unit){
|
||||||
Document_Item *parent = doc->section_stack[doc->section_top];
|
Document_Item *parent = doc->section_stack[doc->section_top];
|
||||||
|
@ -185,6 +215,19 @@ add_full_elements(Abstract_Document *doc, Meta_Unit *unit){
|
||||||
append_child(parent, item);
|
append_child(parent, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_full_elements(Abstract_Document *doc, Meta_Unit *unit, Alternate_Names_Array *alt_names, int32_t alt_name_type){
|
||||||
|
Document_Item *parent = doc->section_stack[doc->section_top];
|
||||||
|
Document_Item *item = push_struct(doc->part, Document_Item);
|
||||||
|
*item = null_document_item;
|
||||||
|
item->type = Doc_Full_Elements;
|
||||||
|
item->unit_elements.unit = unit;
|
||||||
|
item->unit_elements.alt_names = alt_names;
|
||||||
|
item->unit_elements.alt_name_type = alt_name_type;
|
||||||
|
|
||||||
|
append_child(parent, item);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_table_of_contents(Abstract_Document *doc){
|
add_table_of_contents(Abstract_Document *doc){
|
||||||
Document_Item *parent = doc->section_stack[doc->section_top];
|
Document_Item *parent = doc->section_stack[doc->section_top];
|
||||||
|
@ -253,15 +296,69 @@ struct Section_Counter{
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append_section_number(String *out, Section_Counter section_counter){
|
append_section_number_reduced(String *out, Section_Counter section_counter, int32_t reduce){
|
||||||
for (int32_t i = 1; i <= section_counter.nest_level; ++i){
|
int32_t level = section_counter.nest_level-reduce;
|
||||||
|
for (int32_t i = 1; i <= level; ++i){
|
||||||
append_int_to_str(out, section_counter.counter[i]);
|
append_int_to_str(out, section_counter.counter[i]);
|
||||||
if (i != section_counter.nest_level){
|
if (i != level){
|
||||||
append_sc(out, ".");
|
append_sc(out, ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
append_section_number(String *out, Section_Counter section_counter){
|
||||||
|
append_section_number_reduced(out, section_counter, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t
|
||||||
|
extract_command_body(String *out, String l, int32_t *i_in_out, int32_t *body_start_out, int32_t *body_end_out, String command_name){
|
||||||
|
int32_t result = 0;
|
||||||
|
|
||||||
|
int32_t i = *i_in_out;
|
||||||
|
|
||||||
|
for (; i < l.size; ++i){
|
||||||
|
if (!char_is_whitespace(l.str[i])){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t found_command_body = 0;
|
||||||
|
int32_t body_start = 0, body_end = 0;
|
||||||
|
if (l.str[i] == '{'){
|
||||||
|
body_start = i+1;
|
||||||
|
|
||||||
|
for (++i; i < l.size; ++i){
|
||||||
|
if (l.str[i] == '}'){
|
||||||
|
found_command_body = 1;
|
||||||
|
body_end = i;
|
||||||
|
++i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_command_body){
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
#define STR_START "<span style='color:#F00'>! Doc generator error: missing body for "
|
||||||
|
#define STR_SLOW " !</span>"
|
||||||
|
append_sc(out, STR_START);
|
||||||
|
append_ss(out, command_name);
|
||||||
|
append_sc(out, STR_SLOW);
|
||||||
|
#undef STR
|
||||||
|
|
||||||
|
fprintf(stderr, "error: missing body for %.*s\n", command_name.size, command_name.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
*i_in_out = i;
|
||||||
|
*body_start_out = body_start;
|
||||||
|
*body_end_out = body_end;
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_enriched_text_html(String *out, Enriched_Text *text){
|
write_enriched_text_html(String *out, Enriched_Text *text){
|
||||||
String source = text->source;
|
String source = text->source;
|
||||||
|
@ -300,22 +397,48 @@ write_enriched_text_html(String *out, Enriched_Text *text){
|
||||||
make_lit_string("\\"),
|
make_lit_string("\\"),
|
||||||
make_lit_string("VERSION"),
|
make_lit_string("VERSION"),
|
||||||
make_lit_string("CODE_STYLE"),
|
make_lit_string("CODE_STYLE"),
|
||||||
|
make_lit_string("DOC_LINK"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
i = command_end;
|
||||||
|
|
||||||
int32_t match_index = 0;
|
int32_t match_index = 0;
|
||||||
if (string_set_match(enriched_commands, ArrayCount(enriched_commands), command_string, &match_index)){
|
if (string_set_match(enriched_commands, ArrayCount(enriched_commands), command_string, &match_index)){
|
||||||
switch (match_index){
|
switch (match_index){
|
||||||
case 0: append_sc(out, "\\"); break;
|
case 0: append_sc(out, "\\"); break;
|
||||||
case 1: append_sc(out, VERSION); break;
|
case 1: append_sc(out, VERSION); break;
|
||||||
case 2: append_sc(out, "<span style='"HTML_CODE_STYLE"'> TEST </span>"); break;
|
case 2:
|
||||||
|
{
|
||||||
|
int32_t body_start = 0, body_end = 0;
|
||||||
|
int32_t has_body = extract_command_body(out, l, &i, &body_start, &body_end, command_string);
|
||||||
|
if (has_body){
|
||||||
|
String body_text = substr(l, body_start, body_end - body_start);
|
||||||
|
append_sc(out, "<span style='"HTML_CODE_STYLE"'>");
|
||||||
|
append_ss(out, body_text);
|
||||||
|
append_sc(out, "</span>");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
int32_t body_start = 0, body_end = 0;
|
||||||
|
int32_t has_body = extract_command_body(out, l, &i, &body_start, &body_end, command_string);
|
||||||
|
if (has_body){
|
||||||
|
String body_text = substr(l, body_start, body_end - body_start);
|
||||||
|
append_sc(out, "<a href='#");
|
||||||
|
append_ss(out, body_text);
|
||||||
|
append_sc(out, "_doc'>");
|
||||||
|
append_ss(out, body_text);
|
||||||
|
append_sc(out, "</a>");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
append_sc(out, "<span style='color:#F00'>! Doc generator error: unrecognized command !</span>");
|
append_sc(out, "<span style='color:#F00'>! Doc generator error: unrecognized command !</span>");
|
||||||
fprintf(stderr, "error: Unrecognized command %.*s\n", command_string.size, command_string.str);
|
fprintf(stderr, "error: unrecognized command %.*s\n", command_string.size, command_string.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = command_end;
|
|
||||||
start = i;
|
start = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,7 +454,613 @@ write_enriched_text_html(String *out, Enriched_Text *text){
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
doc_item_head_html(String *out, Document_Item *item, Section_Counter section_counter){
|
print_item_in_list(String *out, String name, char *id_postfix){
|
||||||
|
append_sc(out, "<li><a href='#");
|
||||||
|
append_ss(out, name);
|
||||||
|
append_sc(out, id_postfix);
|
||||||
|
append_sc(out, "'>");
|
||||||
|
append_ss(out, name);
|
||||||
|
append_sc(out, "</a></li>");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_used_links(Partition *part, Used_Links *used, int32_t count){
|
||||||
|
used->strs = push_array(part, String, count);
|
||||||
|
used->count = 0;
|
||||||
|
used->max = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t
|
||||||
|
try_to_use(Used_Links *used, String str){
|
||||||
|
int32_t result = 1;
|
||||||
|
int32_t index = 0;
|
||||||
|
|
||||||
|
if (string_set_match(used->strs, used->count, str, &index)){
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
used->strs[used->count++] = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_struct_html(String *out, Item_Node *member, int32_t hide_children){
|
||||||
|
String name = member->name;
|
||||||
|
String type = member->type;
|
||||||
|
String type_postfix = member->type_postfix;
|
||||||
|
|
||||||
|
append_ss (out, type);
|
||||||
|
append_s_char (out, ' ');
|
||||||
|
append_ss (out, name);
|
||||||
|
append_ss (out, type_postfix);
|
||||||
|
|
||||||
|
if (match_ss(type, make_lit_string("struct")) ||
|
||||||
|
match_ss(type, make_lit_string("union"))){
|
||||||
|
|
||||||
|
if (hide_children){
|
||||||
|
append_sc(out, " { /* non-public internals */ } ;");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
append_sc(out, " {<br><div style='margin-left: 8mm;'>");
|
||||||
|
|
||||||
|
for (Item_Node *member_iter = member->first_child;
|
||||||
|
member_iter != 0;
|
||||||
|
member_iter = member_iter->next_sibling){
|
||||||
|
print_struct_html(out, member_iter, hide_children);
|
||||||
|
}
|
||||||
|
|
||||||
|
append_sc(out, "</div>};<br>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
append_sc(out, ";<br>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_function_html(String *out, Used_Links *used, String cpp_name, String ret, char *function_call_head, String name, Argument_Breakdown breakdown){
|
||||||
|
|
||||||
|
append_ss (out, ret);
|
||||||
|
append_s_char (out, ' ');
|
||||||
|
append_sc (out, function_call_head);
|
||||||
|
append_ss (out, name);
|
||||||
|
|
||||||
|
if (breakdown.count == 0){
|
||||||
|
append_sc(out, "()");
|
||||||
|
}
|
||||||
|
else if (breakdown.count == 1){
|
||||||
|
append_sc(out, "(");
|
||||||
|
append_ss(out, breakdown.args[0].param_string);
|
||||||
|
append_sc(out, ")");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
append_sc(out, "(<div style='margin-left: 4mm;'>");
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < breakdown.count; ++j){
|
||||||
|
append_ss(out, breakdown.args[j].param_string);
|
||||||
|
if (j < breakdown.count - 1){
|
||||||
|
append_s_char(out, ',');
|
||||||
|
}
|
||||||
|
append_sc(out, "<br>");
|
||||||
|
}
|
||||||
|
|
||||||
|
append_sc(out, "</div>)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_macro_html(String *out, String name, Argument_Breakdown breakdown){
|
||||||
|
|
||||||
|
append_sc (out, "#define ");
|
||||||
|
append_ss (out, name);
|
||||||
|
|
||||||
|
if (breakdown.count == 0){
|
||||||
|
append_sc(out, "()");
|
||||||
|
}
|
||||||
|
else if (breakdown.count == 1){
|
||||||
|
append_s_char (out, '(');
|
||||||
|
append_ss (out, breakdown.args[0].param_string);
|
||||||
|
append_s_char (out, ')');
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
append_sc (out, "(<div style='margin-left: 4mm;'>");
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < breakdown.count; ++j){
|
||||||
|
append_ss(out, breakdown.args[j].param_string);
|
||||||
|
if (j < breakdown.count - 1){
|
||||||
|
append_s_char(out, ',');
|
||||||
|
}
|
||||||
|
append_sc(out, "<br>");
|
||||||
|
}
|
||||||
|
|
||||||
|
append_sc(out, ")</div>)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Doc_Chunk_Type{
|
||||||
|
DocChunk_PlainText,
|
||||||
|
DocChunk_CodeExample,
|
||||||
|
|
||||||
|
DocChunk_Count
|
||||||
|
};
|
||||||
|
|
||||||
|
static String doc_chunk_headers[] = {
|
||||||
|
make_lit_string(""),
|
||||||
|
make_lit_string("CODE_EXAMPLE"),
|
||||||
|
};
|
||||||
|
|
||||||
|
static String
|
||||||
|
get_next_doc_chunk(String source, String prev_chunk, Doc_Chunk_Type *type){
|
||||||
|
String chunk = {0};
|
||||||
|
String word = {0};
|
||||||
|
int32_t pos = source.size;
|
||||||
|
int32_t word_index = 0;
|
||||||
|
Doc_Chunk_Type t = DocChunk_PlainText;
|
||||||
|
|
||||||
|
int32_t start_pos = (int32_t)(prev_chunk.str - source.str) + prev_chunk.size;
|
||||||
|
String source_tail = substr_tail(source, start_pos);
|
||||||
|
|
||||||
|
Assert(DocChunk_Count == ArrayCount(doc_chunk_headers));
|
||||||
|
|
||||||
|
for (word = get_first_word(source_tail);
|
||||||
|
word.str;
|
||||||
|
word = get_next_word(source_tail, word), ++word_index){
|
||||||
|
|
||||||
|
for (int32_t i = 1; i < DocChunk_Count; ++i){
|
||||||
|
if (match_ss(word, doc_chunk_headers[i])){
|
||||||
|
pos = (int32_t)(word.str - source.str);
|
||||||
|
t = (Doc_Chunk_Type)i;
|
||||||
|
goto doublebreak;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doublebreak:;
|
||||||
|
|
||||||
|
*type = DocChunk_PlainText;
|
||||||
|
if (word_index == 0){
|
||||||
|
*type = t;
|
||||||
|
|
||||||
|
int32_t nest_level = 1;
|
||||||
|
int32_t i = find_s_char(source, pos, '(');
|
||||||
|
for (++i; i < source.size; ++i){
|
||||||
|
if (source.str[i] == '('){
|
||||||
|
++nest_level;
|
||||||
|
}
|
||||||
|
else if (source.str[i] == ')'){
|
||||||
|
--nest_level;
|
||||||
|
if (nest_level == 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = i+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk = substr(source, start_pos, pos - start_pos);
|
||||||
|
|
||||||
|
int32_t is_all_white = 1;
|
||||||
|
for (int32_t i = 0; i < chunk.size; ++i){
|
||||||
|
if (!char_is_whitespace(chunk.str[i])){
|
||||||
|
is_all_white = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_all_white){
|
||||||
|
chunk = null_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String
|
||||||
|
get_first_doc_chunk(String source, Doc_Chunk_Type *type){
|
||||||
|
String start_str = make_string(source.str, 0);
|
||||||
|
String chunk = get_next_doc_chunk(source, start_str, type);
|
||||||
|
return(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_doc_description(String *out, Partition *part, String src){
|
||||||
|
Doc_Chunk_Type type;
|
||||||
|
|
||||||
|
for (String chunk = get_first_doc_chunk(src, &type);
|
||||||
|
chunk.str;
|
||||||
|
chunk = get_next_doc_chunk(src, chunk, &type)){
|
||||||
|
|
||||||
|
switch (type){
|
||||||
|
case DocChunk_PlainText:
|
||||||
|
{
|
||||||
|
for (String line = get_first_double_line(chunk);
|
||||||
|
line.str;
|
||||||
|
line = get_next_double_line(chunk, line)){
|
||||||
|
append_ss(out, line);
|
||||||
|
append_sc(out, "<br><br>");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case DocChunk_CodeExample:
|
||||||
|
{
|
||||||
|
int32_t start = 0;
|
||||||
|
int32_t end = chunk.size-1;
|
||||||
|
while (start < end && chunk.str[start] != '(') ++start;
|
||||||
|
start += 1;
|
||||||
|
while (end > start && chunk.str[end] != ')') --end;
|
||||||
|
|
||||||
|
|
||||||
|
append_sc(out, HTML_EXAMPLE_CODE_OPEN);
|
||||||
|
|
||||||
|
if (start < end){
|
||||||
|
String code_example = substr(chunk, start, end - start);
|
||||||
|
int32_t first_line = 1;
|
||||||
|
|
||||||
|
for (String line = get_first_line(code_example);
|
||||||
|
line.str;
|
||||||
|
line = get_next_line(code_example, line)){
|
||||||
|
|
||||||
|
if (!(first_line && line.size == 0)){
|
||||||
|
int32_t space_i = 0;
|
||||||
|
for (; space_i < line.size; ++space_i){
|
||||||
|
if (line.str[space_i] == ' '){
|
||||||
|
append_sc(out, " ");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String line_tail = substr_tail(line, space_i);
|
||||||
|
append_ss(out, line_tail);
|
||||||
|
append_sc(out, "<br>");
|
||||||
|
}
|
||||||
|
first_line = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
append_sc(out, HTML_EXAMPLE_CODE_CLOSE);
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_struct_docs(String *out, Partition *part, Item_Node *member){
|
||||||
|
for (Item_Node *member_iter = member->first_child;
|
||||||
|
member_iter != 0;
|
||||||
|
member_iter = member_iter->next_sibling){
|
||||||
|
String type = member_iter->type;
|
||||||
|
if (match_ss(type, make_lit_string("struct")) ||
|
||||||
|
match_ss(type, make_lit_string("union"))){
|
||||||
|
print_struct_docs(out, part, member_iter);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Documentation doc = {0};
|
||||||
|
perform_doc_parse(part, member_iter->doc_string, &doc);
|
||||||
|
|
||||||
|
append_sc(out, "<div>");
|
||||||
|
|
||||||
|
append_sc(out, "<div style='"HTML_CODE_STYLE"'>"HTML_DOC_ITEM_HEAD_INL_OPEN);
|
||||||
|
append_ss(out, member_iter->name);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_HEAD_INL_CLOSE"</div>");
|
||||||
|
|
||||||
|
append_sc(out, "<div style='margin-bottom: 6mm;'>"HTML_DOC_ITEM_OPEN);
|
||||||
|
print_doc_description(out, part, doc.main_doc);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_CLOSE"</div>");
|
||||||
|
|
||||||
|
append_sc(out, "</div>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_see_also(String *out, Documentation *doc){
|
||||||
|
int32_t doc_see_count = doc->see_also_count;
|
||||||
|
if (doc_see_count > 0){
|
||||||
|
append_sc(out, HTML_DOC_HEAD_OPEN"See Also"HTML_DOC_HEAD_CLOSE);
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < doc_see_count; ++j){
|
||||||
|
String see_also = doc->see_also[j];
|
||||||
|
append_sc(out, HTML_DOC_ITEM_OPEN"<a href='#");
|
||||||
|
append_ss(out, see_also);
|
||||||
|
append_sc(out, "_doc'>");
|
||||||
|
append_ss(out, see_also);
|
||||||
|
append_sc(out, "</a>"HTML_DOC_ITEM_CLOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_function_docs(String *out, Partition *part, String name, String doc_string){
|
||||||
|
if (doc_string.size == 0){
|
||||||
|
append_sc(out, "No documentation generated for this function.");
|
||||||
|
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
Temp_Memory temp = begin_temp_memory(part);
|
||||||
|
|
||||||
|
Documentation doc = {0};
|
||||||
|
|
||||||
|
perform_doc_parse(part, doc_string, &doc);
|
||||||
|
|
||||||
|
int32_t doc_param_count = doc.param_count;
|
||||||
|
if (doc_param_count > 0){
|
||||||
|
append_sc(out, HTML_DOC_HEAD_OPEN"Parameters"HTML_DOC_HEAD_CLOSE);
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < doc_param_count; ++j){
|
||||||
|
String param_name = doc.param_name[j];
|
||||||
|
String param_docs = doc.param_docs[j];
|
||||||
|
|
||||||
|
// TODO(allen): check that param_name is actually
|
||||||
|
// a parameter to this function!
|
||||||
|
|
||||||
|
append_sc(out, "<div>"HTML_DOC_ITEM_HEAD_OPEN);
|
||||||
|
append_ss(out, param_name);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_HEAD_CLOSE"<div style='margin-bottom: 6mm;'>"HTML_DOC_ITEM_OPEN);
|
||||||
|
append_ss(out, param_docs);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_CLOSE"</div></div>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String ret_doc = doc.return_doc;
|
||||||
|
if (ret_doc.size != 0){
|
||||||
|
append_sc(out, HTML_DOC_HEAD_OPEN"Return"HTML_DOC_HEAD_CLOSE HTML_DOC_ITEM_OPEN);
|
||||||
|
append_ss(out, ret_doc);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
String main_doc = doc.main_doc;
|
||||||
|
if (main_doc.size != 0){
|
||||||
|
append_sc(out, HTML_DOC_HEAD_OPEN"Description"HTML_DOC_HEAD_CLOSE HTML_DOC_ITEM_OPEN);
|
||||||
|
print_doc_description(out, part, main_doc);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_see_also(out, &doc);
|
||||||
|
|
||||||
|
end_temp_memory(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_item_html(String *out, Partition *part, Used_Links *used, Item_Node *item, char *id_postfix, char *section, int32_t I, Alternate_Name *alt_name, int32_t alt_name_type){
|
||||||
|
Temp_Memory temp = begin_temp_memory(part);
|
||||||
|
|
||||||
|
String name = item->name;
|
||||||
|
|
||||||
|
switch (alt_name_type){
|
||||||
|
case AltName_Macro:
|
||||||
|
{
|
||||||
|
name = alt_name->macro;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case AltName_Public_Name:
|
||||||
|
{
|
||||||
|
name = alt_name->public_name;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE(allen):
|
||||||
|
Open a div for the whole item.
|
||||||
|
Put a heading in it with the name and section.
|
||||||
|
Open a "descriptive" box for the display of the code interface.
|
||||||
|
*/
|
||||||
|
append_sc(out, "<div id='");
|
||||||
|
append_ss(out, name);
|
||||||
|
append_sc(out, id_postfix);
|
||||||
|
append_sc(out, "' style='margin-bottom: 1cm;'>");
|
||||||
|
|
||||||
|
int32_t has_cpp_name = 0;
|
||||||
|
if (item->cpp_name.str != 0){
|
||||||
|
if (try_to_use(used, item->cpp_name)){
|
||||||
|
append_sc(out, "<div id='");
|
||||||
|
append_ss(out, item->cpp_name);
|
||||||
|
append_sc(out, id_postfix);
|
||||||
|
append_sc(out, "'>");
|
||||||
|
has_cpp_name = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
append_sc (out, "<h4>§");
|
||||||
|
append_sc (out, section);
|
||||||
|
append_s_char (out, '.');
|
||||||
|
append_int_to_str (out, I);
|
||||||
|
append_sc (out, ": ");
|
||||||
|
append_ss (out, name);
|
||||||
|
append_sc (out, "</h4>");
|
||||||
|
|
||||||
|
append_sc(out, "<div style='"HTML_CODE_STYLE" "HTML_DESCRIPT_SECTION_STYLE"'>");
|
||||||
|
|
||||||
|
switch (item->t){
|
||||||
|
case Item_Function:
|
||||||
|
{
|
||||||
|
// NOTE(allen): Code box
|
||||||
|
print_function_html(out, used, item->cpp_name, item->ret, "", name, item->breakdown);
|
||||||
|
|
||||||
|
// NOTE(allen): Close the code box
|
||||||
|
append_sc(out, "</div>");
|
||||||
|
|
||||||
|
// NOTE(allen): Descriptive section
|
||||||
|
print_function_docs(out, part, name, item->doc_string);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case Item_Macro:
|
||||||
|
{
|
||||||
|
// NOTE(allen): Code box
|
||||||
|
print_macro_html(out, name, item->breakdown);
|
||||||
|
|
||||||
|
// NOTE(allen): Close the code box
|
||||||
|
append_sc(out, "</div>");
|
||||||
|
|
||||||
|
// NOTE(allen): Descriptive section
|
||||||
|
print_function_docs(out, part, name, item->doc_string);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case Item_Typedef:
|
||||||
|
{
|
||||||
|
String type = item->type;
|
||||||
|
|
||||||
|
// NOTE(allen): Code box
|
||||||
|
append_sc (out, "typedef ");
|
||||||
|
append_ss (out, type);
|
||||||
|
append_s_char (out, ' ');
|
||||||
|
append_ss (out, name);
|
||||||
|
append_s_char (out, ';');
|
||||||
|
|
||||||
|
// NOTE(allen): Close the code box
|
||||||
|
append_sc(out, "</div>");
|
||||||
|
|
||||||
|
// NOTE(allen): Descriptive section
|
||||||
|
String doc_string = item->doc_string;
|
||||||
|
Documentation doc = {0};
|
||||||
|
perform_doc_parse(part, doc_string, &doc);
|
||||||
|
|
||||||
|
String main_doc = doc.main_doc;
|
||||||
|
if (main_doc.size != 0){
|
||||||
|
append_sc(out, HTML_DOC_HEAD_OPEN"Description"HTML_DOC_HEAD_CLOSE);
|
||||||
|
|
||||||
|
append_sc(out, HTML_DOC_ITEM_OPEN);
|
||||||
|
print_doc_description(out, part, main_doc);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_CLOSE);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_see_also(out, &doc);
|
||||||
|
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case Item_Enum:
|
||||||
|
{
|
||||||
|
// NOTE(allen): Code box
|
||||||
|
append_sc (out, "enum ");
|
||||||
|
append_ss (out, name);
|
||||||
|
append_s_char (out, ';');
|
||||||
|
|
||||||
|
// NOTE(allen): Close the code box
|
||||||
|
append_sc(out, "</div>");
|
||||||
|
|
||||||
|
// NOTE(allen): Descriptive section
|
||||||
|
String doc_string = item->doc_string;
|
||||||
|
Documentation doc = {0};
|
||||||
|
perform_doc_parse(part, doc_string, &doc);
|
||||||
|
|
||||||
|
String main_doc = doc.main_doc;
|
||||||
|
if (main_doc.size != 0){
|
||||||
|
append_sc(out, HTML_DOC_HEAD_OPEN"Description"HTML_DOC_HEAD_CLOSE);
|
||||||
|
|
||||||
|
append_sc(out, HTML_DOC_ITEM_OPEN);
|
||||||
|
print_doc_description(out, part, main_doc);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_CLOSE);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->first_child){
|
||||||
|
append_sc(out, HTML_DOC_HEAD_OPEN"Values"HTML_DOC_HEAD_CLOSE);
|
||||||
|
|
||||||
|
for (Item_Node *member = item->first_child;
|
||||||
|
member;
|
||||||
|
member = member->next_sibling){
|
||||||
|
Documentation doc = {0};
|
||||||
|
perform_doc_parse(part, member->doc_string, &doc);
|
||||||
|
|
||||||
|
append_sc(out, "<div>");
|
||||||
|
|
||||||
|
// NOTE(allen): Dafuq is this all?
|
||||||
|
append_sc(out, "<div><span style='"HTML_CODE_STYLE"'>"HTML_DOC_ITEM_HEAD_INL_OPEN);
|
||||||
|
append_ss(out, member->name);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_HEAD_INL_CLOSE);
|
||||||
|
|
||||||
|
if (member->value.str){
|
||||||
|
append_sc(out, " = ");
|
||||||
|
append_ss(out, member->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
append_sc(out, "</span></div>");
|
||||||
|
|
||||||
|
append_sc(out, "<div style='margin-bottom: 6mm;'>"HTML_DOC_ITEM_OPEN);
|
||||||
|
print_doc_description(out, part, doc.main_doc);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_CLOSE"</div>");
|
||||||
|
|
||||||
|
append_sc(out, "</div>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_see_also(out, &doc);
|
||||||
|
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case Item_Struct: case Item_Union:
|
||||||
|
{
|
||||||
|
String doc_string = item->doc_string;
|
||||||
|
|
||||||
|
int32_t hide_members = 0;
|
||||||
|
|
||||||
|
if (doc_string.size == 0){
|
||||||
|
hide_members = 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
for (String word = get_first_word(doc_string);
|
||||||
|
word.str;
|
||||||
|
word = get_next_word(doc_string, word)){
|
||||||
|
if (match_ss(word, make_lit_string("HIDE_MEMBERS"))){
|
||||||
|
hide_members = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(allen): Code box
|
||||||
|
print_struct_html(out, item, hide_members);
|
||||||
|
|
||||||
|
// NOTE(allen): Close the code box
|
||||||
|
append_sc(out, "</div>");
|
||||||
|
|
||||||
|
// NOTE(allen): Descriptive section
|
||||||
|
{
|
||||||
|
Documentation doc = {0};
|
||||||
|
perform_doc_parse(part, doc_string, &doc);
|
||||||
|
|
||||||
|
String main_doc = doc.main_doc;
|
||||||
|
if (main_doc.size != 0){
|
||||||
|
append_sc(out, HTML_DOC_HEAD_OPEN"Description"HTML_DOC_HEAD_CLOSE);
|
||||||
|
|
||||||
|
append_sc(out, HTML_DOC_ITEM_OPEN);
|
||||||
|
print_doc_description(out, part, main_doc);
|
||||||
|
append_sc(out, HTML_DOC_ITEM_CLOSE);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hide_members){
|
||||||
|
if (item->first_child){
|
||||||
|
append_sc(out, HTML_DOC_HEAD_OPEN"Fields"HTML_DOC_HEAD_CLOSE);
|
||||||
|
print_struct_docs(out, part, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_see_also(out, &doc);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_cpp_name){
|
||||||
|
append_sc(out, "</div>");
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(allen): Close the item box
|
||||||
|
append_sc(out, "</div><hr>");
|
||||||
|
|
||||||
|
end_temp_memory(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
doc_item_head_html(String *out, Partition *part, Used_Links *used_links, Document_Item *item, Section_Counter section_counter){
|
||||||
switch (item->type){
|
switch (item->type){
|
||||||
case Doc_Root:
|
case Doc_Root:
|
||||||
{
|
{
|
||||||
|
@ -432,11 +1161,75 @@ doc_item_head_html(String *out, Document_Item *item, Section_Counter section_cou
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
|
case Doc_Todo:
|
||||||
|
{
|
||||||
|
append_sc(out, "<div><i>Coming Soon</i><div>");
|
||||||
|
}break;
|
||||||
|
|
||||||
case Doc_Enriched_Text:
|
case Doc_Enriched_Text:
|
||||||
{
|
{
|
||||||
write_enriched_text_html(out, item->text.text);
|
write_enriched_text_html(out, item->text.text);
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
|
case Doc_Element_List:
|
||||||
|
{
|
||||||
|
append_sc(out, "<ul>");
|
||||||
|
|
||||||
|
Meta_Unit *unit = item->unit_elements.unit;
|
||||||
|
Alternate_Names_Array *alt_names = item->unit_elements.alt_names;
|
||||||
|
int32_t count = unit->set.count;
|
||||||
|
|
||||||
|
switch (item->unit_elements.alt_name_type){
|
||||||
|
case AltName_Standard:
|
||||||
|
{
|
||||||
|
for (int32_t i = 0; i < count; ++i){
|
||||||
|
print_item_in_list(out, unit->set.items[i].name, "_doc");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case AltName_Macro:
|
||||||
|
{
|
||||||
|
for (int32_t i = 0; i < count; ++i){
|
||||||
|
print_item_in_list(out, alt_names->names[i].macro, "_doc");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case AltName_Public_Name:
|
||||||
|
{
|
||||||
|
for (int32_t i = 0; i < count; ++i){
|
||||||
|
print_item_in_list(out, alt_names->names[i].public_name, "_doc");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
append_sc(out, "</ul>");
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case Doc_Full_Elements:
|
||||||
|
{
|
||||||
|
Meta_Unit *unit = item->unit_elements.unit;
|
||||||
|
Alternate_Names_Array *alt_names = item->unit_elements.alt_names;
|
||||||
|
int32_t count = unit->set.count;
|
||||||
|
|
||||||
|
char section_space[32];
|
||||||
|
String section_str = make_fixed_width_string(section_space);
|
||||||
|
append_section_number_reduced(§ion_str, section_counter, 1);
|
||||||
|
terminate_with_null(§ion_str);
|
||||||
|
|
||||||
|
if (alt_names){
|
||||||
|
int32_t I = 1;
|
||||||
|
for (int32_t i = 0; i < count; ++i, ++I){
|
||||||
|
print_item_html(out, part, used_links, &unit->set.items[i], "_doc", section_str.str, I, &alt_names->names[i], item->unit_elements.alt_name_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
int32_t I = 1;
|
||||||
|
for (int32_t i = 0; i < count; ++i, ++I){
|
||||||
|
print_item_html(out, part, used_links, &unit->set.items[i], "_doc", section_str.str, I, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
case Doc_Table_Of_Contents:
|
case Doc_Table_Of_Contents:
|
||||||
{
|
{
|
||||||
append_sc(out, "<h3 style='margin:0;'>Table of Contents</h3><ul>");
|
append_sc(out, "<h3 style='margin:0;'>Table of Contents</h3><ul>");
|
||||||
|
@ -468,7 +1261,7 @@ doc_item_head_html(String *out, Document_Item *item, Section_Counter section_cou
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
doc_item_foot_html(String *out, Document_Item *item, Section_Counter section_counter){
|
doc_item_foot_html(String *out, Partition *part, Used_Links *used_links, Document_Item *item, Section_Counter section_counter){
|
||||||
switch (item->type){
|
switch (item->type){
|
||||||
case Doc_Root:
|
case Doc_Root:
|
||||||
{
|
{
|
||||||
|
@ -482,9 +1275,9 @@ doc_item_foot_html(String *out, Document_Item *item, Section_Counter section_cou
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
generate_item_html(String *out, Document_Item *item, Section_Counter *section_counter){
|
generate_item_html(String *out, Partition *part, Used_Links *used_links, Document_Item *item, Section_Counter *section_counter){
|
||||||
Section_Counter sc = *section_counter;
|
Section_Counter sc = *section_counter;
|
||||||
doc_item_head_html(out, item, sc);
|
doc_item_head_html(out, part, used_links, item, sc);
|
||||||
|
|
||||||
if (item->type == Doc_Root || item->type == Doc_Section){
|
if (item->type == Doc_Root || item->type == Doc_Section){
|
||||||
int32_t level = ++section_counter->nest_level;
|
int32_t level = ++section_counter->nest_level;
|
||||||
|
@ -492,20 +1285,23 @@ generate_item_html(String *out, Document_Item *item, Section_Counter *section_co
|
||||||
for (Document_Item *m = item->section.first_child;
|
for (Document_Item *m = item->section.first_child;
|
||||||
m != 0;
|
m != 0;
|
||||||
m = m->next){
|
m = m->next){
|
||||||
generate_item_html(out, m, section_counter);
|
generate_item_html(out, part, used_links, m, section_counter);
|
||||||
}
|
}
|
||||||
--section_counter->nest_level;
|
--section_counter->nest_level;
|
||||||
++section_counter->counter[section_counter->nest_level];
|
++section_counter->counter[section_counter->nest_level];
|
||||||
}
|
}
|
||||||
|
|
||||||
doc_item_foot_html(out, item, sc);
|
doc_item_foot_html(out, part, used_links, item, sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
generate_document_html(String *out, Abstract_Document *doc){
|
generate_document_html(String *out, Partition *part, Abstract_Document *doc){
|
||||||
|
Used_Links used_links = {0};
|
||||||
|
init_used_links(part, &used_links, 4000);
|
||||||
|
|
||||||
Section_Counter section_counter = {0};
|
Section_Counter section_counter = {0};
|
||||||
section_counter.counter[section_counter.nest_level] = 1;
|
section_counter.counter[section_counter.nest_level] = 1;
|
||||||
generate_item_html(out, doc->root_item, §ion_counter);
|
generate_item_html(out, part, &used_links, doc->root_item, §ion_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
669
site/sitegen.cpp
669
site/sitegen.cpp
|
@ -33,122 +33,6 @@
|
||||||
// Meta Parse Rules
|
// Meta Parse Rules
|
||||||
//
|
//
|
||||||
|
|
||||||
static void
|
|
||||||
init_used_links(Partition *part, Used_Links *used, int32_t count){
|
|
||||||
used->strs = push_array(part, String, count);
|
|
||||||
used->count = 0;
|
|
||||||
used->max = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t
|
|
||||||
try_to_use(Used_Links *used, String str){
|
|
||||||
int32_t result = 1;
|
|
||||||
int32_t index = 0;
|
|
||||||
|
|
||||||
if (string_set_match(used->strs, used->count, str, &index)){
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
used->strs[used->count++] = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_struct_html(String *out, Item_Node *member, int32_t hide_children){
|
|
||||||
String name = member->name;
|
|
||||||
String type = member->type;
|
|
||||||
String type_postfix = member->type_postfix;
|
|
||||||
|
|
||||||
append_ss (out, type);
|
|
||||||
append_s_char (out, ' ');
|
|
||||||
append_ss (out, name);
|
|
||||||
append_ss (out, type_postfix);
|
|
||||||
|
|
||||||
if (match_ss(type, make_lit_string("struct")) ||
|
|
||||||
match_ss(type, make_lit_string("union"))){
|
|
||||||
|
|
||||||
if (hide_children){
|
|
||||||
append_sc(out, " { /* non-public internals */ } ;");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
append_sc(out, " {<br><div style='margin-left: 8mm;'>");
|
|
||||||
|
|
||||||
for (Item_Node *member_iter = member->first_child;
|
|
||||||
member_iter != 0;
|
|
||||||
member_iter = member_iter->next_sibling){
|
|
||||||
print_struct_html(out, member_iter, hide_children);
|
|
||||||
}
|
|
||||||
|
|
||||||
append_sc(out, "</div>};<br>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
append_sc(out, ";<br>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_function_html(String *out, Used_Links *used, String cpp_name, String ret, char *function_call_head, String name, Argument_Breakdown breakdown){
|
|
||||||
|
|
||||||
append_ss (out, ret);
|
|
||||||
append_s_char (out, ' ');
|
|
||||||
append_sc (out, function_call_head);
|
|
||||||
append_ss (out, name);
|
|
||||||
|
|
||||||
if (breakdown.count == 0){
|
|
||||||
append_sc(out, "()");
|
|
||||||
}
|
|
||||||
else if (breakdown.count == 1){
|
|
||||||
append_sc(out, "(");
|
|
||||||
append_ss(out, breakdown.args[0].param_string);
|
|
||||||
append_sc(out, ")");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
append_sc(out, "(<div style='margin-left: 4mm;'>");
|
|
||||||
|
|
||||||
for (int32_t j = 0; j < breakdown.count; ++j){
|
|
||||||
append_ss(out, breakdown.args[j].param_string);
|
|
||||||
if (j < breakdown.count - 1){
|
|
||||||
append_s_char(out, ',');
|
|
||||||
}
|
|
||||||
append_sc(out, "<br>");
|
|
||||||
}
|
|
||||||
|
|
||||||
append_sc(out, "</div>)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_macro_html(String *out, String name, Argument_Breakdown breakdown){
|
|
||||||
|
|
||||||
append_sc (out, "#define ");
|
|
||||||
append_ss (out, name);
|
|
||||||
|
|
||||||
if (breakdown.count == 0){
|
|
||||||
append_sc(out, "()");
|
|
||||||
}
|
|
||||||
else if (breakdown.count == 1){
|
|
||||||
append_s_char (out, '(');
|
|
||||||
append_ss (out, breakdown.args[0].param_string);
|
|
||||||
append_s_char (out, ')');
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
append_sc (out, "(<div style='margin-left: 4mm;'>");
|
|
||||||
|
|
||||||
for (int32_t j = 0; j < breakdown.count; ++j){
|
|
||||||
append_ss(out, breakdown.args[j].param_string);
|
|
||||||
if (j < breakdown.count - 1){
|
|
||||||
append_s_char(out, ',');
|
|
||||||
}
|
|
||||||
append_sc(out, "<br>");
|
|
||||||
}
|
|
||||||
|
|
||||||
append_sc(out, ")</div>)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BACK_COLOR "#FAFAFA"
|
#define BACK_COLOR "#FAFAFA"
|
||||||
#define TEXT_COLOR "#0D0D0D"
|
#define TEXT_COLOR "#0D0D0D"
|
||||||
#define CODE_BACK "#DFDFDF"
|
#define CODE_BACK "#DFDFDF"
|
||||||
|
@ -186,199 +70,6 @@ print_macro_html(String *out, String name, Argument_Breakdown breakdown){
|
||||||
#define EXAMPLE_CODE_OPEN "<div style='"CODE_STYLE EXAMPLE_CODE_STYLE"'>"
|
#define EXAMPLE_CODE_OPEN "<div style='"CODE_STYLE EXAMPLE_CODE_STYLE"'>"
|
||||||
#define EXAMPLE_CODE_CLOSE "</div>"
|
#define EXAMPLE_CODE_CLOSE "</div>"
|
||||||
|
|
||||||
enum Doc_Chunk_Type{
|
|
||||||
DocChunk_PlainText,
|
|
||||||
DocChunk_CodeExample,
|
|
||||||
|
|
||||||
DocChunk_Count
|
|
||||||
};
|
|
||||||
|
|
||||||
static String doc_chunk_headers[] = {
|
|
||||||
make_lit_string(""),
|
|
||||||
make_lit_string("CODE_EXAMPLE"),
|
|
||||||
};
|
|
||||||
|
|
||||||
static String
|
|
||||||
get_next_doc_chunk(String source, String prev_chunk, Doc_Chunk_Type *type){
|
|
||||||
String chunk = {0};
|
|
||||||
String word = {0};
|
|
||||||
int32_t pos = source.size;
|
|
||||||
int32_t word_index = 0;
|
|
||||||
Doc_Chunk_Type t = DocChunk_PlainText;
|
|
||||||
|
|
||||||
int32_t start_pos = (int32_t)(prev_chunk.str - source.str) + prev_chunk.size;
|
|
||||||
String source_tail = substr_tail(source, start_pos);
|
|
||||||
|
|
||||||
Assert(DocChunk_Count == ArrayCount(doc_chunk_headers));
|
|
||||||
|
|
||||||
for (word = get_first_word(source_tail);
|
|
||||||
word.str;
|
|
||||||
word = get_next_word(source_tail, word), ++word_index){
|
|
||||||
|
|
||||||
for (int32_t i = 1; i < DocChunk_Count; ++i){
|
|
||||||
if (match_ss(word, doc_chunk_headers[i])){
|
|
||||||
pos = (int32_t)(word.str - source.str);
|
|
||||||
t = (Doc_Chunk_Type)i;
|
|
||||||
goto doublebreak;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doublebreak:;
|
|
||||||
|
|
||||||
*type = DocChunk_PlainText;
|
|
||||||
if (word_index == 0){
|
|
||||||
*type = t;
|
|
||||||
|
|
||||||
int32_t nest_level = 1;
|
|
||||||
int32_t i = find_s_char(source, pos, '(');
|
|
||||||
for (++i; i < source.size; ++i){
|
|
||||||
if (source.str[i] == '('){
|
|
||||||
++nest_level;
|
|
||||||
}
|
|
||||||
else if (source.str[i] == ')'){
|
|
||||||
--nest_level;
|
|
||||||
if (nest_level == 0){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = i+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk = substr(source, start_pos, pos - start_pos);
|
|
||||||
|
|
||||||
int32_t is_all_white = 1;
|
|
||||||
for (int32_t i = 0; i < chunk.size; ++i){
|
|
||||||
if (!char_is_whitespace(chunk.str[i])){
|
|
||||||
is_all_white = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_all_white){
|
|
||||||
chunk = null_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String
|
|
||||||
get_first_doc_chunk(String source, Doc_Chunk_Type *type){
|
|
||||||
String start_str = make_string(source.str, 0);
|
|
||||||
String chunk = get_next_doc_chunk(source, start_str, type);
|
|
||||||
return(chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_doc_description(String *out, Partition *part, String src){
|
|
||||||
Doc_Chunk_Type type;
|
|
||||||
|
|
||||||
for (String chunk = get_first_doc_chunk(src, &type);
|
|
||||||
chunk.str;
|
|
||||||
chunk = get_next_doc_chunk(src, chunk, &type)){
|
|
||||||
|
|
||||||
switch (type){
|
|
||||||
case DocChunk_PlainText:
|
|
||||||
{
|
|
||||||
for (String line = get_first_double_line(chunk);
|
|
||||||
line.str;
|
|
||||||
line = get_next_double_line(chunk, line)){
|
|
||||||
append_ss(out, line);
|
|
||||||
append_sc(out, "<br><br>");
|
|
||||||
}
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case DocChunk_CodeExample:
|
|
||||||
{
|
|
||||||
int32_t start = 0;
|
|
||||||
int32_t end = chunk.size-1;
|
|
||||||
while (start < end && chunk.str[start] != '(') ++start;
|
|
||||||
start += 1;
|
|
||||||
while (end > start && chunk.str[end] != ')') --end;
|
|
||||||
|
|
||||||
|
|
||||||
append_sc(out, EXAMPLE_CODE_OPEN);
|
|
||||||
|
|
||||||
if (start < end){
|
|
||||||
String code_example = substr(chunk, start, end - start);
|
|
||||||
int32_t first_line = 1;
|
|
||||||
|
|
||||||
for (String line = get_first_line(code_example);
|
|
||||||
line.str;
|
|
||||||
line = get_next_line(code_example, line)){
|
|
||||||
|
|
||||||
if (!(first_line && line.size == 0)){
|
|
||||||
int32_t space_i = 0;
|
|
||||||
for (; space_i < line.size; ++space_i){
|
|
||||||
if (line.str[space_i] == ' '){
|
|
||||||
append_sc(out, " ");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String line_tail = substr_tail(line, space_i);
|
|
||||||
append_ss(out, line_tail);
|
|
||||||
append_sc(out, "<br>");
|
|
||||||
}
|
|
||||||
first_line = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
append_sc(out, EXAMPLE_CODE_CLOSE);
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_struct_docs(String *out, Partition *part, Item_Node *member){
|
|
||||||
for (Item_Node *member_iter = member->first_child;
|
|
||||||
member_iter != 0;
|
|
||||||
member_iter = member_iter->next_sibling){
|
|
||||||
String type = member_iter->type;
|
|
||||||
if (match_ss(type, make_lit_string("struct")) ||
|
|
||||||
match_ss(type, make_lit_string("union"))){
|
|
||||||
print_struct_docs(out, part, member_iter);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
Documentation doc = {0};
|
|
||||||
perform_doc_parse(part, member_iter->doc_string, &doc);
|
|
||||||
|
|
||||||
append_sc(out, "<div>");
|
|
||||||
|
|
||||||
append_sc(out, "<div style='"CODE_STYLE"'>"DOC_ITEM_HEAD_INL_OPEN);
|
|
||||||
append_ss(out, member_iter->name);
|
|
||||||
append_sc(out, DOC_ITEM_HEAD_INL_CLOSE"</div>");
|
|
||||||
|
|
||||||
append_sc(out, "<div style='margin-bottom: 6mm;'>"DOC_ITEM_OPEN);
|
|
||||||
print_doc_description(out, part, doc.main_doc);
|
|
||||||
append_sc(out, DOC_ITEM_CLOSE"</div>");
|
|
||||||
|
|
||||||
append_sc(out, "</div>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_see_also(String *out, Documentation *doc){
|
|
||||||
int32_t doc_see_count = doc->see_also_count;
|
|
||||||
if (doc_see_count > 0){
|
|
||||||
append_sc(out, DOC_HEAD_OPEN"See Also"DOC_HEAD_CLOSE);
|
|
||||||
|
|
||||||
for (int32_t j = 0; j < doc_see_count; ++j){
|
|
||||||
String see_also = doc->see_also[j];
|
|
||||||
append_sc(out, DOC_ITEM_OPEN"<a href='#");
|
|
||||||
append_ss(out, see_also);
|
|
||||||
append_sc(out, "_doc'>");
|
|
||||||
append_ss(out, see_also);
|
|
||||||
append_sc(out, "</a>"DOC_ITEM_CLOSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_function_body_code(String *out, Parse_Context *context, int32_t start){
|
print_function_body_code(String *out, Parse_Context *context, int32_t start){
|
||||||
String pstr = {0}, lexeme = {0};
|
String pstr = {0}, lexeme = {0};
|
||||||
|
@ -427,307 +118,11 @@ print_function_body_code(String *out, Parse_Context *context, int32_t start){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static Alternate_Names_Array
|
||||||
print_function_docs(String *out, Partition *part, String name, String doc_string){
|
|
||||||
if (doc_string.size == 0){
|
|
||||||
append_sc(out, "No documentation generated for this function.");
|
|
||||||
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
Temp_Memory temp = begin_temp_memory(part);
|
|
||||||
|
|
||||||
Documentation doc = {0};
|
|
||||||
|
|
||||||
perform_doc_parse(part, doc_string, &doc);
|
|
||||||
|
|
||||||
int32_t doc_param_count = doc.param_count;
|
|
||||||
if (doc_param_count > 0){
|
|
||||||
append_sc(out, DOC_HEAD_OPEN"Parameters"DOC_HEAD_CLOSE);
|
|
||||||
|
|
||||||
for (int32_t j = 0; j < doc_param_count; ++j){
|
|
||||||
String param_name = doc.param_name[j];
|
|
||||||
String param_docs = doc.param_docs[j];
|
|
||||||
|
|
||||||
// TODO(allen): check that param_name is actually
|
|
||||||
// a parameter to this function!
|
|
||||||
|
|
||||||
append_sc(out, "<div>"DOC_ITEM_HEAD_OPEN);
|
|
||||||
append_ss(out, param_name);
|
|
||||||
append_sc(out, DOC_ITEM_HEAD_CLOSE"<div style='margin-bottom: 6mm;'>"DOC_ITEM_OPEN);
|
|
||||||
append_ss(out, param_docs);
|
|
||||||
append_sc(out, DOC_ITEM_CLOSE"</div></div>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String ret_doc = doc.return_doc;
|
|
||||||
if (ret_doc.size != 0){
|
|
||||||
append_sc(out, DOC_HEAD_OPEN"Return"DOC_HEAD_CLOSE DOC_ITEM_OPEN);
|
|
||||||
append_ss(out, ret_doc);
|
|
||||||
append_sc(out, DOC_ITEM_CLOSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
String main_doc = doc.main_doc;
|
|
||||||
if (main_doc.size != 0){
|
|
||||||
append_sc(out, DOC_HEAD_OPEN"Description"DOC_HEAD_CLOSE DOC_ITEM_OPEN);
|
|
||||||
print_doc_description(out, part, main_doc);
|
|
||||||
append_sc(out, DOC_ITEM_CLOSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
print_see_also(out, &doc);
|
|
||||||
|
|
||||||
end_temp_memory(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_item_in_list(String *out, String name, char *id_postfix){
|
|
||||||
append_sc(out, "<li><a href='#");
|
|
||||||
append_ss(out, name);
|
|
||||||
append_sc(out, id_postfix);
|
|
||||||
append_sc(out, "'>");
|
|
||||||
append_ss(out, name);
|
|
||||||
append_sc(out, "</a></li>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_item(String *out, Partition *part, Used_Links *used,
|
|
||||||
Item_Node *item, char *id_postfix, char *function_prefix,
|
|
||||||
char *section, int32_t I){
|
|
||||||
Temp_Memory temp = begin_temp_memory(part);
|
|
||||||
|
|
||||||
String name = item->name;
|
|
||||||
/* NOTE(allen):
|
|
||||||
Open a div for the whole item.
|
|
||||||
Put a heading in it with the name and section.
|
|
||||||
Open a "descriptive" box for the display of the code interface.
|
|
||||||
*/
|
|
||||||
append_sc(out, "<div id='");
|
|
||||||
append_ss(out, name);
|
|
||||||
append_sc(out, id_postfix);
|
|
||||||
append_sc(out, "' style='margin-bottom: 1cm;'>");
|
|
||||||
|
|
||||||
int32_t has_cpp_name = 0;
|
|
||||||
if (item->cpp_name.str != 0){
|
|
||||||
if (try_to_use(used, item->cpp_name)){
|
|
||||||
append_sc(out, "<div id='");
|
|
||||||
append_ss(out, item->cpp_name);
|
|
||||||
append_sc(out, id_postfix);
|
|
||||||
append_sc(out, "'>");
|
|
||||||
has_cpp_name = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
append_sc (out, "<h4>§");
|
|
||||||
append_sc (out, section);
|
|
||||||
append_s_char (out, '.');
|
|
||||||
append_int_to_str (out, I);
|
|
||||||
append_sc (out, ": ");
|
|
||||||
append_ss (out, name);
|
|
||||||
append_sc (out, "</h4>");
|
|
||||||
|
|
||||||
append_sc(out, "<div style='"CODE_STYLE" "DESCRIPT_SECTION_STYLE"'>");
|
|
||||||
|
|
||||||
switch (item->t){
|
|
||||||
case Item_Function:
|
|
||||||
{
|
|
||||||
// NOTE(allen): Code box
|
|
||||||
Assert(function_prefix != 0);
|
|
||||||
print_function_html(out, used, item->cpp_name, item->ret, function_prefix, item->name, item->breakdown);
|
|
||||||
|
|
||||||
// NOTE(allen): Close the code box
|
|
||||||
append_sc(out, "</div>");
|
|
||||||
|
|
||||||
// NOTE(allen): Descriptive section
|
|
||||||
print_function_docs(out, part, item->name, item->doc_string);
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case Item_Macro:
|
|
||||||
{
|
|
||||||
// NOTE(allen): Code box
|
|
||||||
print_macro_html(out, item->name, item->breakdown);
|
|
||||||
|
|
||||||
// NOTE(allen): Close the code box
|
|
||||||
append_sc(out, "</div>");
|
|
||||||
|
|
||||||
// NOTE(allen): Descriptive section
|
|
||||||
print_function_docs(out, part, item->name, item->doc_string);
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case Item_Typedef:
|
|
||||||
{
|
|
||||||
String type = item->type;
|
|
||||||
|
|
||||||
// NOTE(allen): Code box
|
|
||||||
append_sc (out, "typedef ");
|
|
||||||
append_ss (out, type);
|
|
||||||
append_s_char (out, ' ');
|
|
||||||
append_ss (out, name);
|
|
||||||
append_s_char (out, ';');
|
|
||||||
|
|
||||||
// NOTE(allen): Close the code box
|
|
||||||
append_sc(out, "</div>");
|
|
||||||
|
|
||||||
// NOTE(allen): Descriptive section
|
|
||||||
String doc_string = item->doc_string;
|
|
||||||
Documentation doc = {0};
|
|
||||||
perform_doc_parse(part, doc_string, &doc);
|
|
||||||
|
|
||||||
String main_doc = doc.main_doc;
|
|
||||||
if (main_doc.size != 0){
|
|
||||||
append_sc(out, DOC_HEAD_OPEN"Description"DOC_HEAD_CLOSE);
|
|
||||||
|
|
||||||
append_sc(out, DOC_ITEM_OPEN);
|
|
||||||
print_doc_description(out, part, main_doc);
|
|
||||||
append_sc(out, DOC_ITEM_CLOSE);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
print_see_also(out, &doc);
|
|
||||||
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case Item_Enum:
|
|
||||||
{
|
|
||||||
// NOTE(allen): Code box
|
|
||||||
append_sc (out, "enum ");
|
|
||||||
append_ss (out, name);
|
|
||||||
append_s_char (out, ';');
|
|
||||||
|
|
||||||
// NOTE(allen): Close the code box
|
|
||||||
append_sc(out, "</div>");
|
|
||||||
|
|
||||||
// NOTE(allen): Descriptive section
|
|
||||||
String doc_string = item->doc_string;
|
|
||||||
Documentation doc = {0};
|
|
||||||
perform_doc_parse(part, doc_string, &doc);
|
|
||||||
|
|
||||||
String main_doc = doc.main_doc;
|
|
||||||
if (main_doc.size != 0){
|
|
||||||
append_sc(out, DOC_HEAD_OPEN"Description"DOC_HEAD_CLOSE);
|
|
||||||
|
|
||||||
append_sc(out, DOC_ITEM_OPEN);
|
|
||||||
print_doc_description(out, part, main_doc);
|
|
||||||
append_sc(out, DOC_ITEM_CLOSE);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item->first_child){
|
|
||||||
append_sc(out, DOC_HEAD_OPEN"Values"DOC_HEAD_CLOSE);
|
|
||||||
|
|
||||||
for (Item_Node *member = item->first_child;
|
|
||||||
member;
|
|
||||||
member = member->next_sibling){
|
|
||||||
Documentation doc = {0};
|
|
||||||
perform_doc_parse(part, member->doc_string, &doc);
|
|
||||||
|
|
||||||
append_sc(out, "<div>");
|
|
||||||
|
|
||||||
// NOTE(allen): Dafuq is this all?
|
|
||||||
append_sc(out, "<div><span style='"CODE_STYLE"'>"DOC_ITEM_HEAD_INL_OPEN);
|
|
||||||
append_ss(out, member->name);
|
|
||||||
append_sc(out, DOC_ITEM_HEAD_INL_CLOSE);
|
|
||||||
|
|
||||||
if (member->value.str){
|
|
||||||
append_sc(out, " = ");
|
|
||||||
append_ss(out, member->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
append_sc(out, "</span></div>");
|
|
||||||
|
|
||||||
append_sc(out, "<div style='margin-bottom: 6mm;'>"DOC_ITEM_OPEN);
|
|
||||||
print_doc_description(out, part, doc.main_doc);
|
|
||||||
append_sc(out, DOC_ITEM_CLOSE"</div>");
|
|
||||||
|
|
||||||
append_sc(out, "</div>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print_see_also(out, &doc);
|
|
||||||
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case Item_Struct: case Item_Union:
|
|
||||||
{
|
|
||||||
String doc_string = item->doc_string;
|
|
||||||
|
|
||||||
int32_t hide_members = 0;
|
|
||||||
|
|
||||||
if (doc_string.size == 0){
|
|
||||||
hide_members = 1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
for (String word = get_first_word(doc_string);
|
|
||||||
word.str;
|
|
||||||
word = get_next_word(doc_string, word)){
|
|
||||||
if (match_ss(word, make_lit_string("HIDE_MEMBERS"))){
|
|
||||||
hide_members = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(allen): Code box
|
|
||||||
print_struct_html(out, item, hide_members);
|
|
||||||
|
|
||||||
// NOTE(allen): Close the code box
|
|
||||||
append_sc(out, "</div>");
|
|
||||||
|
|
||||||
// NOTE(allen): Descriptive section
|
|
||||||
{
|
|
||||||
Documentation doc = {0};
|
|
||||||
perform_doc_parse(part, doc_string, &doc);
|
|
||||||
|
|
||||||
String main_doc = doc.main_doc;
|
|
||||||
if (main_doc.size != 0){
|
|
||||||
append_sc(out, DOC_HEAD_OPEN"Description"DOC_HEAD_CLOSE);
|
|
||||||
|
|
||||||
append_sc(out, DOC_ITEM_OPEN);
|
|
||||||
print_doc_description(out, part, main_doc);
|
|
||||||
append_sc(out, DOC_ITEM_CLOSE);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hide_members){
|
|
||||||
if (item->first_child){
|
|
||||||
append_sc(out, DOC_HEAD_OPEN"Fields"DOC_HEAD_CLOSE);
|
|
||||||
print_struct_docs(out, part, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print_see_also(out, &doc);
|
|
||||||
}
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_cpp_name){
|
|
||||||
append_sc(out, "</div>");
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(allen): Close the item box
|
|
||||||
append_sc(out, "</div><hr>");
|
|
||||||
|
|
||||||
end_temp_memory(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct App_API_Name{
|
|
||||||
String macro;
|
|
||||||
String public_name;
|
|
||||||
} App_API_Name;
|
|
||||||
|
|
||||||
typedef struct App_API{
|
|
||||||
App_API_Name *names;
|
|
||||||
} App_API;
|
|
||||||
|
|
||||||
static App_API
|
|
||||||
allocate_app_api(Partition *part, int32_t count){
|
allocate_app_api(Partition *part, int32_t count){
|
||||||
App_API app_api = {0};
|
Alternate_Names_Array app_api = {0};
|
||||||
app_api.names = push_array(part, App_API_Name, count);
|
app_api.names = push_array(part, Alternate_Name, count);
|
||||||
memset(app_api.names, 0, sizeof(App_API_Name)*count);
|
memset(app_api.names, 0, sizeof(Alternate_Name)*count);
|
||||||
return(app_api);
|
return(app_api);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,12 +196,12 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
|
|
||||||
|
|
||||||
// NOTE(allen): Compute and store variations of the custom function names
|
// NOTE(allen): Compute and store variations of the custom function names
|
||||||
App_API func_4ed_names = allocate_app_api(part, custom_funcs_unit.set.count);
|
Alternate_Names_Array custom_func_names = allocate_app_api(part, custom_funcs_unit.set.count);
|
||||||
|
|
||||||
for (int32_t i = 0; i < custom_funcs_unit.set.count; ++i){
|
for (int32_t i = 0; i < custom_funcs_unit.set.count; ++i){
|
||||||
String name_string = custom_funcs_unit.set.items[i].name;
|
String name_string = custom_funcs_unit.set.items[i].name;
|
||||||
String *macro = &func_4ed_names.names[i].macro;
|
String *macro = &custom_func_names.names[i].macro;
|
||||||
String *public_name = &func_4ed_names.names[i].public_name;
|
String *public_name = &custom_func_names.names[i].public_name;
|
||||||
|
|
||||||
*macro = str_alloc(part, name_string.size+4);
|
*macro = str_alloc(part, name_string.size+4);
|
||||||
to_upper_ss(macro, name_string);
|
to_upper_ss(macro, name_string);
|
||||||
|
@ -820,6 +215,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
|
|
||||||
// NOTE(allen): Load enriched text materials
|
// NOTE(allen): Load enriched text materials
|
||||||
Enriched_Text introduction = load_enriched_text(part, src_directory, "introduction.txt");
|
Enriched_Text introduction = load_enriched_text(part, src_directory, "introduction.txt");
|
||||||
|
Enriched_Text lexer_introduction = load_enriched_text(part, src_directory, "lexer_introduction.txt");
|
||||||
|
|
||||||
// NOTE(allen): Put together the abstract document
|
// NOTE(allen): Put together the abstract document
|
||||||
Abstract_Document doc = {0};
|
Abstract_Document doc = {0};
|
||||||
|
@ -838,13 +234,13 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
begin_section(&doc, "Types and Functions", "types_and_functions");
|
begin_section(&doc, "Types and Functions", "types_and_functions");
|
||||||
{
|
{
|
||||||
begin_section(&doc, "Function List", 0);
|
begin_section(&doc, "Function List", 0);
|
||||||
add_element_list(&doc, &custom_funcs_unit);
|
add_element_list(&doc, &custom_funcs_unit, &custom_func_names, AltName_Public_Name);
|
||||||
end_section(&doc);
|
end_section(&doc);
|
||||||
begin_section(&doc, "Type List", 0);
|
begin_section(&doc, "Type List", 0);
|
||||||
add_element_list(&doc, &custom_types_unit);
|
add_element_list(&doc, &custom_types_unit);
|
||||||
end_section(&doc);
|
end_section(&doc);
|
||||||
begin_section(&doc, "Function Descriptions", 0);
|
begin_section(&doc, "Function Descriptions", 0);
|
||||||
add_full_elements(&doc, &custom_funcs_unit);
|
add_full_elements(&doc, &custom_funcs_unit, &custom_func_names, AltName_Public_Name);
|
||||||
end_section(&doc);
|
end_section(&doc);
|
||||||
begin_section(&doc, "Type Descriptions", 0);
|
begin_section(&doc, "Type Descriptions", 0);
|
||||||
add_full_elements(&doc, &custom_types_unit);
|
add_full_elements(&doc, &custom_types_unit);
|
||||||
|
@ -869,7 +265,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
begin_section(&doc, "Lexer Library", "lexer_library");
|
begin_section(&doc, "Lexer Library", "lexer_library");
|
||||||
{
|
{
|
||||||
begin_section(&doc, "Lexer Intro", 0);
|
begin_section(&doc, "Lexer Intro", 0);
|
||||||
add_todo(&doc);
|
add_enriched_text(&doc, &lexer_introduction);
|
||||||
end_section(&doc);
|
end_section(&doc);
|
||||||
begin_section(&doc, "Lexer Function List", 0);
|
begin_section(&doc, "Lexer Function List", 0);
|
||||||
add_element_list(&doc, &lexer_funcs_unit);
|
add_element_list(&doc, &lexer_funcs_unit);
|
||||||
|
@ -895,7 +291,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
|
|
||||||
// Output Docs - General Document Generator
|
// Output Docs - General Document Generator
|
||||||
if (begin_file_out(&context, "gen-test.html", &out)){
|
if (begin_file_out(&context, "gen-test.html", &out)){
|
||||||
generate_document_html(&out, &doc);
|
generate_document_html(&out, part, &doc);
|
||||||
end_file_out(context);
|
end_file_out(context);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -1015,7 +411,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
"<span style='"CODE_STYLE"'>editor@4coder.net</span> or "
|
"<span style='"CODE_STYLE"'>editor@4coder.net</span> or "
|
||||||
"to get help from community members you can post on the "
|
"to get help from community members you can post on the "
|
||||||
"4coder forums hosted on handmade.network at "
|
"4coder forums hosted on handmade.network at "
|
||||||
"<span style='"CODE_STYLE"'>4coder.handmade.network</span></p>"
|
"<span style='"CODE_STYLE"'>4coder.handmade.network</span>.</p>"
|
||||||
"</div>");
|
"</div>");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1029,7 +425,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
"<span style='"CODE_STYLE"'>editor@4coder.net</span> or "
|
"<span style='"CODE_STYLE"'>editor@4coder.net</span> or "
|
||||||
"to get help from members of the 4coder and handmade network community you "
|
"to get help from members of the 4coder and handmade network community you "
|
||||||
"can post on the 4coder forums hosted at "
|
"can post on the 4coder forums hosted at "
|
||||||
"<span style='"CODE_STYLE"'>4coder.handmade.network</span></p>"
|
"<span style='"CODE_STYLE"'>4coder.handmade.network</span>.</p>"
|
||||||
"</div>");
|
"</div>");
|
||||||
|
|
||||||
#undef MAJOR_SECTION
|
#undef MAJOR_SECTION
|
||||||
|
@ -1060,7 +456,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
|
|
||||||
append_sc(&out, "<h3>§"SECTION" Function List</h3><ul>");
|
append_sc(&out, "<h3>§"SECTION" Function List</h3><ul>");
|
||||||
for (int32_t i = 0; i < custom_funcs_unit.set.count; ++i){
|
for (int32_t i = 0; i < custom_funcs_unit.set.count; ++i){
|
||||||
print_item_in_list(&out, func_4ed_names.names[i].public_name, "_doc");
|
print_item_in_list(&out, custom_func_names.names[i].public_name, "_doc");
|
||||||
}
|
}
|
||||||
append_sc(&out, "</ul>");
|
append_sc(&out, "</ul>");
|
||||||
|
|
||||||
|
@ -1079,11 +475,12 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
append_sc(&out, "<h3>§"SECTION" Function Descriptions</h3>");
|
append_sc(&out, "<h3>§"SECTION" Function Descriptions</h3>");
|
||||||
for (int32_t i = 0; i < custom_funcs_unit.set.count; ++i){
|
for (int32_t i = 0; i < custom_funcs_unit.set.count; ++i){
|
||||||
Item_Node *item = &custom_funcs_unit.set.items[i];
|
Item_Node *item = &custom_funcs_unit.set.items[i];
|
||||||
String name = func_4ed_names.names[i].public_name;
|
String name = custom_func_names.names[i].public_name;
|
||||||
|
|
||||||
append_sc (&out, "<div id='");
|
append_sc (&out, "<div id='");
|
||||||
append_ss (&out, name);
|
append_ss (&out, name);
|
||||||
append_sc (&out, "_doc' style='margin-bottom: 1cm;'><h4>§"SECTION".");
|
append_sc (&out, "_doc' style='margin-bottom: 1cm;'>");
|
||||||
|
append_sc (&out, "<h4>§"SECTION".");
|
||||||
append_int_to_str(&out, i+1);
|
append_int_to_str(&out, i+1);
|
||||||
append_sc (&out, ": ");
|
append_sc (&out, ": ");
|
||||||
append_ss (&out, name);
|
append_ss (&out, name);
|
||||||
|
@ -1104,7 +501,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
|
|
||||||
int32_t I = 1;
|
int32_t I = 1;
|
||||||
for (int32_t i = 0; i < custom_types_unit.set.count; ++i, ++I){
|
for (int32_t i = 0; i < custom_types_unit.set.count; ++i, ++I){
|
||||||
print_item(&out, part, &used_links, custom_types_unit.set.items + i, "_doc", 0, SECTION, I);
|
print_item_html(&out, part, &used_links, custom_types_unit.set.items + i, "_doc", SECTION, I, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MAJOR_SECTION
|
#undef MAJOR_SECTION
|
||||||
|
@ -1120,7 +517,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
#undef SECTION
|
#undef SECTION
|
||||||
#define SECTION MAJOR_SECTION".1"
|
#define SECTION MAJOR_SECTION".1"
|
||||||
|
|
||||||
append_sc(&out, "<h3>§"SECTION" String Intro</h3>");
|
append_sc(&out, "<h3>§"SECTION" String Library Intro</h3>");
|
||||||
|
|
||||||
append_sc(&out, "<div><i>Coming Soon</i><div>");
|
append_sc(&out, "<div><i>Coming Soon</i><div>");
|
||||||
|
|
||||||
|
@ -1141,7 +538,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
append_sc(&out, "<h3>§"SECTION" String Function Descriptions</h3>");
|
append_sc(&out, "<h3>§"SECTION" String Function Descriptions</h3>");
|
||||||
|
|
||||||
for (int32_t i = 0; i < string_unit.set.count; ++i){
|
for (int32_t i = 0; i < string_unit.set.count; ++i){
|
||||||
print_item(&out, part, &used_links, string_unit.set.items+i, "_doc", "", SECTION, i+1);
|
print_item_html(&out, part, &used_links, string_unit.set.items+i, "_doc", SECTION, i+1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MAJOR_SECTION
|
#undef MAJOR_SECTION
|
||||||
|
@ -1161,23 +558,23 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
|
|
||||||
append_sc(&out,
|
append_sc(&out,
|
||||||
"<div>"
|
"<div>"
|
||||||
"The 4cpp lexer system provides a polished, fast, flexible system that "
|
"<p>The 4cpp lexer system provides a polished, fast, flexible system that "
|
||||||
"takes in C/C++ and outputs a tokenization of the text data. There are "
|
"takes in C/C++ and outputs a tokenization of the text data. There are "
|
||||||
"two API levels. One level is setup to let you easily get a tokenization "
|
"two API levels. One level is setup to let you easily get a tokenization "
|
||||||
"of the file. This level manages memory for you with malloc to make it "
|
"of the file. This level manages memory for you with malloc to make it "
|
||||||
"as fast as possible to start getting your tokens. The second level "
|
"as fast as possible to start getting your tokens. The second level "
|
||||||
"enables deep integration by allowing control over allocation, data "
|
"enables deep integration by allowing control over allocation, data "
|
||||||
"chunking, and output rate control.<br><br>"
|
"chunking, and output rate control.</p>"
|
||||||
"To use the quick setup API you simply include 4cpp_lexer.h and read the "
|
"<p>To use the quick setup API you simply include 4cpp_lexer.h and read the "
|
||||||
"documentation at <a href='#cpp_lex_file_doc'>cpp_lex_file</a>.<br><br>"
|
"documentation at <a href='#cpp_lex_file_doc'>cpp_lex_file</a>.</p>"
|
||||||
"To use the the fancier API include 4cpp_lexer.h and read the "
|
"<p>To use the the fancier API include 4cpp_lexer.h and read the "
|
||||||
"documentation at <a href='#cpp_lex_step_doc'>cpp_lex_step</a>. "
|
"documentation at <a href='#cpp_lex_step_doc'>cpp_lex_step</a>. "
|
||||||
"If you want to be absolutely sure you are not including malloc into "
|
"If you want to be absolutely sure you are not including malloc into "
|
||||||
"your program you can define FCPP_FORBID_MALLOC before the include and "
|
"your program you can define FCPP_FORBID_MALLOC before the include and "
|
||||||
"the \"step\" API will continue to work.<br><br>"
|
"the \"step\" API will continue to work.</p>"
|
||||||
"There are a few more features in 4cpp that are not documented yet. "
|
"<p>There are a few more features in 4cpp that are not documented yet. "
|
||||||
"You are free to try to use these, but I am not totally sure they are "
|
"You are free to try to use these, but I am not totally sure they are "
|
||||||
"ready yet, and when they are they will be documented."
|
"ready yet, and when they are they will be documented.</p>"
|
||||||
"</div>");
|
"</div>");
|
||||||
|
|
||||||
#undef SECTION
|
#undef SECTION
|
||||||
|
@ -1194,7 +591,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
#undef SECTION
|
#undef SECTION
|
||||||
#define SECTION MAJOR_SECTION".3"
|
#define SECTION MAJOR_SECTION".3"
|
||||||
|
|
||||||
append_sc(&out, "<h3>§"SECTION" Lexer Types List</h3>");
|
append_sc(&out, "<h3>§"SECTION" Lexer Type List</h3>");
|
||||||
|
|
||||||
append_sc(&out, "<ul>");
|
append_sc(&out, "<ul>");
|
||||||
for (int32_t i = 0; i < lexer_types_unit.set.count; ++i){
|
for (int32_t i = 0; i < lexer_types_unit.set.count; ++i){
|
||||||
|
@ -1207,7 +604,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
|
|
||||||
append_sc(&out, "<h3>§"SECTION" Lexer Function Descriptions</h3>");
|
append_sc(&out, "<h3>§"SECTION" Lexer Function Descriptions</h3>");
|
||||||
for (int32_t i = 0; i < lexer_funcs_unit.set.count; ++i){
|
for (int32_t i = 0; i < lexer_funcs_unit.set.count; ++i){
|
||||||
print_item(&out, part, &used_links, lexer_funcs_unit.set.items+i, "_doc", "", SECTION, i+1);
|
print_item_html(&out, part, &used_links, lexer_funcs_unit.set.items+i, "_doc", SECTION, i+1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef SECTION
|
#undef SECTION
|
||||||
|
@ -1215,7 +612,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
|
|
||||||
append_sc(&out, "<h3>§"SECTION" Lexer Type Descriptions</h3>");
|
append_sc(&out, "<h3>§"SECTION" Lexer Type Descriptions</h3>");
|
||||||
for (int32_t i = 0; i < lexer_types_unit.set.count; ++i){
|
for (int32_t i = 0; i < lexer_types_unit.set.count; ++i){
|
||||||
print_item(&out, part, &used_links, lexer_types_unit.set.items+i, "_doc", "", SECTION, i+1);
|
print_item_html(&out, part, &used_links, lexer_types_unit.set.items+i, "_doc", SECTION, i+1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
append_sc(&out, "</div></body></html>");
|
append_sc(&out, "</div></body></html>");
|
||||||
|
@ -1228,7 +625,7 @@ generate_site(char *code_directory, char *src_directory, char *dst_directory){
|
||||||
// Here to test the file equality tester
|
// Here to test the file equality tester
|
||||||
// Output Docs - General Document Generator
|
// Output Docs - General Document Generator
|
||||||
if (begin_file_out(&context, "gen-test2.html", &out)){
|
if (begin_file_out(&context, "gen-test2.html", &out)){
|
||||||
generate_document_html(&out, &doc);
|
generate_document_html(&out, part, &doc);
|
||||||
end_file_out(context);
|
end_file_out(context);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
|
|
||||||
This is the documentation for the 4cpp lexer version \VERSION. The documentation is the newest piece of this lexer project so it may still have problems. What is here should be correct and mostly complete.
|
The 4cpp lexer system provides a polished, fast, flexible system that takes in C/C++ and outputs a tokenization of the text data. There are two API levels. One level is setup to let you easily get a tokenization of the file. This level manages memory for you with malloc to make it as fast as possible to start getting your tokens. The second level enables deep integration by allowing control over allocation, data chunking, and output rate control.
|
||||||
|
|
||||||
If you have questions or discover errors please contact \CODE_STYLE{editor@4coder.net} or to get help from members of the 4coder and handmade network community you can post on the 4coder forums hosted at \CODE_STYLE{4coder.handmade.network}.
|
To use the quick setup API you simply include 4cpp_lexer.h and read the documentation at \DOC_LINK{cpp_lex_file}.
|
||||||
|
|
||||||
|
To use the the fancier API include 4cpp_lexer.h and read the documentation at \DOC_LINK{cpp_lex_step}. If you want to be absolutely sure you are not including malloc into your program you can define FCPP_FORBID_MALLOC before the include and the "step" API will continue to work.
|
||||||
|
|
||||||
|
There are a few more features in 4cpp that are not documented yet. You are free to try to use these, but I am not totally sure they are ready yet, and when they are they will be documented.
|
||||||
|
|
Loading…
Reference in New Issue