fixed several small issues and added a new test for unicode files
parent
30a2a95b69
commit
9e151fd823
File diff suppressed because one or more lines are too long
|
@ -183,78 +183,87 @@ find_anchor_token(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Arra
|
||||||
int32_t line_start, int32_t tab_width, int32_t *current_indent_out){
|
int32_t line_start, int32_t tab_width, int32_t *current_indent_out){
|
||||||
Cpp_Token *token = get_first_token_at_line(app, buffer, tokens, line_start);
|
Cpp_Token *token = get_first_token_at_line(app, buffer, tokens, line_start);
|
||||||
|
|
||||||
if (token != tokens.tokens){
|
if (token == 0 && tokens.count == 0){
|
||||||
--token;
|
// In this case just let the null token pointer be returned.
|
||||||
for (; token > tokens.tokens; --token){
|
}
|
||||||
if (!(token->flags & CPP_TFLAG_PP_BODY)){
|
else{
|
||||||
switch(token->type){
|
if (token == 0){
|
||||||
case CPP_TOKEN_BRACE_OPEN:
|
token = tokens.tokens + (tokens.count - 1);
|
||||||
case CPP_TOKEN_BRACE_CLOSE:
|
}
|
||||||
goto out_of_loop;
|
|
||||||
|
if (token != tokens.tokens){
|
||||||
|
--token;
|
||||||
|
for (; token > tokens.tokens; --token){
|
||||||
|
if (!(token->flags & CPP_TFLAG_PP_BODY)){
|
||||||
|
switch(token->type){
|
||||||
|
case CPP_TOKEN_BRACE_OPEN:
|
||||||
|
case CPP_TOKEN_BRACE_CLOSE:
|
||||||
|
goto out_of_loop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out_of_loop:;
|
||||||
}
|
}
|
||||||
out_of_loop:;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t current_indent = 0;
|
|
||||||
int32_t found_safe_start_position = 0;
|
|
||||||
do{
|
|
||||||
int32_t line = buffer_get_line_index(app, buffer, token->start);
|
|
||||||
int32_t start = buffer_get_line_start(app, buffer, line);
|
|
||||||
|
|
||||||
Hard_Start_Result hard_start = buffer_find_hard_start(app, buffer, start, tab_width);
|
int32_t current_indent = 0;
|
||||||
current_indent = hard_start.indent_pos;
|
int32_t found_safe_start_position = 0;
|
||||||
|
do{
|
||||||
Cpp_Token *start_token = get_first_token_at_line(app, buffer, tokens, line);
|
int32_t line = buffer_get_line_index(app, buffer, token->start);
|
||||||
Cpp_Token *brace_token = token;
|
int32_t start = buffer_get_line_start(app, buffer, line);
|
||||||
|
|
||||||
if (start_token->type == CPP_TOKEN_PARENTHESE_OPEN){
|
Hard_Start_Result hard_start = buffer_find_hard_start(app, buffer, start, tab_width);
|
||||||
if (start_token == tokens.tokens){
|
current_indent = hard_start.indent_pos;
|
||||||
found_safe_start_position = 1;
|
|
||||||
|
Cpp_Token *start_token = get_first_token_at_line(app, buffer, tokens, line);
|
||||||
|
Cpp_Token *brace_token = token;
|
||||||
|
|
||||||
|
if (start_token->type == CPP_TOKEN_PARENTHESE_OPEN){
|
||||||
|
if (start_token == tokens.tokens){
|
||||||
|
found_safe_start_position = 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
token = start_token-1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
token = start_token-1;
|
int32_t close = 0;
|
||||||
}
|
|
||||||
}
|
for (token = brace_token; token > start_token; --token){
|
||||||
else{
|
switch(token->type){
|
||||||
int32_t close = 0;
|
case CPP_TOKEN_PARENTHESE_CLOSE:
|
||||||
|
case CPP_TOKEN_BRACKET_CLOSE:
|
||||||
for (token = brace_token; token > start_token; --token){
|
case CPP_TOKEN_BRACE_CLOSE:
|
||||||
switch(token->type){
|
close = token->type;
|
||||||
|
goto out_of_loop2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out_of_loop2:;
|
||||||
|
|
||||||
|
switch (close){
|
||||||
|
case 0: token = start_token; found_safe_start_position = 1; break;
|
||||||
|
|
||||||
case CPP_TOKEN_PARENTHESE_CLOSE:
|
case CPP_TOKEN_PARENTHESE_CLOSE:
|
||||||
|
token = seek_matching_token_backwards(tokens, token-1,
|
||||||
|
CPP_TOKEN_PARENTHESE_OPEN,
|
||||||
|
CPP_TOKEN_PARENTHESE_CLOSE);
|
||||||
|
break;
|
||||||
|
|
||||||
case CPP_TOKEN_BRACKET_CLOSE:
|
case CPP_TOKEN_BRACKET_CLOSE:
|
||||||
|
token = seek_matching_token_backwards(tokens, token-1,
|
||||||
|
CPP_TOKEN_BRACKET_OPEN,
|
||||||
|
CPP_TOKEN_BRACKET_CLOSE);
|
||||||
|
break;
|
||||||
|
|
||||||
case CPP_TOKEN_BRACE_CLOSE:
|
case CPP_TOKEN_BRACE_CLOSE:
|
||||||
close = token->type;
|
token = seek_matching_token_backwards(tokens, token-1,
|
||||||
goto out_of_loop2;
|
CPP_TOKEN_BRACE_OPEN,
|
||||||
|
CPP_TOKEN_BRACE_CLOSE);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_of_loop2:;
|
} while(found_safe_start_position == 0);
|
||||||
|
*current_indent_out = current_indent;
|
||||||
switch (close){
|
}
|
||||||
case 0: token = start_token; found_safe_start_position = 1; break;
|
|
||||||
|
|
||||||
case CPP_TOKEN_PARENTHESE_CLOSE:
|
|
||||||
token = seek_matching_token_backwards(tokens, token-1,
|
|
||||||
CPP_TOKEN_PARENTHESE_OPEN,
|
|
||||||
CPP_TOKEN_PARENTHESE_CLOSE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPP_TOKEN_BRACKET_CLOSE:
|
|
||||||
token = seek_matching_token_backwards(tokens, token-1,
|
|
||||||
CPP_TOKEN_BRACKET_OPEN,
|
|
||||||
CPP_TOKEN_BRACKET_CLOSE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPP_TOKEN_BRACE_CLOSE:
|
|
||||||
token = seek_matching_token_backwards(tokens, token-1,
|
|
||||||
CPP_TOKEN_BRACE_OPEN,
|
|
||||||
CPP_TOKEN_BRACE_CLOSE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(found_safe_start_position == 0);
|
|
||||||
*current_indent_out = current_indent;
|
|
||||||
|
|
||||||
return(token);
|
return(token);
|
||||||
}
|
}
|
||||||
|
@ -288,186 +297,193 @@ get_indentation_marks(Application_Links *app, Partition *part, Buffer_Summary *b
|
||||||
Cpp_Token *token_ptr = find_anchor_token(app, buffer, tokens, line_start,
|
Cpp_Token *token_ptr = find_anchor_token(app, buffer, tokens, line_start,
|
||||||
tab_width, &indent.current_indent);
|
tab_width, &indent.current_indent);
|
||||||
|
|
||||||
int32_t line_index = buffer_get_line_index(app, buffer, token_ptr->start);
|
if (token_ptr == 0){
|
||||||
|
for (int32_t line_index = line_start; line_index < line_end; ++line_index){
|
||||||
if (line_index > line_start){
|
indent_marks[line_index] = 0;
|
||||||
line_index = line_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t next_line_start_pos = buffer_get_line_start(app, buffer, line_index+1);
|
|
||||||
|
|
||||||
switch (token_ptr->type){
|
|
||||||
case CPP_TOKEN_BRACKET_OPEN: indent.current_indent += tab_width; break;
|
|
||||||
case CPP_TOKEN_BRACE_OPEN: indent.current_indent += tab_width; break;
|
|
||||||
case CPP_TOKEN_PARENTHESE_OPEN: indent.current_indent += tab_width; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
indent.previous_line_indent = indent.current_indent;
|
|
||||||
|
|
||||||
for (;line_index < line_end;){
|
|
||||||
Cpp_Token prev_token = *token_ptr, token = {0};
|
|
||||||
|
|
||||||
++token_ptr;
|
|
||||||
if (token_ptr < tokens.tokens + tokens.count){
|
|
||||||
token = *token_ptr;
|
|
||||||
}
|
}
|
||||||
else{
|
}
|
||||||
token.type = CPP_TOKEN_EOF;
|
else{
|
||||||
token.start = buffer->size;
|
int32_t line_index = buffer_get_line_index(app, buffer, token_ptr->start);
|
||||||
token.flags = 0;
|
|
||||||
|
if (line_index > line_start){
|
||||||
|
line_index = line_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;token.start >= next_line_start_pos && line_index < line_end;){
|
int32_t next_line_start_pos = buffer_get_line_start(app, buffer, line_index+1);
|
||||||
next_line_start_pos = buffer_get_line_start(app, buffer, line_index+1);
|
|
||||||
|
switch (token_ptr->type){
|
||||||
|
case CPP_TOKEN_BRACKET_OPEN: indent.current_indent += tab_width; break;
|
||||||
|
case CPP_TOKEN_BRACE_OPEN: indent.current_indent += tab_width; break;
|
||||||
|
case CPP_TOKEN_PARENTHESE_OPEN: indent.current_indent += tab_width; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
indent.previous_line_indent = indent.current_indent;
|
||||||
|
|
||||||
|
for (;line_index < line_end;){
|
||||||
|
Cpp_Token prev_token = *token_ptr, token = {0};
|
||||||
|
|
||||||
int32_t this_indent = 0;
|
++token_ptr;
|
||||||
{
|
if (token_ptr < tokens.tokens + tokens.count){
|
||||||
int32_t previous_indent = indent.previous_line_indent;
|
token = *token_ptr;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
token.type = CPP_TOKEN_EOF;
|
||||||
|
token.start = buffer->size;
|
||||||
|
token.flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;token.start >= next_line_start_pos && line_index < line_end;){
|
||||||
|
next_line_start_pos = buffer_get_line_start(app, buffer, line_index+1);
|
||||||
|
|
||||||
int32_t this_line_start = buffer_get_line_start(app, buffer, line_index);
|
int32_t this_indent = 0;
|
||||||
int32_t next_line_start = buffer_get_line_start(app, buffer, line_index+1);
|
{
|
||||||
|
int32_t previous_indent = indent.previous_line_indent;
|
||||||
bool32 did_special_behavior = false;
|
|
||||||
|
int32_t this_line_start = buffer_get_line_start(app, buffer, line_index);
|
||||||
if (prev_token.start <= this_line_start && prev_token.start + prev_token.size > this_line_start){
|
int32_t next_line_start = buffer_get_line_start(app, buffer, line_index+1);
|
||||||
if (prev_token.type == CPP_TOKEN_COMMENT){
|
|
||||||
Hard_Start_Result hard_start = buffer_find_hard_start(app, buffer, this_line_start, tab_width);
|
bool32 did_special_behavior = false;
|
||||||
|
|
||||||
if (exact_align){
|
if (prev_token.start <= this_line_start && prev_token.start + prev_token.size > this_line_start){
|
||||||
this_indent = indent.previous_comment_indent;
|
if (prev_token.type == CPP_TOKEN_COMMENT){
|
||||||
}
|
Hard_Start_Result hard_start = buffer_find_hard_start(app, buffer, this_line_start, tab_width);
|
||||||
else{
|
|
||||||
if (hard_start.all_whitespace){
|
if (exact_align){
|
||||||
this_indent = previous_indent;
|
this_indent = indent.previous_comment_indent;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
int32_t line_pos = hard_start.char_pos - this_line_start;
|
if (hard_start.all_whitespace){
|
||||||
this_indent = line_pos + indent.comment_shift;
|
this_indent = previous_indent;
|
||||||
if (this_indent < 0){
|
}
|
||||||
this_indent = 0;
|
else{
|
||||||
|
int32_t line_pos = hard_start.char_pos - this_line_start;
|
||||||
|
this_indent = line_pos + indent.comment_shift;
|
||||||
|
if (this_indent < 0){
|
||||||
|
this_indent = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hard_start.all_whitespace){
|
||||||
|
if (line_index >= line_start){
|
||||||
|
indent.previous_comment_indent = this_indent;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
indent.previous_comment_indent = hard_start.indent_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
did_special_behavior = true;
|
||||||
}
|
}
|
||||||
|
else if (prev_token.type == CPP_TOKEN_STRING_CONSTANT){
|
||||||
if (!hard_start.all_whitespace){
|
this_indent = previous_indent;
|
||||||
if (line_index >= line_start){
|
did_special_behavior = true;
|
||||||
indent.previous_comment_indent = this_indent;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!did_special_behavior){
|
||||||
|
this_indent = indent.current_indent;
|
||||||
|
if (token.start < next_line_start){
|
||||||
|
if (token.flags & CPP_TFLAG_PP_DIRECTIVE){
|
||||||
|
this_indent = 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
indent.previous_comment_indent = hard_start.indent_pos;
|
switch (token.type){
|
||||||
}
|
case CPP_TOKEN_BRACKET_CLOSE: this_indent -= tab_width; break;
|
||||||
}
|
case CPP_TOKEN_BRACE_CLOSE: this_indent -= tab_width; break;
|
||||||
|
case CPP_TOKEN_BRACE_OPEN: break;
|
||||||
did_special_behavior = true;
|
|
||||||
}
|
default:
|
||||||
else if (prev_token.type == CPP_TOKEN_STRING_CONSTANT){
|
if (indent.current_indent > 0){
|
||||||
this_indent = previous_indent;
|
if (!(prev_token.flags & CPP_TFLAG_PP_BODY) &&
|
||||||
did_special_behavior = true;
|
!(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:
|
||||||
if (!did_special_behavior){
|
case CPP_TOKEN_SEMICOLON: case CPP_TOKEN_COLON:
|
||||||
this_indent = indent.current_indent;
|
case CPP_TOKEN_COMMA: case CPP_TOKEN_COMMENT: break;
|
||||||
if (token.start < next_line_start){
|
default: this_indent += tab_width;
|
||||||
if (token.flags & CPP_TFLAG_PP_DIRECTIVE){
|
}
|
||||||
this_indent = 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
switch (token.type){
|
|
||||||
case CPP_TOKEN_BRACKET_CLOSE: this_indent -= tab_width; break;
|
|
||||||
case CPP_TOKEN_BRACE_CLOSE: this_indent -= tab_width; break;
|
|
||||||
case CPP_TOKEN_BRACE_OPEN: break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (indent.current_indent > 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: this_indent += tab_width;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this_indent < 0) this_indent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indent.paren_nesting > 0){
|
||||||
|
if (prev_token.type != CPP_TOKEN_PARENTHESE_OPEN){
|
||||||
|
int32_t level = indent.paren_nesting-1;
|
||||||
|
if (level >= ArrayCount(indent.paren_anchor_indent)){
|
||||||
|
level = ArrayCount(indent.paren_anchor_indent)-1;
|
||||||
|
}
|
||||||
|
this_indent = indent.paren_anchor_indent[level];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this_indent < 0) this_indent = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rebase the paren anchor if the first token
|
||||||
|
// after the open paren is on the next line.
|
||||||
if (indent.paren_nesting > 0){
|
if (indent.paren_nesting > 0){
|
||||||
if (prev_token.type != CPP_TOKEN_PARENTHESE_OPEN){
|
if (prev_token.type == CPP_TOKEN_PARENTHESE_OPEN){
|
||||||
int32_t level = indent.paren_nesting-1;
|
int32_t level = indent.paren_nesting-1;
|
||||||
if (level >= ArrayCount(indent.paren_anchor_indent)){
|
if (level >= ArrayCount(indent.paren_anchor_indent)){
|
||||||
level = ArrayCount(indent.paren_anchor_indent)-1;
|
level = ArrayCount(indent.paren_anchor_indent)-1;
|
||||||
}
|
}
|
||||||
this_indent = indent.paren_anchor_indent[level];
|
indent.paren_anchor_indent[level] = this_indent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Rebase the paren anchor if the first token
|
|
||||||
// after the open paren is on the next line.
|
|
||||||
if (indent.paren_nesting > 0){
|
|
||||||
if (prev_token.type == CPP_TOKEN_PARENTHESE_OPEN){
|
|
||||||
int32_t level = indent.paren_nesting-1;
|
|
||||||
if (level >= ArrayCount(indent.paren_anchor_indent)){
|
|
||||||
level = ArrayCount(indent.paren_anchor_indent)-1;
|
|
||||||
}
|
|
||||||
indent.paren_anchor_indent[level] = this_indent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line_index >= line_start){
|
|
||||||
indent_marks[line_index] = this_indent;
|
|
||||||
}
|
|
||||||
++line_index;
|
|
||||||
|
|
||||||
indent.previous_line_indent = this_indent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update indent state.
|
|
||||||
switch (token.type){
|
|
||||||
case CPP_TOKEN_BRACKET_OPEN: indent.current_indent += 4; break;
|
|
||||||
case CPP_TOKEN_BRACKET_CLOSE: indent.current_indent -= 4; break;
|
|
||||||
case CPP_TOKEN_BRACE_OPEN: indent.current_indent += 4; break;
|
|
||||||
case CPP_TOKEN_BRACE_CLOSE: indent.current_indent -= 4; break;
|
|
||||||
|
|
||||||
case CPP_TOKEN_COMMENT:
|
|
||||||
{
|
|
||||||
int32_t line = buffer_get_line_index(app, buffer, token.start);
|
|
||||||
int32_t start = buffer_get_line_start(app, buffer, line);
|
|
||||||
|
|
||||||
indent.comment_shift = (indent.current_indent - (token.start - start));
|
if (line_index >= line_start){
|
||||||
indent.previous_comment_indent = (token.start - start);
|
indent_marks[line_index] = this_indent;
|
||||||
}break;
|
}
|
||||||
|
++line_index;
|
||||||
|
|
||||||
|
indent.previous_line_indent = this_indent;
|
||||||
|
}
|
||||||
|
|
||||||
case CPP_TOKEN_PARENTHESE_OPEN:
|
// Update indent state.
|
||||||
if (!(token.flags & CPP_TFLAG_PP_BODY)){
|
switch (token.type){
|
||||||
if (indent.paren_nesting < ArrayCount(indent.paren_anchor_indent)){
|
case CPP_TOKEN_BRACKET_OPEN: indent.current_indent += 4; break;
|
||||||
|
case CPP_TOKEN_BRACKET_CLOSE: indent.current_indent -= 4; break;
|
||||||
|
case CPP_TOKEN_BRACE_OPEN: indent.current_indent += 4; break;
|
||||||
|
case CPP_TOKEN_BRACE_CLOSE: indent.current_indent -= 4; break;
|
||||||
|
|
||||||
|
case CPP_TOKEN_COMMENT:
|
||||||
|
{
|
||||||
int32_t line = buffer_get_line_index(app, buffer, token.start);
|
int32_t line = buffer_get_line_index(app, buffer, token.start);
|
||||||
int32_t start = buffer_get_line_start(app, buffer, line);
|
int32_t start = buffer_get_line_start(app, buffer, line);
|
||||||
int32_t char_pos = token.start - start;
|
|
||||||
|
|
||||||
Hard_Start_Result hard_start =
|
indent.comment_shift = (indent.current_indent - (token.start - start));
|
||||||
buffer_find_hard_start(app, buffer, start, tab_width);
|
indent.previous_comment_indent = (token.start - start);
|
||||||
|
}break;
|
||||||
int32_t line_pos = hard_start.char_pos - start;
|
|
||||||
|
case CPP_TOKEN_PARENTHESE_OPEN:
|
||||||
indent.paren_anchor_indent[indent.paren_nesting] =
|
if (!(token.flags & CPP_TFLAG_PP_BODY)){
|
||||||
char_pos - line_pos + indent.previous_line_indent + 1;
|
if (indent.paren_nesting < ArrayCount(indent.paren_anchor_indent)){
|
||||||
|
int32_t line = buffer_get_line_index(app, buffer, token.start);
|
||||||
|
int32_t start = buffer_get_line_start(app, buffer, line);
|
||||||
|
int32_t char_pos = token.start - start;
|
||||||
|
|
||||||
|
Hard_Start_Result hard_start =
|
||||||
|
buffer_find_hard_start(app, buffer, start, tab_width);
|
||||||
|
|
||||||
|
int32_t line_pos = hard_start.char_pos - start;
|
||||||
|
|
||||||
|
indent.paren_anchor_indent[indent.paren_nesting] =
|
||||||
|
char_pos - line_pos + indent.previous_line_indent + 1;
|
||||||
|
}
|
||||||
|
++indent.paren_nesting;
|
||||||
}
|
}
|
||||||
++indent.paren_nesting;
|
break;
|
||||||
|
|
||||||
|
case CPP_TOKEN_PARENTHESE_CLOSE:
|
||||||
|
if (!(token.flags & CPP_TFLAG_PP_BODY)){
|
||||||
|
--indent.paren_nesting;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case CPP_TOKEN_PARENTHESE_CLOSE:
|
|
||||||
if (!(token.flags & CPP_TFLAG_PP_BODY)){
|
|
||||||
--indent.paren_nesting;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -556,7 +556,7 @@ static int32_t
|
||||||
buffer_get_line_start(Application_Links *app, Buffer_Summary *buffer, int32_t line){
|
buffer_get_line_start(Application_Links *app, Buffer_Summary *buffer, int32_t line){
|
||||||
Partial_Cursor partial_cursor;
|
Partial_Cursor partial_cursor;
|
||||||
int32_t result = buffer->size;
|
int32_t result = buffer->size;
|
||||||
if (line < buffer->line_count){
|
if (line <= buffer->line_count){
|
||||||
app->buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &partial_cursor);
|
app->buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &partial_cursor);
|
||||||
result = partial_cursor.pos;
|
result = partial_cursor.pos;
|
||||||
}
|
}
|
||||||
|
@ -1676,7 +1676,7 @@ seek_token_left(Cpp_Token_Array *tokens, int32_t pos){
|
||||||
--token;
|
--token;
|
||||||
}
|
}
|
||||||
|
|
||||||
return token->start;
|
return(token->start);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
|
@ -1690,27 +1690,45 @@ seek_token_right(Cpp_Token_Array *tokens, int32_t pos){
|
||||||
}
|
}
|
||||||
|
|
||||||
Cpp_Token *token = tokens->tokens + get.token_index;
|
Cpp_Token *token = tokens->tokens + get.token_index;
|
||||||
return token->start + token->size;
|
return(token->start + token->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Cpp_Token_Array
|
||||||
|
buffer_get_all_tokens(Application_Links *app, Partition *part, Buffer_Summary *buffer){
|
||||||
|
Cpp_Token_Array array = {0};
|
||||||
|
|
||||||
|
if (buffer->exists && buffer->is_lexed){
|
||||||
|
array.count = app->buffer_token_count(app, buffer);
|
||||||
|
array.max_count = array.count;
|
||||||
|
array.tokens = push_array(part, Cpp_Token, array.count);
|
||||||
|
app->buffer_read_tokens(app, buffer, 0, array.count, array.tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
buffer_boundary_seek(Application_Links *app, Buffer_Summary *buffer, int32_t start_pos,
|
buffer_boundary_seek(Application_Links *app, Buffer_Summary *buffer, Partition *part,
|
||||||
bool32 seek_forward, Seek_Boundary_Flag flags)/*
|
int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags)/*
|
||||||
DOC_PARAM(buffer, The buffer parameter specifies the buffer through which to seek.)
|
DOC_PARAM(buffer, The buffer parameter specifies the buffer through which to seek.)
|
||||||
DOC_PARAM(start_pos, The beginning position of the seek is specified by start_pos measured in absolute position.)
|
DOC_PARAM(start_pos, The beginning position of the seek is specified by start_pos measured in absolute position.)
|
||||||
DOC_PARAM(seek_forward, If this parameter is non-zero it indicates that the seek should move foward through the buffer.)
|
DOC_PARAM(seek_forward, If this parameter is non-zero it indicates that the seek should move foward through the buffer.)
|
||||||
DOC_PARAM(flags, This field specifies the types of boundaries at which the seek should stop.)
|
DOC_PARAM(flags, This field specifies the types of boundaries at which the seek should stop.)
|
||||||
|
|
||||||
DOC_RETURN(This call returns the absolute position where the seek stopped.
|
DOC_RETURN(This call returns the absolute position where the seek stopped.
|
||||||
If the seek goes below 0 the returned value is -1.
|
If the seek goes below 0 the returned value is -1.
|
||||||
If the seek goes past the end the returned value is the size of the buffer.)
|
If the seek goes past the end the returned value is the size of the buffer.)
|
||||||
|
|
||||||
DOC_SEE(Seek_Boundary_Flag)
|
DOC_SEE(Seek_Boundary_Flag)
|
||||||
DOC_SEE(4coder_Buffer_Positioning_System)
|
DOC_SEE(4coder_Buffer_Positioning_System)
|
||||||
*/{
|
*/{
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
|
|
||||||
|
// TODO(allen): reduce duplication?
|
||||||
|
Temp_Memory temp = begin_temp_memory(part);
|
||||||
if (buffer->exists){
|
if (buffer->exists){
|
||||||
// TODO(allen): reduce duplication?
|
int32_t pos[4];
|
||||||
int32_t size = buffer->size;
|
int32_t size = buffer->size;
|
||||||
int32_t pos[4] = {0};
|
|
||||||
int32_t new_pos = 0;
|
int32_t new_pos = 0;
|
||||||
|
|
||||||
if (start_pos < 0){
|
if (start_pos < 0){
|
||||||
|
@ -1721,16 +1739,17 @@ DOC_SEE(4coder_Buffer_Positioning_System)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seek_forward){
|
if (seek_forward){
|
||||||
for (int32_t i = 0; i < ArrayCount(pos); ++i) pos[i] = size;
|
for (int32_t i = 0; i < ArrayCount(pos); ++i){
|
||||||
|
pos[i] = size;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & (1)){
|
if (flags & BoundaryWhitespace){
|
||||||
pos[0] = buffer_seek_whitespace_right(app, buffer, start_pos);
|
pos[0] = buffer_seek_whitespace_right(app, buffer, start_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & (1 << 1)){
|
if (flags & BoundaryToken){
|
||||||
if (buffer->tokens_are_ready){
|
if (buffer->tokens_are_ready){
|
||||||
Cpp_Token_Array array;
|
Cpp_Token_Array array = buffer_get_all_tokens(app, part, buffer);
|
||||||
// TODO(allen): Fill this array.
|
|
||||||
pos[1] = seek_token_right(&array, start_pos);
|
pos[1] = seek_token_right(&array, start_pos);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -1738,32 +1757,37 @@ DOC_SEE(4coder_Buffer_Positioning_System)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & (1 << 2)){
|
if (flags & BoundaryAlphanumeric){
|
||||||
pos[2] = buffer_seek_alphanumeric_right(app, buffer, start_pos);
|
pos[2] = buffer_seek_alphanumeric_right(app, buffer, start_pos);
|
||||||
if (flags & (1 << 3)){
|
if (flags & BoundaryCamelCase){
|
||||||
pos[3] = buffer_seek_range_camel_right(app, buffer, start_pos, pos[2]);
|
pos[3] = buffer_seek_range_camel_right(app, buffer, start_pos, pos[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (flags & (1 << 3)){
|
if (flags & BoundaryCamelCase){
|
||||||
pos[3] = buffer_seek_alphanumeric_or_camel_right(app, buffer, start_pos);
|
pos[3] = buffer_seek_alphanumeric_or_camel_right(app, buffer, start_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_pos = size;
|
new_pos = size;
|
||||||
for (int32_t i = 0; i < ArrayCount(pos); ++i){
|
for (int32_t i = 0; i < ArrayCount(pos); ++i){
|
||||||
if (pos[i] < new_pos) new_pos = pos[i];
|
if (pos[i] < new_pos){
|
||||||
|
new_pos = pos[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (flags & (1)){
|
for (int32_t i = 0; i < ArrayCount(pos); ++i){
|
||||||
|
pos[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & BoundaryWhitespace){
|
||||||
pos[0] = buffer_seek_whitespace_left(app, buffer, start_pos);
|
pos[0] = buffer_seek_whitespace_left(app, buffer, start_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & (1 << 1)){
|
if (flags & BoundaryToken){
|
||||||
if (buffer->tokens_are_ready){
|
if (buffer->tokens_are_ready){
|
||||||
Cpp_Token_Array array;
|
Cpp_Token_Array array = buffer_get_all_tokens(app, part, buffer);
|
||||||
// TODO(allen): Fill this array.
|
|
||||||
pos[1] = seek_token_left(&array, start_pos);
|
pos[1] = seek_token_left(&array, start_pos);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -1771,29 +1795,39 @@ DOC_SEE(4coder_Buffer_Positioning_System)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & (1 << 2)){
|
if (flags & BoundaryAlphanumeric){
|
||||||
pos[2] = buffer_seek_alphanumeric_left(app, buffer, start_pos);
|
pos[2] = buffer_seek_alphanumeric_left(app, buffer, start_pos);
|
||||||
if (flags & (1 << 3)){
|
if (flags & BoundaryCamelCase){
|
||||||
pos[3] = buffer_seek_range_camel_left(app, buffer, start_pos, pos[2]);
|
pos[3] = buffer_seek_range_camel_left(app, buffer, start_pos, pos[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (flags & (1 << 3)){
|
if (flags & BoundaryCamelCase){
|
||||||
pos[3] = buffer_seek_alphanumeric_or_camel_left(app, buffer, start_pos);
|
pos[3] = buffer_seek_alphanumeric_or_camel_left(app, buffer, start_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_pos = 0;
|
new_pos = 0;
|
||||||
for (int32_t i = 0; i < ArrayCount(pos); ++i){
|
for (int32_t i = 0; i < ArrayCount(pos); ++i){
|
||||||
if (pos[i] > new_pos) new_pos = pos[i];
|
if (pos[i] > new_pos){
|
||||||
|
new_pos = pos[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = new_pos;
|
result = new_pos;
|
||||||
}
|
}
|
||||||
|
end_temp_memory(temp);
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t
|
||||||
|
buffer_boundary_seek(Application_Links *app, Buffer_Summary *buffer,
|
||||||
|
int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags){
|
||||||
|
int32_t result = buffer_boundary_seek(app, buffer, &global_part, start_pos, seek_forward, flags);
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
basic_seek(Application_Links *app, int32_t seek_type, uint32_t flags){
|
basic_seek(Application_Links *app, int32_t seek_type, uint32_t flags){
|
||||||
uint32_t access = AccessProtected;
|
uint32_t access = AccessProtected;
|
||||||
|
|
|
@ -297,11 +297,11 @@ ENUM(uint32_t, Input_Type_Flag){
|
||||||
EventOnRightButton = 0x8,
|
EventOnRightButton = 0x8,
|
||||||
/* DOC(If EventOnWheel is set, any wheel movement is included in the set.) */
|
/* DOC(If EventOnWheel is set, any wheel movement is included in the set.) */
|
||||||
EventOnWheel = 0x10,
|
EventOnWheel = 0x10,
|
||||||
/* DOC(If EventOnButton is set, all mouse button events are included in the set.) */
|
|
||||||
EventOnButton = (EventOnLeftButton | EventOnRightButton | EventOnWheel),
|
|
||||||
|
|
||||||
/* DOC(This is not totally implemented yet.) */
|
/* DOC(This is not totally implemented yet.) */
|
||||||
EventOnMouseMove = 0x20,
|
EventOnMouseMove = 0x20,
|
||||||
|
|
||||||
|
/* DOC(If EventOnButton is set, all mouse button events are included in the set.) */
|
||||||
|
EventOnButton = (EventOnLeftButton | EventOnRightButton | EventOnWheel),
|
||||||
/* DOC(This is not totally implemented yet.) */
|
/* DOC(This is not totally implemented yet.) */
|
||||||
EventOnMouse = (EventOnButton | EventOnMouseMove),
|
EventOnMouse = (EventOnButton | EventOnMouseMove),
|
||||||
|
|
||||||
|
@ -587,21 +587,15 @@ struct Buffer_Edit{
|
||||||
DOC_SEE(Access_Flag)
|
DOC_SEE(Access_Flag)
|
||||||
DOC_SEE(Dirty_State) */
|
DOC_SEE(Dirty_State) */
|
||||||
struct Buffer_Summary{
|
struct Buffer_Summary{
|
||||||
/* DOC(
|
/* DOC(This field indicates whether the Buffer_Summary describes a buffer that is open in 4coder.
|
||||||
This field indicates whether the Buffer_Summary describes a buffer that is open in 4coder.
|
When this field is false the summary is referred to as a "null summary".) */
|
||||||
When this field is false the summary is referred to as a "null summary".
|
|
||||||
) */
|
|
||||||
bool32 exists;
|
bool32 exists;
|
||||||
/* DOC(If this is not a null summary, this field indicates whether the buffer has finished loading.) */
|
/* DOC(If this is not a null summary, this field indicates whether the buffer has finished loading.) */
|
||||||
bool32 ready;
|
bool32 ready;
|
||||||
/* DOC(
|
/* DOC(If this is not a null summary this field is the id of the associated buffer.
|
||||||
If this is not a null summary this field is the id of the associated buffer.
|
If this is a null summary then buffer_id is 0.) */
|
||||||
If this is a null summary then buffer_id is 0.
|
|
||||||
) */
|
|
||||||
int32_t buffer_id;
|
int32_t buffer_id;
|
||||||
/*
|
/*DOC(If this is not a null summary, this field contains flags describing the protection status of the buffer.)*/
|
||||||
DOC(If this is not a null summary, this field contains flags describing the protection status of the buffer.)
|
|
||||||
*/
|
|
||||||
Access_Flag lock_flags;
|
Access_Flag lock_flags;
|
||||||
|
|
||||||
/* DOC(If this is not a null summary, this field specifies the size of the text in the buffer.) */
|
/* DOC(If this is not a null summary, this field specifies the size of the text in the buffer.) */
|
||||||
|
|
|
@ -288,7 +288,7 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz
|
||||||
int32_t token_i = token_array_out->count;
|
int32_t token_i = token_array_out->count;
|
||||||
int32_t max_token_i = token_array_out->max_count;
|
int32_t max_token_i = token_array_out->max_count;
|
||||||
|
|
||||||
char c = 0;
|
uint8_t c = 0;
|
||||||
|
|
||||||
int32_t end_pos = size + S.chunk_pos;
|
int32_t end_pos = size + S.chunk_pos;
|
||||||
chunk -= S.chunk_pos;
|
chunk -= S.chunk_pos;
|
||||||
|
@ -330,8 +330,8 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz
|
||||||
S.fsm = null_lex_fsm;
|
S.fsm = null_lex_fsm;
|
||||||
for(;;){
|
for(;;){
|
||||||
{
|
{
|
||||||
unsigned short *eq_classes = get_eq_classes[S.pp_state];
|
uint16_t *eq_classes = get_eq_classes[S.pp_state];
|
||||||
unsigned char *fsm_table = get_table[S.pp_state];
|
uint8_t *fsm_table = get_table[S.pp_state];
|
||||||
|
|
||||||
for (; S.fsm.state < LS_count && S.pos < end_pos;){
|
for (; S.fsm.state < LS_count && S.pos < end_pos;){
|
||||||
c = chunk[S.pos++];
|
c = chunk[S.pos++];
|
||||||
|
@ -489,7 +489,7 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz
|
||||||
String_And_Flag data = preprops[sub_match];
|
String_And_Flag data = preprops[sub_match];
|
||||||
S.token.type = (Cpp_Token_Type)data.flags;
|
S.token.type = (Cpp_Token_Type)data.flags;
|
||||||
S.token.flags = CPP_TFLAG_PP_DIRECTIVE;
|
S.token.flags = CPP_TFLAG_PP_DIRECTIVE;
|
||||||
S.pp_state = (unsigned char)cpp_pp_directive_to_state(S.token.type);
|
S.pp_state = (uint8_t)cpp_pp_directive_to_state(S.token.type);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
S.token.type = CPP_TOKEN_JUNK;
|
S.token.type = CPP_TOKEN_JUNK;
|
||||||
|
|
|
@ -77,12 +77,6 @@ CUSTOM_COMMAND_SIG(reopen_test){
|
||||||
//TEST_TIME_E();
|
//TEST_TIME_E();
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(run_all_tests){
|
|
||||||
exec_command(app, load_lots_of_files);
|
|
||||||
exec_command(app, reopen_test);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
CUSTOM_COMMAND_SIG(generate_stop_spots_test_data){
|
CUSTOM_COMMAND_SIG(generate_stop_spots_test_data){
|
||||||
Buffer_Summary buffer = app->create_buffer(app, literal(LOTS_OF_FILES "/4ed.cpp"), 0);
|
Buffer_Summary buffer = app->create_buffer(app, literal(LOTS_OF_FILES "/4ed.cpp"), 0);
|
||||||
View_Summary view = app->get_active_view(app, AccessAll);
|
View_Summary view = app->get_active_view(app, AccessAll);
|
||||||
|
@ -97,6 +91,18 @@ CUSTOM_COMMAND_SIG(generate_stop_spots_test_data){
|
||||||
app->buffer_compute_cursor(app, &buffer, seek_line_char(316, 29), &curs);
|
app->buffer_compute_cursor(app, &buffer, seek_line_char(316, 29), &curs);
|
||||||
fwrite(&curs.pos, 4, 1, file);
|
fwrite(&curs.pos, 4, 1, file);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 10; ++i){
|
||||||
|
Query_Bar bar = {0};
|
||||||
|
bar.prompt = make_lit_string("Do something to continue the test");
|
||||||
|
if (app->start_query_bar(app, &bar, 0)){
|
||||||
|
app->get_user_input(app, EventAll, EventAll);
|
||||||
|
}
|
||||||
|
refresh_buffer(app, &buffer);
|
||||||
|
if (buffer.tokens_are_ready){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Seek_Boundary_Flag flag_set[] = {
|
static Seek_Boundary_Flag flag_set[] = {
|
||||||
BoundaryWhitespace,
|
BoundaryWhitespace,
|
||||||
BoundaryToken,
|
BoundaryToken,
|
||||||
|
@ -111,7 +117,7 @@ CUSTOM_COMMAND_SIG(generate_stop_spots_test_data){
|
||||||
for (int32_t seek_forward = 0; seek_forward <= 1; ++seek_forward){
|
for (int32_t seek_forward = 0; seek_forward <= 1; ++seek_forward){
|
||||||
pos = curs.pos;
|
pos = curs.pos;
|
||||||
for (int32_t i = 0; i < 100; ++i){
|
for (int32_t i = 0; i < 100; ++i){
|
||||||
pos = app->buffer_boundary_seek(app, &buffer, pos, seek_forward, flag_set[flag_i]);
|
pos = buffer_boundary_seek(app, &buffer, pos, seek_forward, flag_set[flag_i]);
|
||||||
fwrite(&pos, 4, 1, file);
|
fwrite(&pos, 4, 1, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +126,6 @@ CUSTOM_COMMAND_SIG(generate_stop_spots_test_data){
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fcheck(int32_t x, FILE *file){
|
fcheck(int32_t x, FILE *file){
|
||||||
|
@ -143,6 +148,18 @@ CUSTOM_COMMAND_SIG(stop_spots_test){
|
||||||
app->buffer_compute_cursor(app, &buffer, seek_line_char(316, 29), &curs);
|
app->buffer_compute_cursor(app, &buffer, seek_line_char(316, 29), &curs);
|
||||||
fcheck(curs.pos, file);
|
fcheck(curs.pos, file);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 10; ++i){
|
||||||
|
Query_Bar bar = {0};
|
||||||
|
bar.prompt = make_lit_string("Do something to continue the test");
|
||||||
|
if (app->start_query_bar(app, &bar, 0)){
|
||||||
|
app->get_user_input(app, EventAll, EventAll);
|
||||||
|
}
|
||||||
|
refresh_buffer(app, &buffer);
|
||||||
|
if (buffer.tokens_are_ready){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Seek_Boundary_Flag flag_set[] = {
|
static Seek_Boundary_Flag flag_set[] = {
|
||||||
BoundaryWhitespace,
|
BoundaryWhitespace,
|
||||||
BoundaryToken,
|
BoundaryToken,
|
||||||
|
@ -167,13 +184,25 @@ CUSTOM_COMMAND_SIG(stop_spots_test){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(load_unicode_file){
|
||||||
|
Buffer_Summary buffer = app->create_buffer(app, literal(TEST_FILES "/mod_markov.c"), 0);
|
||||||
|
View_Summary view = app->get_active_view(app, AccessAll);
|
||||||
|
app->view_set_buffer(app, &view, buffer.buffer_id, 0);
|
||||||
|
|
||||||
|
app->view_set_cursor(app, &view, seek_line_char(230, 25), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(run_all_tests){
|
||||||
|
exec_command(app, load_lots_of_files);
|
||||||
|
exec_command(app, reopen_test);
|
||||||
|
exec_command(app, stop_spots_test);
|
||||||
|
exec_command(app, load_unicode_file);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_get_bindings(Bind_Helper *context){
|
test_get_bindings(Bind_Helper *context){
|
||||||
begin_map(context, mapid_global);
|
begin_map(context, mapid_global);
|
||||||
|
bind(context, key_f3, MDFR_NONE, run_all_tests);
|
||||||
//bind(context, key_f3, MDFR_NONE, run_all_tests);
|
|
||||||
bind(context, key_f3, MDFR_NONE, stop_spots_test);
|
|
||||||
|
|
||||||
end_map(context);
|
end_map(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue