Merge branch 'master' of https://bitbucket.org/4coder/4coder
This commit is contained in:
commit
ec3f047614
|
@ -237,6 +237,7 @@ OPEN_FILE_HOOK_SIG(my_file_settings){
|
|||
}
|
||||
|
||||
buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, default_wrap_width);
|
||||
buffer_set_setting(app, &buffer, BufferSetting_MinimumBaseWrapPosition, default_min_base_width);
|
||||
buffer_set_setting(app, &buffer, BufferSetting_MapID, (treat_as_code)?((int32_t)my_code_map):((int32_t)mapid_file));
|
||||
|
||||
if (treat_as_code && enable_code_wrapping && buffer.size < (1 << 18)){
|
||||
|
|
|
@ -810,8 +810,11 @@ CUSTOM_COMMAND_SIG(left_adjust_view){
|
|||
|
||||
GUI_Scroll_Vars scroll = view.scroll_vars;
|
||||
|
||||
float x = get_view_x(view);
|
||||
x = x - 30.f;
|
||||
float x = get_view_x(view) - 30.f;
|
||||
if (x < 0){
|
||||
x = 0.f;
|
||||
}
|
||||
|
||||
scroll.target_x = (int32_t)(x + .5f);
|
||||
view_set_scroll(app, &view, scroll);
|
||||
}
|
||||
|
@ -3133,14 +3136,7 @@ get_build_directory(Application_Links *app, Buffer_Summary *buffer, String *dir_
|
|||
|
||||
// TODO(allen): Better names for the "standard build search" family.
|
||||
static int32_t
|
||||
standard_build_search(Application_Links *app,
|
||||
View_Summary *view,
|
||||
Buffer_Summary *active_buffer,
|
||||
String *dir, String *command,
|
||||
int32_t perform_backup,
|
||||
int32_t use_path_in_command,
|
||||
String filename,
|
||||
String commandname){
|
||||
standard_build_search(Application_Links *app, View_Summary *view, Buffer_Summary *active_buffer, String *dir, String *command, int32_t perform_backup, int32_t use_path_in_command, String filename, String commandname){
|
||||
int32_t result = false;
|
||||
|
||||
for(;;){
|
||||
|
@ -3489,10 +3485,11 @@ COMMAND_CALLER_HOOK(default_command_caller){
|
|||
return(0);
|
||||
}
|
||||
|
||||
// NOTE(allen|a4.0.12): A primordial config system (actually really hate this but it seems best)
|
||||
// NOTE(allen|a4.0.12): A primordial config system (actually really hate this but it seems best at least right now... arg)
|
||||
|
||||
static bool32 enable_code_wrapping = 1;
|
||||
static int32_t default_wrap_width = 672;
|
||||
static int32_t default_min_base_width = 550;
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -3558,6 +3555,13 @@ process_config_file(Application_Links *app){
|
|||
default_wrap_width = str_to_int(val);
|
||||
}
|
||||
}
|
||||
else if (match(id, "default_min_base_width")){
|
||||
if (val_token.type == CPP_TOKEN_INTEGER_CONSTANT){
|
||||
String val = make_string(mem + val_token.start, val_token.size);
|
||||
default_min_base_width = str_to_int(val);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_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 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);
|
||||
|
@ -129,16 +129,7 @@ parse_jump_location(String line, Name_Based_Jump_Location *location,
|
|||
}
|
||||
}
|
||||
else{
|
||||
colon_pos1 = find_s_char(line, 0, ':');
|
||||
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] == ' '){
|
||||
if (colon_pos2+1 <= line.size){
|
||||
String filename = substr(line, 0, colon_pos1);
|
||||
String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#define MAJOR 4
|
||||
#define MINOR 0
|
||||
#define PATCH 12
|
||||
#define PATCH 13
|
||||
|
||||
#define VN__(a,b,c) #a"."#b"."#c
|
||||
#define VN_(a,b,c) VN__(a,b,c)
|
||||
|
|
|
@ -4,6 +4,8 @@ The implementation for the custom API
|
|||
|
||||
// TOP
|
||||
|
||||
#define API_EXPORT
|
||||
|
||||
inline b32
|
||||
access_test(u32 lock_flags, u32 access_flags){
|
||||
b32 result = 0;
|
||||
|
@ -153,15 +155,12 @@ imp_get_view(Command_Data *cmd, View_Summary *view){
|
|||
return(vptr);
|
||||
}
|
||||
|
||||
#define API_EXPORT
|
||||
|
||||
API_EXPORT bool32
|
||||
Exec_Command(Application_Links *app, Command_ID command_id)
|
||||
/*
|
||||
DOC_PARAM(command_id, The command_id parameter specifies which internal command to execute.)
|
||||
DOC_RETURN(This call returns non-zero if command_id named a valid internal command.)
|
||||
DOC(A call to exec_command executes an internal command.
|
||||
If command_id is invalid a warning is posted to *messages*.)
|
||||
DOC(A call to exec_command executes an internal command. If command_id is invalid a warning is posted to *messages*.)
|
||||
DOC_SEE(Command_ID)
|
||||
*/{
|
||||
bool32 result = false;
|
||||
|
@ -721,15 +720,18 @@ DOC_RETURN(returns non-zero on success)
|
|||
int32_t result = 0;
|
||||
|
||||
if (file){
|
||||
result = 1;
|
||||
switch (setting){
|
||||
case BufferSetting_Lex: result = file->settings.tokens_exist; break;
|
||||
case BufferSetting_WrapLine: result = !file->settings.unwrapped_lines; break;
|
||||
case BufferSetting_WrapPosition: result = file->settings.display_width; break;
|
||||
case BufferSetting_MapID: result = file->settings.base_map_id; break;
|
||||
case BufferSetting_Eol: result = file->settings.dos_write_mode; break;
|
||||
case BufferSetting_Unimportant: result = file->settings.unimportant; break;
|
||||
case BufferSetting_ReadOnly: result = file->settings.read_only; break;
|
||||
case BufferSetting_VirtualWhitespace: result = file->settings.virtual_white; break;
|
||||
case BufferSetting_Lex: *value_out = file->settings.tokens_exist; break;
|
||||
case BufferSetting_WrapLine: *value_out = !file->settings.unwrapped_lines; break;
|
||||
case BufferSetting_WrapPosition: *value_out = file->settings.display_width; break;
|
||||
case BufferSetting_MinimumBaseWrapPosition: *value_out = file->settings.minimum_base_display_width; break;
|
||||
case BufferSetting_MapID: *value_out = file->settings.base_map_id; break;
|
||||
case BufferSetting_Eol: *value_out = file->settings.dos_write_mode; break;
|
||||
case BufferSetting_Unimportant: *value_out = file->settings.unimportant; break;
|
||||
case BufferSetting_ReadOnly: *value_out = file->settings.read_only; break;
|
||||
case BufferSetting_VirtualWhitespace: *value_out = file->settings.virtual_white; break;
|
||||
default: result = 0; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1542,12 +1544,14 @@ DOC_RETURN(returns non-zero on success)
|
|||
*/{
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
View *vptr = imp_get_view(cmd, view);
|
||||
int32_t result = -1;
|
||||
int32_t result = 0;
|
||||
|
||||
if (vptr){
|
||||
result = 1;
|
||||
switch (setting){
|
||||
case ViewSetting_ShowWhitespace: result = vptr->file_data.show_whitespace; break;
|
||||
case ViewSetting_ShowScrollbar: result = !vptr->hide_scrollbar; break;
|
||||
case ViewSetting_ShowWhitespace: *value_out = vptr->file_data.show_whitespace; break;
|
||||
case ViewSetting_ShowScrollbar: *value_out = !vptr->hide_scrollbar; break;
|
||||
default: result = 0; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -284,8 +284,8 @@ view_file_display_width(View *view){
|
|||
inline f32
|
||||
view_file_minimum_base__width(View *view){
|
||||
Editing_File *file = view->file_data.file;
|
||||
f32 result = (f32)file->settings.display_width;
|
||||
return(result);
|
||||
f32 result = (f32)file->settings.display_width;
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline f32
|
||||
|
@ -1066,7 +1066,7 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){
|
|||
}
|
||||
|
||||
if (state->in_pp_body){
|
||||
if (!(state->token_ptr->flags & CPP_TFLAG_PP_BODY)){
|
||||
if (!(state->token_ptr->flags & CPP_TFLAG_PP_BODY)){
|
||||
state->in_pp_body = 0;
|
||||
state->wrap_x = state->plane_wrap_x;
|
||||
}
|
||||
|
@ -1252,7 +1252,7 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, u16 flags, u16
|
|||
}
|
||||
else{
|
||||
if (other_is_words){
|
||||
guess = 100;
|
||||
guess = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1367,46 +1367,46 @@ get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start, b32 *adjust_
|
|||
current_shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top-1] + wrap_state->tab_indent_amount;
|
||||
|
||||
*adjust_top_to_this = 1;
|
||||
}
|
||||
|
||||
f32 statement_continuation_indent = 0.f;
|
||||
if (current_shift != 0.f && wrap_state->wrap_x.paren_safe_top == 0){
|
||||
if (!(prev_token.flags & CPP_TFLAG_PP_BODY) && !(prev_token.flags & CPP_TFLAG_PP_DIRECTIVE)){
|
||||
|
||||
switch (prev_token.type){
|
||||
case CPP_TOKEN_BRACKET_OPEN:
|
||||
case CPP_TOKEN_BRACE_OPEN:
|
||||
case CPP_TOKEN_BRACE_CLOSE:
|
||||
case CPP_TOKEN_SEMICOLON:
|
||||
case CPP_TOKEN_COLON:
|
||||
case CPP_TOKEN_COMMA:
|
||||
case CPP_TOKEN_COMMENT: break;
|
||||
default: statement_continuation_indent += wrap_state->tab_indent_amount; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (wrap_state->token_ptr->type){
|
||||
case CPP_TOKEN_BRACE_CLOSE: case CPP_TOKEN_BRACE_OPEN: break;
|
||||
default: current_shift += statement_continuation_indent; break;
|
||||
}
|
||||
}
|
||||
|
||||
f32 statement_continuation_indent = 0.f;
|
||||
if (current_shift != 0.f && wrap_state->wrap_x.paren_safe_top == 0){
|
||||
if (!(prev_token.flags & CPP_TFLAG_PP_BODY) && !(prev_token.flags & CPP_TFLAG_PP_DIRECTIVE)){
|
||||
|
||||
switch (prev_token.type){
|
||||
case CPP_TOKEN_BRACKET_OPEN:
|
||||
case CPP_TOKEN_BRACE_OPEN:
|
||||
case CPP_TOKEN_BRACE_CLOSE:
|
||||
case CPP_TOKEN_SEMICOLON:
|
||||
case CPP_TOKEN_COLON:
|
||||
case CPP_TOKEN_COMMA:
|
||||
case CPP_TOKEN_COMMENT: break;
|
||||
default: statement_continuation_indent += wrap_state->tab_indent_amount; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (wrap_state->token_ptr->type){
|
||||
case CPP_TOKEN_BRACE_CLOSE: case CPP_TOKEN_BRACE_OPEN: break;
|
||||
default: current_shift += statement_continuation_indent; break;
|
||||
if (wrap_state->token_ptr->start < next_line_start){
|
||||
if (wrap_state->token_ptr->flags & CPP_TFLAG_PP_DIRECTIVE){
|
||||
current_shift = 0;
|
||||
}
|
||||
else{
|
||||
switch (wrap_state->token_ptr->type){
|
||||
case CPP_TOKEN_BRACE_CLOSE:
|
||||
{
|
||||
if (wrap_state->wrap_x.paren_safe_top == 0){
|
||||
current_shift -= wrap_state->tab_indent_amount;
|
||||
}
|
||||
}
|
||||
|
||||
if (wrap_state->token_ptr->start < next_line_start){
|
||||
if (wrap_state->token_ptr->flags & CPP_TFLAG_PP_DIRECTIVE){
|
||||
current_shift = 0;
|
||||
}
|
||||
else{
|
||||
switch (wrap_state->token_ptr->type){
|
||||
case CPP_TOKEN_BRACE_CLOSE:
|
||||
{
|
||||
if (wrap_state->wrap_x.paren_safe_top == 0){
|
||||
current_shift -= wrap_state->tab_indent_amount;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(current_shift);
|
||||
}
|
||||
|
@ -1499,7 +1499,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
b32 still_looping = 0;
|
||||
do{
|
||||
for (; i < stream.end; ++i){
|
||||
u8 ch = stream.data[i];
|
||||
u8 ch = stream.data[i];
|
||||
|
||||
switch (word_stage){
|
||||
case 0:
|
||||
|
@ -1549,13 +1549,16 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
|
||||
if (use_tokens){
|
||||
Code_Wrap_State original_wrap_state = wrap_state;
|
||||
i32 next_line_start = params.buffer->line_starts[stop.line_index+1];
|
||||
i32 next_line_start = buffer_size(params.buffer);
|
||||
if (stop.line_index+1 < params.buffer->line_count){
|
||||
next_line_start = params.buffer->line_starts[stop.line_index+1];
|
||||
}
|
||||
|
||||
f32 base_adjusted_width = wrap_state.wrap_x.base_x + minimum_base_width;
|
||||
|
||||
if (minimum_base_width != 0 && current_width < base_adjusted_width){
|
||||
current_width = base_adjusted_width;
|
||||
}
|
||||
current_width = base_adjusted_width;
|
||||
}
|
||||
|
||||
if (stop.status == BLStatus_NeedLineShift){
|
||||
real_count = 0;
|
||||
|
@ -1580,7 +1583,8 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
b32 emit_comment_position = 0;
|
||||
b32 first_word = 1;
|
||||
|
||||
if (wrap_state.token_ptr->type == CPP_TOKEN_COMMENT){
|
||||
if (wrap_state.token_ptr->type == CPP_TOKEN_COMMENT ||
|
||||
wrap_state.token_ptr->type == CPP_TOKEN_STRING_CONSTANT){
|
||||
i32 i = wrap_state.token_ptr->start;
|
||||
i32 end_i = i + wrap_state.token_ptr->size;
|
||||
|
||||
|
@ -1607,74 +1611,86 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
|
|||
potential_wrap.wrap_x = x;
|
||||
potential_wrap.adjust_top_to_this = 0;
|
||||
|
||||
if (buffer_stringify_loop(&stream, params.buffer, i, end_i)){
|
||||
b32 still_looping = 1;
|
||||
if (buffer_stringify_loop(&stream, params.buffer, i, end_i)){
|
||||
b32 still_looping = 1;
|
||||
|
||||
do{
|
||||
while (still_looping){
|
||||
for (; i < stream.end; ++i){
|
||||
u8 ch = stream.data[i];
|
||||
while(still_looping){
|
||||
for (; i < stream.end; ++i){
|
||||
u8 ch = stream.data[i];
|
||||
|
||||
if (char_is_whitespace(ch)){
|
||||
goto doublebreak_stage1;
|
||||
}
|
||||
|
||||
f32 adv = params.adv[ch];
|
||||
x += adv;
|
||||
if (!first_word && x > current_width){
|
||||
emit_comment_position = 1;
|
||||
goto doublebreak_stage1;
|
||||
if (!char_is_whitespace(ch)){
|
||||
goto doublebreak_stage_vspace;
|
||||
}
|
||||
}
|
||||
still_looping = buffer_stringify_next(&stream);
|
||||
}
|
||||
doublebreak_stage1:;
|
||||
first_word = 0;
|
||||
}
|
||||
still_looping = buffer_stringify_next(&stream);
|
||||
}
|
||||
doublebreak_stage_vspace:;
|
||||
|
||||
if (emit_comment_position){
|
||||
step.position_end = i;
|
||||
step.final_x = x;
|
||||
goto finished_comment_split;
|
||||
}
|
||||
do{
|
||||
while (still_looping){
|
||||
for (; i < stream.end; ++i){
|
||||
u8 ch = stream.data[i];
|
||||
|
||||
while(still_looping){
|
||||
for (; i < stream.end; ++i){
|
||||
u8 ch = stream.data[i];
|
||||
if (char_is_whitespace(ch)){
|
||||
goto doublebreak_stage1;
|
||||
}
|
||||
|
||||
if (!char_is_whitespace(ch)){
|
||||
goto doublebreak_stage2;
|
||||
f32 adv = params.adv[ch];
|
||||
x += adv;
|
||||
if (!first_word && x > current_width){
|
||||
emit_comment_position = 1;
|
||||
goto doublebreak_stage1;
|
||||
}
|
||||
}
|
||||
still_looping = buffer_stringify_next(&stream);
|
||||
}
|
||||
doublebreak_stage1:;
|
||||
first_word = 0;
|
||||
|
||||
if (emit_comment_position){
|
||||
step.position_end = i;
|
||||
step.final_x = x;
|
||||
goto finished_comment_split;
|
||||
}
|
||||
|
||||
f32 adv = params.adv[ch];
|
||||
x += adv;
|
||||
while(still_looping){
|
||||
for (; i < stream.end; ++i){
|
||||
u8 ch = stream.data[i];
|
||||
|
||||
if (!char_is_whitespace(ch)){
|
||||
goto doublebreak_stage2;
|
||||
}
|
||||
|
||||
f32 adv = params.adv[ch];
|
||||
x += adv;
|
||||
}
|
||||
still_looping = buffer_stringify_next(&stream);
|
||||
}
|
||||
doublebreak_stage2:;
|
||||
|
||||
potential_wrap.wrap_position = i;
|
||||
potential_wrap.wrap_x = x;
|
||||
}while(still_looping);
|
||||
}
|
||||
still_looping = buffer_stringify_next(&stream);
|
||||
}
|
||||
doublebreak_stage2:;
|
||||
|
||||
potential_wrap.wrap_position = i;
|
||||
potential_wrap.wrap_x = x;
|
||||
}while(still_looping);
|
||||
}
|
||||
finished_comment_split:;
|
||||
if (emit_comment_position){
|
||||
potential_marks[potential_count] = potential_wrap;
|
||||
++potential_count;
|
||||
}
|
||||
}
|
||||
|
||||
finished_comment_split:;
|
||||
if (emit_comment_position){
|
||||
potential_marks[potential_count] = potential_wrap;
|
||||
++potential_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (!emit_comment_position){
|
||||
step = wrap_state_consume_token(&wrap_state, next_line_start-1);
|
||||
}
|
||||
if (!emit_comment_position){
|
||||
step = wrap_state_consume_token(&wrap_state, next_line_start-1);
|
||||
}
|
||||
|
||||
b32 need_to_choose_a_wrap = 0;
|
||||
if (step.final_x > current_width){
|
||||
need_to_choose_a_wrap = 1;
|
||||
}
|
||||
|
||||
adjust_top_to_this = 0;
|
||||
current_shift = get_current_shift(&wrap_state, next_line_start, &adjust_top_to_this);
|
||||
adjust_top_to_this = 0;
|
||||
current_shift = get_current_shift(&wrap_state, next_line_start, &adjust_top_to_this);
|
||||
|
||||
b32 next_token_is_on_line = 0;
|
||||
if (wrap_state.token_ptr->start < next_line_start){
|
||||
|
@ -2146,7 +2162,7 @@ file_first_lex_serial(System_Functions *system, Mem_Options *mem, Editing_File *
|
|||
Temp_Memory temp = begin_temp_memory(part);
|
||||
|
||||
Buffer_Type *buffer = &file->state.buffer;
|
||||
i32 text_size = buffer_size(buffer);
|
||||
i32 text_size = buffer_size(buffer);
|
||||
|
||||
i32 mem_size = partition_remaining(part);
|
||||
|
||||
|
@ -2155,69 +2171,69 @@ file_first_lex_serial(System_Functions *system, Mem_Options *mem, Editing_File *
|
|||
tokens.count = 0;
|
||||
tokens.tokens = push_array(part, Cpp_Token, tokens.max_count);
|
||||
|
||||
b32 still_lexing = 1;
|
||||
b32 still_lexing = 1;
|
||||
|
||||
Cpp_Lex_Data lex = cpp_lex_data_init();
|
||||
Cpp_Lex_Data lex = cpp_lex_data_init();
|
||||
|
||||
// TODO(allen): deduplicate this against relex
|
||||
char *chunks[3];
|
||||
i32 chunk_sizes[3];
|
||||
// TODO(allen): deduplicate this against relex
|
||||
char *chunks[3];
|
||||
i32 chunk_sizes[3];
|
||||
|
||||
chunks[0] = buffer->data;
|
||||
chunk_sizes[0] = buffer->size1;
|
||||
chunks[0] = buffer->data;
|
||||
chunk_sizes[0] = buffer->size1;
|
||||
|
||||
chunks[1] = buffer->data + buffer->size1 + buffer->gap_size;
|
||||
chunk_sizes[1] = buffer->size2;
|
||||
chunks[1] = buffer->data + buffer->size1 + buffer->gap_size;
|
||||
chunk_sizes[1] = buffer->size2;
|
||||
|
||||
chunks[2] = 0;
|
||||
chunk_sizes[2] = 0;
|
||||
chunks[2] = 0;
|
||||
chunk_sizes[2] = 0;
|
||||
|
||||
i32 chunk_index = 0;
|
||||
i32 chunk_index = 0;
|
||||
|
||||
do{
|
||||
char *chunk = chunks[chunk_index];
|
||||
i32 chunk_size = chunk_sizes[chunk_index];
|
||||
do{
|
||||
char *chunk = chunks[chunk_index];
|
||||
i32 chunk_size = chunk_sizes[chunk_index];
|
||||
|
||||
i32 result = cpp_lex_step(&lex, chunk, chunk_size, text_size, &tokens, NO_OUT_LIMIT);
|
||||
i32 result = cpp_lex_step(&lex, chunk, chunk_size, text_size, &tokens, NO_OUT_LIMIT);
|
||||
|
||||
switch (result){
|
||||
case LexResult_NeedChunk: ++chunk_index; break;
|
||||
case LexResult_NeedTokenMemory: InvalidCodePath;
|
||||
case LexResult_HitTokenLimit: InvalidCodePath;
|
||||
case LexResult_Finished: still_lexing = 0; break;
|
||||
}
|
||||
} while (still_lexing);
|
||||
switch (result){
|
||||
case LexResult_NeedChunk: ++chunk_index; break;
|
||||
case LexResult_NeedTokenMemory: InvalidCodePath;
|
||||
case LexResult_HitTokenLimit: InvalidCodePath;
|
||||
case LexResult_Finished: still_lexing = 0; break;
|
||||
}
|
||||
} while (still_lexing);
|
||||
|
||||
i32 new_max = LargeRoundUp(tokens.count+1, Kbytes(1));
|
||||
i32 new_max = LargeRoundUp(tokens.count+1, Kbytes(1));
|
||||
|
||||
{
|
||||
Assert(file->state.swap_array.tokens == 0);
|
||||
file->state.swap_array.tokens = (Cpp_Token*) general_memory_allocate(system, general, new_max*sizeof(Cpp_Token));
|
||||
}
|
||||
{
|
||||
Assert(file->state.swap_array.tokens == 0);
|
||||
file->state.swap_array.tokens = (Cpp_Token*) general_memory_allocate(system, general, new_max*sizeof(Cpp_Token));
|
||||
}
|
||||
|
||||
u8 *dest = (u8*)file->state.swap_array.tokens;
|
||||
u8 *src = (u8*)tokens.tokens;
|
||||
u8 *dest = (u8*)file->state.swap_array.tokens;
|
||||
u8 *src = (u8*)tokens.tokens;
|
||||
|
||||
memcpy(dest, src, tokens.count*sizeof(Cpp_Token));
|
||||
memcpy(dest, src, tokens.count*sizeof(Cpp_Token));
|
||||
|
||||
{
|
||||
Cpp_Token_Array *file_token_array = &file->state.token_array;
|
||||
file_token_array->count = tokens.count;
|
||||
file_token_array->max_count = new_max;
|
||||
if (file_token_array->tokens){
|
||||
general_memory_free(system, general, file_token_array->tokens);
|
||||
}
|
||||
file_token_array->tokens = file->state.swap_array.tokens;
|
||||
file->state.swap_array.tokens = 0;
|
||||
}
|
||||
{
|
||||
Cpp_Token_Array *file_token_array = &file->state.token_array;
|
||||
file_token_array->count = tokens.count;
|
||||
file_token_array->max_count = new_max;
|
||||
if (file_token_array->tokens){
|
||||
general_memory_free(system, general, file_token_array->tokens);
|
||||
}
|
||||
file_token_array->tokens = file->state.swap_array.tokens;
|
||||
file->state.swap_array.tokens = 0;
|
||||
}
|
||||
|
||||
// NOTE(allen): These are outside the locked section because I don't
|
||||
// think getting these out of order will cause critical bugs, and I
|
||||
// want to minimize what's done in locked sections.
|
||||
file->state.tokens_complete = 1;
|
||||
file->state.still_lexing = 0;
|
||||
// NOTE(allen): These are outside the locked section because I don't
|
||||
// think getting these out of order will cause critical bugs, and I
|
||||
// want to minimize what's done in locked sections.
|
||||
file->state.tokens_complete = 1;
|
||||
file->state.still_lexing = 0;
|
||||
|
||||
end_temp_memory(temp);
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
||||
file->state.tokens_complete = 1;
|
||||
|
@ -2363,69 +2379,69 @@ file_relex_serial(System_Functions *system, Mem_Options *mem, Editing_File *file
|
|||
|
||||
Assert(!file->state.still_lexing);
|
||||
|
||||
Buffer_Type *buffer = &file->state.buffer;
|
||||
Cpp_Token_Array *array = &file->state.token_array;
|
||||
Buffer_Type *buffer = &file->state.buffer;
|
||||
Cpp_Token_Array *array = &file->state.token_array;
|
||||
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
Cpp_Token_Array relex_array;
|
||||
relex_array.count = 0;
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
Cpp_Token_Array relex_array;
|
||||
relex_array.count = 0;
|
||||
relex_array.max_count = partition_remaining(part) / sizeof(Cpp_Token);
|
||||
relex_array.tokens = push_array(part, Cpp_Token, relex_array.max_count);
|
||||
relex_array.tokens = push_array(part, Cpp_Token, relex_array.max_count);
|
||||
|
||||
i32 size = buffer_size(buffer);
|
||||
i32 size = buffer_size(buffer);
|
||||
|
||||
Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount);
|
||||
Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount);
|
||||
|
||||
char *chunks[3];
|
||||
i32 chunk_sizes[3];
|
||||
char *chunks[3];
|
||||
i32 chunk_sizes[3];
|
||||
|
||||
chunks[0] = buffer->data;
|
||||
chunk_sizes[0] = buffer->size1;
|
||||
chunks[0] = buffer->data;
|
||||
chunk_sizes[0] = buffer->size1;
|
||||
|
||||
chunks[1] = buffer->data + buffer->size1 + buffer->gap_size;
|
||||
chunk_sizes[1] = buffer->size2;
|
||||
chunks[1] = buffer->data + buffer->size1 + buffer->gap_size;
|
||||
chunk_sizes[1] = buffer->size2;
|
||||
|
||||
chunks[2] = 0;
|
||||
chunk_sizes[2] = 0;
|
||||
chunks[2] = 0;
|
||||
chunk_sizes[2] = 0;
|
||||
|
||||
i32 chunk_index = 0;
|
||||
char *chunk = chunks[chunk_index];
|
||||
i32 chunk_size = chunk_sizes[chunk_index];
|
||||
i32 chunk_index = 0;
|
||||
char *chunk = chunks[chunk_index];
|
||||
i32 chunk_size = chunk_sizes[chunk_index];
|
||||
|
||||
while (!cpp_relex_is_start_chunk(&state, chunk, chunk_size)){
|
||||
while (!cpp_relex_is_start_chunk(&state, chunk, chunk_size)){
|
||||
++chunk_index;
|
||||
chunk = chunks[chunk_index];
|
||||
chunk_size = chunk_sizes[chunk_index];
|
||||
}
|
||||
|
||||
for(;;){
|
||||
Cpp_Lex_Result lex_result = cpp_relex_step(&state, chunk, chunk_size, size, array, &relex_array);
|
||||
|
||||
switch (lex_result){
|
||||
case LexResult_NeedChunk:
|
||||
++chunk_index;
|
||||
chunk = chunks[chunk_index];
|
||||
chunk_size = chunk_sizes[chunk_index];
|
||||
break;
|
||||
|
||||
case LexResult_NeedTokenMemory: InvalidCodePath;
|
||||
|
||||
case LexResult_Finished: goto doublebreak;
|
||||
}
|
||||
}
|
||||
doublebreak:;
|
||||
|
||||
for(;;){
|
||||
Cpp_Lex_Result lex_result = cpp_relex_step(&state, chunk, chunk_size, size, array, &relex_array);
|
||||
i32 new_count = cpp_relex_get_new_count(&state, array->count, &relex_array);
|
||||
if (new_count > array->max_count){
|
||||
i32 new_max = LargeRoundUp(new_count, Kbytes(1));
|
||||
array->tokens = (Cpp_Token*)
|
||||
general_memory_reallocate(system, general, array->tokens, array->count*sizeof(Cpp_Token), new_max*sizeof(Cpp_Token));
|
||||
array->max_count = new_max;
|
||||
}
|
||||
|
||||
switch (lex_result){
|
||||
case LexResult_NeedChunk:
|
||||
++chunk_index;
|
||||
chunk = chunks[chunk_index];
|
||||
chunk_size = chunk_sizes[chunk_index];
|
||||
break;
|
||||
cpp_relex_complete(&state, array, &relex_array);
|
||||
|
||||
case LexResult_NeedTokenMemory: InvalidCodePath;
|
||||
|
||||
case LexResult_Finished: goto doublebreak;
|
||||
}
|
||||
}
|
||||
doublebreak:;
|
||||
|
||||
i32 new_count = cpp_relex_get_new_count(&state, array->count, &relex_array);
|
||||
if (new_count > array->max_count){
|
||||
i32 new_max = LargeRoundUp(new_count, Kbytes(1));
|
||||
array->tokens = (Cpp_Token*)
|
||||
general_memory_reallocate(system, general, array->tokens, array->count*sizeof(Cpp_Token), new_max*sizeof(Cpp_Token));
|
||||
array->max_count = new_max;
|
||||
}
|
||||
|
||||
cpp_relex_complete(&state, array, &relex_array);
|
||||
|
||||
end_temp_memory(temp);
|
||||
end_temp_memory(temp);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
@ -3116,7 +3132,7 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file
|
|||
// NOTE(allen): token fixing
|
||||
if (file->settings.tokens_exist){
|
||||
if (!file->settings.virtual_white){
|
||||
file_relex_parallel(system, mem, file, start, end, shift_amount);
|
||||
file_relex_parallel(system, mem, file, start, end, shift_amount);
|
||||
}
|
||||
else{
|
||||
file_relex_serial(system, mem, file, start, end, shift_amount);
|
||||
|
@ -3208,7 +3224,7 @@ file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file,
|
|||
Buffer_Edit *last_edit = batch + batch_size - 1;
|
||||
|
||||
if (!file->settings.virtual_white){
|
||||
file_relex_parallel(system, mem, file, first_edit->start, last_edit->end, shift_total);
|
||||
file_relex_parallel(system, mem, file, first_edit->start, last_edit->end, shift_total);
|
||||
}
|
||||
else{
|
||||
file_relex_serial(system, mem, file, first_edit->start, last_edit->end, shift_total);
|
||||
|
@ -3724,13 +3740,13 @@ make_string_terminated(Partition *part, char *str, i32 len){
|
|||
|
||||
internal void
|
||||
init_normal_file(System_Functions *system, Models *models, Editing_File *file, char *buffer, i32 size){
|
||||
String val = make_string(buffer, size);
|
||||
String val = make_string(buffer, size);
|
||||
file_create_from_string(system, models, file, val);
|
||||
|
||||
Mem_Options *mem = &models->mem;
|
||||
if (file->settings.tokens_exist && file->state.token_array.tokens == 0){
|
||||
if (!file->settings.virtual_white){
|
||||
file_first_lex_parallel(system, mem, file);
|
||||
file_first_lex_parallel(system, mem, file);
|
||||
}
|
||||
else{
|
||||
file_first_lex_serial(system, mem, file);
|
||||
|
@ -3796,7 +3812,7 @@ view_open_file(System_Functions *system, Models *models, View *view, String file
|
|||
init_normal_file(system, models, file, buffer, size);
|
||||
}
|
||||
else{
|
||||
system->load_close(handle);
|
||||
system->load_close(handle);
|
||||
}
|
||||
|
||||
if (gen_buffer){
|
||||
|
@ -4123,9 +4139,9 @@ internal void
|
|||
intbar_draw_string(Render_Target *target, File_Bar *bar, String str, u32 char_color){
|
||||
i16 font_id = bar->font_id;
|
||||
draw_string(target, font_id, str,
|
||||
(i32)(bar->pos_x + bar->text_shift_x),
|
||||
(i32)(bar->pos_y + bar->text_shift_y),
|
||||
char_color);
|
||||
(i32)(bar->pos_x + bar->text_shift_x),
|
||||
(i32)(bar->pos_y + bar->text_shift_y),
|
||||
char_color);
|
||||
bar->pos_x += font_string_width(target, font_id, str);
|
||||
}
|
||||
|
||||
|
@ -4408,10 +4424,10 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set, K
|
|||
|
||||
inline Single_Line_Input_Step
|
||||
app_single_line_input_step(System_Functions *system, Key_Event_Data key, String *string){
|
||||
Single_Line_Mode mode = {};
|
||||
mode.type = SINGLE_LINE_STRING;
|
||||
mode.string = string;
|
||||
return app_single_line_input_core(system, 0, key, mode);
|
||||
Single_Line_Mode mode = {};
|
||||
mode.type = SINGLE_LINE_STRING;
|
||||
mode.string = string;
|
||||
return app_single_line_input_core(system, 0, key, mode);
|
||||
}
|
||||
|
||||
inline Single_Line_Input_Step
|
||||
|
|
3
TODO.txt
3
TODO.txt
|
@ -76,6 +76,7 @@
|
|||
; [X] killing compilation panel changes active panel
|
||||
; [X] make panel resizing not whacky with child panels
|
||||
; [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
|
||||
; [] 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 after deleting long line
|
||||
;
|
||||
; [] over left-shifting the view?
|
||||
;
|
||||
|
||||
; BEFORE I SHIP
|
||||
;
|
||||
|
|
14
build.cpp
14
build.cpp
|
@ -826,20 +826,20 @@ do_buildsuper(char *cdir){
|
|||
//terminate_with_null(&str);
|
||||
//buildsuper(cdir, BUILD_DIR, str.str);
|
||||
#if defined(IS_WINDOWS)
|
||||
//copy_sc(&str, "../code/internal_4coder_tests.cpp");
|
||||
//terminate_with_null(&str);
|
||||
//buildsuper(cdir, BUILD_DIR, str.str);
|
||||
copy_sc(&str, "../code/power/4coder_casey.cpp");
|
||||
copy_sc(&str, "../code/internal_4coder_tests.cpp");
|
||||
terminate_with_null(&str);
|
||||
buildsuper(cdir, BUILD_DIR, str.str);
|
||||
//copy_sc(&str, "../4vim/4coder_chronal.cpp");
|
||||
//terminate_with_null(&str);
|
||||
//buildsuper(cdir, BUILD_DIR, str.str);
|
||||
#else
|
||||
copy_sc(&str, "../code/power/4coder_experiments.cpp");
|
||||
terminate_with_null(&str);
|
||||
buildsuper(cdir, BUILD_DIR, str.str);
|
||||
#endif
|
||||
//copy_sc(&str, "../code/power/4coder_casey.cpp");
|
||||
//terminate_with_null(&str);
|
||||
//buildsuper(cdir, BUILD_DIR, str.str);
|
||||
//copy_sc(&str, "../4vim/4coder_chronal.cpp");
|
||||
//terminate_with_null(&str);
|
||||
//buildsuper(cdir, BUILD_DIR, str.str);
|
||||
|
||||
END_TIME_SECTION("build custom");
|
||||
}
|
||||
|
|
|
@ -1763,15 +1763,12 @@ This call returns non-zero on success.) */{
|
|||
CPP_NAME(string_set_match)
|
||||
API_EXPORT FSTRING_LINK fstr_bool
|
||||
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 may be an array of any type.
|
||||
It should point at the String in the first element of the array.)
|
||||
DOC_PARAM(count, The item_size parameter should describe the "stride" from one String to the next, in other
|
||||
words it should be the size of one element of the array.)
|
||||
DOC_PARAM(str_set, The str_set parameter may be an array of any type. It should point at the String in the first element of the array.)
|
||||
DOC_PARAM(count, The item_size parameter should describe the "stride" from one String to the next, in other words it should be the size of one element of the array.)
|
||||
DOC_PARAM(count, The count parameter specifies the number of elements 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(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 = 0;
|
||||
int32_t i = 0;
|
||||
|
@ -1792,15 +1789,19 @@ DOC_PARAM(str_set, The str_set parameter is an array of String structs specifyin
|
|||
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(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);
|
||||
}
|
||||
|
||||
API_EXPORT FSTRING_LINK String
|
||||
get_first_double_line(String source){
|
||||
get_first_double_line(String source)/*
|
||||
DOC_PARAM(source, the source string accross which a 'double line' iteration will occur)
|
||||
DOC_RETURN(The returned value is the first 'double line' in the source string.)
|
||||
DOC(A 'double line' is a string of characters delimited by two new line characters. This call begins an iteration over all the double lines in the given source string.)
|
||||
DOC_SEE(get_next_double_line)
|
||||
*/{
|
||||
String line = {0};
|
||||
int32_t pos0 = find_substr_s(source, 0, make_lit_string("\n\n"));
|
||||
int32_t pos1 = find_substr_s(source, 0, make_lit_string("\r\n\r\n"));
|
||||
|
@ -1812,7 +1813,12 @@ get_first_double_line(String source){
|
|||
}
|
||||
|
||||
API_EXPORT FSTRING_LINK String
|
||||
get_next_double_line(String source, String line){
|
||||
get_next_double_line(String source, String line)/*
|
||||
DOC_PARAM(source, the source string accross which the 'double line' iteration is occurring)
|
||||
DOC_PARAM(line, the value returned from the previous call of get_first_double_line or get_next_double_line)
|
||||
DOC_RETURN(The returned value is the first 'double line' in the source string.)
|
||||
DOC_SEE(get_first_double_line)
|
||||
*/{
|
||||
String next = {0};
|
||||
int32_t pos = (int32_t)(line.str - source.str) + line.size;
|
||||
int32_t start = 0, pos0 = 0, pos1 = 0;
|
||||
|
@ -1835,7 +1841,12 @@ get_next_double_line(String source, String line){
|
|||
}
|
||||
|
||||
API_EXPORT FSTRING_LINK String
|
||||
get_next_word(String source, String prev_word){
|
||||
get_next_word(String source, String prev_word)/*
|
||||
DOC_PARAM(source, the source string accross which the 'word' iteration is occurring)
|
||||
DOC_PARAM(line, the value returned from the previous call of get_first_word or get_next_word)
|
||||
DOC_RETURN(The returned value is the first 'word' in the source string.)
|
||||
DOC_SEE(get_first_word)
|
||||
*/{
|
||||
|
||||
String word = {0};
|
||||
int32_t pos0 = (int32_t)(prev_word.str - source.str) + prev_word.size;
|
||||
|
@ -1864,7 +1875,12 @@ get_next_word(String source, String prev_word){
|
|||
}
|
||||
|
||||
API_EXPORT FSTRING_LINK String
|
||||
get_first_word(String source){
|
||||
get_first_word(String source)/*
|
||||
DOC_PARAM(source, the source string accross which a 'word' iteration will occur)
|
||||
DOC_RETURN(The returned value is the first 'word' in the source string.)
|
||||
DOC(A 'word' is a string of characters delimited by whitespace or parentheses. This call begins an iteration over all the double lines in the given source string.)
|
||||
DOC_SEE(get_next_word)
|
||||
*/{
|
||||
String start_str = make_string(source.str, 0);
|
||||
String word = get_next_word(source, start_str);
|
||||
return(word);
|
||||
|
|
Binary file not shown.
|
@ -47,6 +47,21 @@ enum{
|
|||
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{
|
||||
Document_Item *next;
|
||||
Document_Item *parent;
|
||||
|
@ -61,6 +76,8 @@ struct Document_Item{
|
|||
|
||||
struct{
|
||||
Meta_Unit *unit;
|
||||
Alternate_Names_Array *alt_names;
|
||||
int32_t alt_name_type;
|
||||
} unit_elements;
|
||||
|
||||
struct{
|
||||
|
@ -174,6 +191,19 @@ add_element_list(Abstract_Document *doc, Meta_Unit *unit){
|
|||
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
|
||||
add_full_elements(Abstract_Document *doc, Meta_Unit *unit){
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
add_table_of_contents(Abstract_Document *doc){
|
||||
Document_Item *parent = doc->section_stack[doc->section_top];
|
||||
|
@ -253,15 +296,69 @@ struct Section_Counter{
|
|||
};
|
||||
|
||||
static void
|
||||
append_section_number(String *out, Section_Counter section_counter){
|
||||
for (int32_t i = 1; i <= section_counter.nest_level; ++i){
|
||||
append_section_number_reduced(String *out, Section_Counter section_counter, int32_t reduce){
|
||||
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]);
|
||||
if (i != section_counter.nest_level){
|
||||
if (i != level){
|
||||
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
|
||||
write_enriched_text_html(String *out, Enriched_Text *text){
|
||||
String source = text->source;
|
||||
|
@ -300,22 +397,48 @@ write_enriched_text_html(String *out, Enriched_Text *text){
|
|||
make_lit_string("\\"),
|
||||
make_lit_string("VERSION"),
|
||||
make_lit_string("CODE_STYLE"),
|
||||
make_lit_string("DOC_LINK"),
|
||||
};
|
||||
|
||||
i = command_end;
|
||||
|
||||
int32_t match_index = 0;
|
||||
if (string_set_match(enriched_commands, ArrayCount(enriched_commands), command_string, &match_index)){
|
||||
switch (match_index){
|
||||
case 0: append_sc(out, "\\"); 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{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
i = command_end;
|
||||
start = i;
|
||||
}
|
||||
}
|
||||
|
@ -330,8 +453,614 @@ write_enriched_text_html(String *out, Enriched_Text *text){
|
|||
append_sc(out, "</div>");
|
||||
}
|
||||
|
||||
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
|
||||
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, Document_Item *item, Section_Counter section_counter){
|
||||
doc_item_head_html(String *out, Partition *part, Used_Links *used_links, Document_Item *item, Section_Counter section_counter){
|
||||
switch (item->type){
|
||||
case Doc_Root:
|
||||
{
|
||||
|
@ -432,11 +1161,75 @@ doc_item_head_html(String *out, Document_Item *item, Section_Counter section_cou
|
|||
}
|
||||
}break;
|
||||
|
||||
case Doc_Todo:
|
||||
{
|
||||
append_sc(out, "<div><i>Coming Soon</i><div>");
|
||||
}break;
|
||||
|
||||
case Doc_Enriched_Text:
|
||||
{
|
||||
write_enriched_text_html(out, item->text.text);
|
||||
}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:
|
||||
{
|
||||
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
|
||||
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){
|
||||
case Doc_Root:
|
||||
{
|
||||
|
@ -482,9 +1275,9 @@ doc_item_foot_html(String *out, Document_Item *item, Section_Counter section_cou
|
|||
}
|
||||
|
||||
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;
|
||||
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){
|
||||
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;
|
||||
m != 0;
|
||||
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->counter[section_counter->nest_level];
|
||||
}
|
||||
|
||||
doc_item_foot_html(out, item, sc);
|
||||
doc_item_foot_html(out, part, used_links, item, sc);
|
||||
}
|
||||
|
||||
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.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
|
||||
|
|
966
site/sitegen.cpp
966
site/sitegen.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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