switched buffer_boundary_seek over to custom code

This commit is contained in:
Allen Webster 2016-09-08 18:03:43 -04:00
parent bdd893438d
commit 431d80a8b8
9 changed files with 585 additions and 684 deletions

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,6 @@
#define GET_BUFFER_NEXT_SIG(n) void n(Application_Links *app, Buffer_Summary *buffer, Access_Flag access)
#define GET_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, Buffer_ID buffer_id, Access_Flag access)
#define GET_BUFFER_BY_NAME_SIG(n) Buffer_Summary n(Application_Links *app, char *name, int32_t len, Access_Flag access)
#define BUFFER_BOUNDARY_SEEK_SIG(n) int32_t n(Application_Links *app, Buffer_Summary *buffer, int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags)
#define BUFFER_READ_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *out)
#define BUFFER_REPLACE_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len)
#define BUFFER_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out)
@ -69,7 +68,6 @@ typedef GET_BUFFER_FIRST_SIG(Get_Buffer_First_Function);
typedef GET_BUFFER_NEXT_SIG(Get_Buffer_Next_Function);
typedef GET_BUFFER_SIG(Get_Buffer_Function);
typedef GET_BUFFER_BY_NAME_SIG(Get_Buffer_By_Name_Function);
typedef BUFFER_BOUNDARY_SEEK_SIG(Buffer_Boundary_Seek_Function);
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
@ -131,7 +129,6 @@ Get_Buffer_First_Function *get_buffer_first;
Get_Buffer_Next_Function *get_buffer_next;
Get_Buffer_Function *get_buffer;
Get_Buffer_By_Name_Function *get_buffer_by_name;
Buffer_Boundary_Seek_Function *buffer_boundary_seek;
Buffer_Read_Range_Function *buffer_read_range;
Buffer_Replace_Range_Function *buffer_replace_range;
Buffer_Compute_Cursor_Function *buffer_compute_cursor;
@ -200,7 +197,6 @@ app_links->get_buffer_first = Get_Buffer_First;\
app_links->get_buffer_next = Get_Buffer_Next;\
app_links->get_buffer = Get_Buffer;\
app_links->get_buffer_by_name = Get_Buffer_By_Name;\
app_links->buffer_boundary_seek = Buffer_Boundary_Seek;\
app_links->buffer_read_range = Buffer_Read_Range;\
app_links->buffer_replace_range = Buffer_Replace_Range;\
app_links->buffer_compute_cursor = Buffer_Compute_Cursor;\

View File

@ -1375,12 +1375,376 @@ CUSTOM_COMMAND_SIG(seek_beginning_of_line){
app->view_set_cursor(app, &view, seek_pos(new_pos), true);
}
// TODO(allen): REDUCE DUPLICATION!
static int32_t
buffer_seek_whitespace_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos){
char data_chunk[1024];
Stream_Chunk stream = {0};
if (init_stream_chunk(&stream, app, buffer,
pos, data_chunk, sizeof(data_chunk))){
bool32 still_looping = 1;
do{
for (; pos < stream.end; ++pos){
if (!char_is_whitespace(stream.data[pos])){
goto double_break1;
}
}
still_looping = forward_stream_chunk(&stream);
}while(still_looping);
double_break1:;
still_looping = 1;
do{
for (; pos < stream.end; ++pos){
if (char_is_whitespace(stream.data[pos])){
goto double_break2;
}
}
still_looping = forward_stream_chunk(&stream);
}while(still_looping);
double_break2:;
}
return(pos);
}
static int32_t
buffer_seek_whitespace_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos){
char data_chunk[1024];
Stream_Chunk stream = {0};
--pos;
if (pos > 0){
if (init_stream_chunk(&stream, app, buffer,
pos, data_chunk, sizeof(data_chunk))){
bool32 still_looping = 1;
do{
for (; pos >= stream.start; --pos){
if (!char_is_whitespace(stream.data[pos])){
goto double_break1;
}
}
still_looping = backward_stream_chunk(&stream);
}while(still_looping);
double_break1:;
still_looping = 1;
do{
for (; pos >= stream.start; --pos){
if (char_is_whitespace(stream.data[pos])){
++pos;
goto double_break2;
}
}
still_looping = backward_stream_chunk(&stream);
}while(still_looping);
double_break2:;
}
}
else{
pos = 0;
}
return(pos);
}
static int32_t
buffer_seek_alphanumeric_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos){
char data_chunk[1024];
Stream_Chunk stream = {0};
if (init_stream_chunk(&stream, app, buffer,
pos, data_chunk, sizeof(data_chunk))){
bool32 still_looping = 1;
do{
for (; pos < stream.end; ++pos){
if (char_is_alpha_numeric_true(stream.data[pos])){
goto double_break1;
}
}
still_looping = forward_stream_chunk(&stream);
}while(still_looping);
double_break1:;
still_looping = 1;
do{
for (; pos < stream.end; ++pos){
if (!char_is_alpha_numeric_true(stream.data[pos])){
goto double_break2;
}
}
still_looping = forward_stream_chunk(&stream);
}while(still_looping);
double_break2:;
}
return(pos);
}
static int32_t
buffer_seek_alphanumeric_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos){
char data_chunk[1024];
Stream_Chunk stream = {0};
--pos;
if (pos > 0){
if (init_stream_chunk(&stream, app, buffer,
pos, data_chunk, sizeof(data_chunk))){
bool32 still_looping = 1;
do{
for (; pos >= stream.start; --pos){
if (char_is_alpha_numeric_true(stream.data[pos])){
goto double_break1;
}
}
still_looping = backward_stream_chunk(&stream);
}while(still_looping);
double_break1:;
still_looping = 1;
do{
for (; pos >= stream.start; --pos){
if (!char_is_alpha_numeric_true(stream.data[pos])){
++pos;
goto double_break2;
}
}
still_looping = backward_stream_chunk(&stream);
}while(still_looping);
double_break2:;
}
}
else{
pos = 0;
}
return(pos);
}
static int32_t
buffer_seek_range_camel_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t an_pos){
char data_chunk[1024];
Stream_Chunk stream = {0};
++pos;
if (pos < an_pos){
stream.max_end = an_pos;
if (init_stream_chunk(&stream, app, buffer,
pos, data_chunk, sizeof(data_chunk))){
char c = 0, pc = stream.data[pos];
++pos;
bool32 still_looping = 1;
do{
for (; pos < stream.end; ++pos){
c = stream.data[pos];
if (char_is_upper(c) && char_is_lower(pc)){
goto double_break1;
}
pc = c;
}
still_looping = forward_stream_chunk(&stream);
}while(still_looping);
double_break1:;
}
}
else{
pos = an_pos;
}
return(pos);
}
static int32_t
buffer_seek_range_camel_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t an_pos){
char data_chunk[1024];
Stream_Chunk stream = {0};
--pos;
if (pos > 0){
stream.min_start = an_pos+1;
if (init_stream_chunk(&stream, app, buffer,
pos, data_chunk, sizeof(data_chunk))){
char c = 0, pc = stream.data[pos];
bool32 still_looping = 1;
do{
for (; pos >= stream.start; --pos){
c = stream.data[pos];
if (char_is_upper(c) && char_is_lower(pc)){
goto double_break1;
}
pc = c;
}
still_looping = backward_stream_chunk(&stream);
}while(still_looping);
double_break1:;
}
}
else{
pos = 0;
}
return(pos);
}
static int32_t
buffer_seek_alphanumeric_or_camel_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos){
int32_t an_pos = buffer_seek_alphanumeric_right(app, buffer, pos);
int32_t result = buffer_seek_range_camel_right(app, buffer, pos, an_pos);
return(result);
}
static int32_t
buffer_seek_alphanumeric_or_camel_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos){
int32_t an_pos = buffer_seek_alphanumeric_left(app, buffer, pos);
int32_t result = buffer_seek_range_camel_left(app, buffer, pos, an_pos);
return(result);
}
static int32_t
seek_token_left(Cpp_Token_Array *tokens, int32_t pos){
Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
if (get.token_index == -1){
get.token_index = 0;
}
Cpp_Token *token = tokens->tokens + get.token_index;
if (token->start == pos && get.token_index > 0){
--token;
}
return token->start;
}
static int32_t
seek_token_right(Cpp_Token_Array *tokens, int32_t pos){
Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
if (get.in_whitespace){
++get.token_index;
}
if (get.token_index >= tokens->count){
get.token_index = tokens->count-1;
}
Cpp_Token *token = tokens->tokens + get.token_index;
return token->start + token->size;
}
static int32_t
buffer_boundary_seek(Application_Links *app, Buffer_Summary *buffer, 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(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(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.
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.)
DOC_SEE(Seek_Boundary_Flag)
DOC_SEE(4coder_Buffer_Positioning_System)
*/{
int32_t result = 0;
if (buffer->exists){
// TODO(allen): reduce duplication?
int32_t size = buffer->size;
int32_t pos[4] = {0};
int32_t new_pos = 0;
if (start_pos < 0){
start_pos = 0;
}
else if (start_pos > size){
start_pos = size;
}
if (seek_forward){
for (int32_t i = 0; i < ArrayCount(pos); ++i) pos[i] = size;
if (flags & (1)){
pos[0] = buffer_seek_whitespace_right(app, buffer, start_pos);
}
if (flags & (1 << 1)){
if (buffer->tokens_are_ready){
Cpp_Token_Array array;
// TODO(allen): Fill this array.
pos[1] = seek_token_right(&array, start_pos);
}
else{
pos[1] = buffer_seek_whitespace_right(app, buffer, start_pos);
}
}
if (flags & (1 << 2)){
pos[2] = buffer_seek_alphanumeric_right(app, buffer, start_pos);
if (flags & (1 << 3)){
pos[3] = buffer_seek_range_camel_right(app, buffer, start_pos, pos[2]);
}
}
else{
if (flags & (1 << 3)){
pos[3] = buffer_seek_alphanumeric_or_camel_right(app, buffer, start_pos);
}
}
new_pos = size;
for (int32_t i = 0; i < ArrayCount(pos); ++i){
if (pos[i] < new_pos) new_pos = pos[i];
}
}
else{
if (flags & (1)){
pos[0] = buffer_seek_whitespace_left(app, buffer, start_pos);
}
if (flags & (1 << 1)){
if (buffer->tokens_are_ready){
Cpp_Token_Array array;
// TODO(allen): Fill this array.
pos[1] = seek_token_left(&array, start_pos);
}
else{
pos[1] = buffer_seek_whitespace_left(app, buffer, start_pos);
}
}
if (flags & (1 << 2)){
pos[2] = buffer_seek_alphanumeric_left(app, buffer, start_pos);
if (flags & (1 << 3)){
pos[3] = buffer_seek_range_camel_left(app, buffer, start_pos, pos[2]);
}
}
else{
if (flags & (1 << 3)){
pos[3] = buffer_seek_alphanumeric_or_camel_left(app, buffer, start_pos);
}
}
new_pos = 0;
for (int32_t i = 0; i < ArrayCount(pos); ++i){
if (pos[i] > new_pos) new_pos = pos[i];
}
}
result = new_pos;
}
return(result);
}
static void
basic_seek(Application_Links *app, int32_t seek_type, uint32_t flags){
uint32_t access = AccessProtected;
View_Summary view = app->get_active_view(app, access);
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, access);
int32_t pos = app->buffer_boundary_seek(app, &buffer, view.cursor.pos, seek_type, flags);
int32_t pos = buffer_boundary_seek(app, &buffer, view.cursor.pos, seek_type, flags);
app->view_set_cursor(app, &view, seek_pos(pos), true);
}
@ -1567,8 +1931,8 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word){
view = app->get_active_view(app, access);
buffer = app->get_buffer(app, view.buffer_id, access);
pos1 = app->buffer_boundary_seek(app, &buffer, view.cursor.pos, false, BoundaryToken | BoundaryWhitespace);
pos2 = app->buffer_boundary_seek(app, &buffer, pos1, true, BoundaryToken | BoundaryWhitespace);
pos1 = buffer_boundary_seek(app, &buffer, view.cursor.pos, false, BoundaryToken | BoundaryWhitespace);
pos2 = buffer_boundary_seek(app, &buffer, pos1, true, BoundaryToken | BoundaryWhitespace);
Range range = make_range(pos1, pos2);
app->buffer_replace_range(app, &buffer, range.start, range.end, 0, 0);

View File

@ -48,6 +48,8 @@ typedef struct Offset_String{
#define FCODER_STRING_H
FSTRING_INLINE fstr_bool char_is_slash(char c);
FSTRING_INLINE fstr_bool char_is_upper(char c);
FSTRING_INLINE fstr_bool char_is_lower(char c);
FSTRING_INLINE char char_to_upper(char c);
FSTRING_INLINE char char_to_lower(char c);
FSTRING_INLINE fstr_bool char_is_whitespace(char c);
@ -261,6 +263,22 @@ char_is_slash(char c)
}
#endif
#if !defined(FSTRING_GUARD)
FSTRING_INLINE fstr_bool
char_is_upper(char c)
{
return (c >= 'A' && c <= 'Z');
}
#endif
#if !defined(FSTRING_GUARD)
FSTRING_INLINE fstr_bool
char_is_lower(char c)
{
return (c >= 'a' && c <= 'z');
}
#endif
#if !defined(FSTRING_GUARD)
FSTRING_INLINE char
char_to_upper(char c)

View File

@ -579,109 +579,6 @@ seek_token_right(Cpp_Token_Array *tokens, i32 pos){
return token->start + token->size;
}
API_EXPORT int32_t
Buffer_Boundary_Seek(Application_Links *app, Buffer_Summary *buffer, 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(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(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.
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.)
DOC_SEE(Seek_Boundary_Flag)
DOC_SEE(4coder_Buffer_Positioning_System)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file;
int32_t result = 0;
file = imp_get_file(cmd, buffer);
if (file){
// TODO(allen): reduce duplication?
i32 size = buffer_size(&file->state.buffer);
i32 pos[4] = {0};
i32 new_pos = 0;
if (start_pos < 0){
start_pos = 0;
}
else if (start_pos > size){
start_pos = size;
}
if (seek_forward){
for (i32 i = 0; i < ArrayCount(pos); ++i) pos[i] = size;
if (flags & (1)){
pos[0] = buffer_seek_whitespace_right(&file->state.buffer, start_pos);
}
if (flags & (1 << 1)){
if (file->state.tokens_complete){
pos[1] = seek_token_right(&file->state.token_array, start_pos);
}
else{
pos[1] = buffer_seek_whitespace_right(&file->state.buffer, start_pos);
}
}
if (flags & (1 << 2)){
pos[2] = buffer_seek_alphanumeric_right(&file->state.buffer, start_pos);
if (flags & (1 << 3)){
pos[3] = buffer_seek_range_camel_right(&file->state.buffer, start_pos, pos[2]);
}
}
else{
if (flags & (1 << 3)){
pos[3] = buffer_seek_alphanumeric_or_camel_right(&file->state.buffer, start_pos);
}
}
new_pos = size;
for (i32 i = 0; i < ArrayCount(pos); ++i){
if (pos[i] < new_pos) new_pos = pos[i];
}
}
else{
if (flags & (1)){
pos[0] = buffer_seek_whitespace_left(&file->state.buffer, start_pos);
}
if (flags & (1 << 1)){
if (file->state.tokens_complete){
pos[1] = seek_token_left(&file->state.token_array, start_pos);
}
else{
pos[1] = buffer_seek_whitespace_left(&file->state.buffer, start_pos);
}
}
if (flags & (1 << 2)){
pos[2] = buffer_seek_alphanumeric_left(&file->state.buffer, start_pos);
if (flags & (1 << 3)){
pos[3] = buffer_seek_range_camel_left(&file->state.buffer, start_pos, pos[2]);
}
}
else{
if (flags & (1 << 3)){
pos[3] = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, start_pos);
}
}
new_pos = 0;
for (i32 i = 0; i < ArrayCount(pos); ++i){
if (pos[i] > new_pos) new_pos = pos[i];
}
}
result = new_pos;
fill_buffer_summary(buffer, file, cmd);
}
return(result);
}
API_EXPORT bool32
Buffer_Read_Range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *out)/*
DOC_PARAM(buffer, This parameter specifies the buffer to read.)

View File

@ -24,25 +24,6 @@ buffer_stringify(Buffer_Type *buffer, int start, int end, char *out){
}
}
inline_4tech void
buffer_backify(Buffer_Type *buffer, int start, int end, char *out){
for (Buffer_Backify_Type loop = buffer_backify_loop(buffer, end, start);
buffer_backify_good(&loop);
buffer_backify_next(&loop)){
memcpy_4tech(out, loop.data, loop.size);
out += loop.size;
}
}
internal_4tech char
buffer_get_char(Buffer_Type *buffer, int i){
char out = 0;
if (i >= 0 && i < buffer_size(buffer)){
buffer_stringify(buffer, i, i+1, &out);
}
return(out);
}
internal_4tech int
buffer_convert_out(Buffer_Type *buffer, char *dest, int max){
Buffer_Stringify_Type loop;
@ -86,461 +67,6 @@ buffer_count_newlines(Buffer_Type *buffer, int start, int end){
return(count);
}
internal_4tech int
buffer_seek_delimiter(Buffer_Type *buffer, int pos, char delim){
Buffer_Stringify_Type loop;
char *data;
int end, size;
size = buffer_size(buffer);
for(loop = buffer_stringify_loop(buffer, pos, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end; ++pos){
if (data[pos] == delim) goto double_break;
}
}
double_break:
return(pos);
}
internal_4tech int
buffer_reverse_seek_delimiter(Buffer_Type *buffer, int pos, char delim){
Buffer_Backify_Type loop;
char *data;
int end;
for(loop = buffer_backify_loop(buffer, pos, 0);
buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= 0; --pos){
if (data[pos] == delim) goto double_break;
}
}
double_break:
return(pos);
}
internal_4tech int
buffer_seek_whitespace_right(Buffer_Type *buffer, int pos){
Buffer_Stringify_Type loop;
char *data;
int end;
int size;
size = buffer_size(buffer);
loop = buffer_stringify_loop(buffer, pos, size);
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end && is_whitespace(data[pos]); ++pos);
if (!is_whitespace(data[pos])) break;
}
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end && !is_whitespace(data[pos]); ++pos);
if (is_whitespace(data[pos])) break;
}
return(pos);
}
internal_4tech int
buffer_seek_whitespace_left(Buffer_Type *buffer, int pos){
Buffer_Backify_Type loop;
char *data;
int end;
int size;
--pos;
if (pos > 0){
size = buffer_size(buffer);
loop = buffer_backify_loop(buffer, pos, 1);
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= end && is_whitespace(data[pos]); --pos);
if (!is_whitespace(data[pos])) break;
}
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= end && !is_whitespace(data[pos]); --pos);
if (is_whitespace(data[pos])) break;
}
if (pos != 0) ++pos;
}
else{
pos = 0;
}
return(pos);
}
internal_4tech int
buffer_seek_word_right_assume_on_word(Buffer_Type *buffer, int pos){
Buffer_Stringify_Type loop;
char *data;
int end;
int size;
size = buffer_size(buffer);
loop = buffer_stringify_loop(buffer, pos, size);
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end; ++pos){
if (!is_alphanumeric(data[pos])) goto double_break;
}
}
double_break:
return(pos);
}
internal_4tech int
buffer_seek_alphanumeric_right(Buffer_Type *buffer, int pos){
Buffer_Stringify_Type loop;
char *data;
int end;
int size;
size = buffer_size(buffer);
loop = buffer_stringify_loop(buffer, pos, size);
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end; ++pos){
if (is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_mid;
}
}
buffer_seek_alphanumeric_right_mid:
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end; ++pos){
if (!is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_end;
}
}
buffer_seek_alphanumeric_right_end:
return(pos);
}
internal_4tech int
buffer_seek_alphanumeric_left(Buffer_Type *buffer, int pos){
Buffer_Backify_Type loop;
char *data;
int end;
int size;
--pos;
if (pos >= 0){
size = buffer_size(buffer);
loop = buffer_backify_loop(buffer, pos, 1);
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - end;
for (; pos >= end; --pos){
if (is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_left_mid;
}
}
buffer_seek_alphanumeric_left_mid:
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - end;
for (; pos >= end; --pos){
if (!is_alphanumeric_true(data[pos])){
++pos;
goto buffer_seek_alphanumeric_left_end;
}
}
}
}
else{
pos = 0;
}
buffer_seek_alphanumeric_left_end:
return(pos);
}
internal_4tech int
buffer_seek_range_camel_right(Buffer_Type *buffer, int pos, int an_pos){
Buffer_Stringify_Type loop;
char *data;
int end, size;
char ch, prev_ch;
size = buffer_size(buffer);
assert_4tech(pos <= an_pos);
assert_4tech(an_pos <= size);
++pos;
if (pos < an_pos){
loop = buffer_stringify_loop(buffer, pos, an_pos);
if (buffer_stringify_good(&loop)){
prev_ch = loop.data[0];
++pos;
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end; ++pos){
ch = data[pos];
if (is_upper(ch) && is_lower(prev_ch)) goto buffer_seek_alphanumeric_or_camel_right_end;
prev_ch = ch;
}
}
}
}
else{
pos = an_pos;
}
buffer_seek_alphanumeric_or_camel_right_end:
return(pos);
}
internal_4tech int
buffer_seek_range_camel_left(Buffer_Type *buffer, int pos, int an_pos){
Buffer_Backify_Type loop;
char *data;
int end, size;
char ch, prev_ch;
size = buffer_size(buffer);
assert_4tech(an_pos <= pos);
assert_4tech(0 <= an_pos);
--pos;
loop = buffer_backify_loop(buffer, pos, an_pos+1);
if (buffer_backify_good(&loop)){
prev_ch = loop.data[0];
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= end; --pos){
ch = data[pos];
if (is_upper(ch) && is_lower(prev_ch)) goto buffer_seek_alphanumeric_or_camel_left_end;
prev_ch = ch;
}
}
}
buffer_seek_alphanumeric_or_camel_left_end:
return(pos);
}
internal_4tech int
buffer_seek_alphanumeric_or_camel_right(Buffer_Type *buffer, int pos){
int an_pos, result;
an_pos = buffer_seek_alphanumeric_right(buffer, pos);
result = buffer_seek_range_camel_right(buffer, pos, an_pos);
return(result);
}
internal_4tech int
buffer_seek_alphanumeric_or_camel_left(Buffer_Type *buffer, int pos){
int an_pos, result;
an_pos = buffer_seek_alphanumeric_left(buffer, pos);
result = buffer_seek_range_camel_left(buffer, pos, an_pos);
return(result);
}
struct Hard_Start_Result{
int char_pos;
int indent_pos;
int all_whitespace;
int all_space;
};
internal_4tech Hard_Start_Result
buffer_find_hard_start(Buffer_Type *buffer, int line_start, int tab_width){
Hard_Start_Result result = {0};
Buffer_Stringify_Type loop;
char *data;
int size, end;
char c;
result.all_space = 1;
result.indent_pos = 0;
size = buffer_size(buffer);
tab_width -= 1;
result.char_pos = line_start;
for (loop = buffer_stringify_loop(buffer, line_start, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; result.char_pos < end; ++result.char_pos){
c = data[result.char_pos];
if (c == '\n' || c == 0){
result.all_whitespace = 1;
goto buffer_find_hard_start_end;
}
if (c >= '!' && c <= '~') goto buffer_find_hard_start_end;
if (c == '\t') result.indent_pos += tab_width;
if (c != ' ') result.all_space = 0;
result.indent_pos += 1;
}
}
buffer_find_hard_start_end:
return(result);
}
internal_4tech int
buffer_find_string(Buffer_Type *buffer, int start_pos, int end_pos, char *str, int len, char *spare){
Buffer_Stringify_Type loop;
char *data;
int end, pos;
pos = start_pos;
if (len > 0){
for (loop = buffer_stringify_loop(buffer, start_pos, end_pos - len + 1);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end; ++pos){
if (*str == data[pos]){
buffer_stringify(buffer, pos, pos + len, spare);
if (is_match(str, spare, len))
goto buffer_find_string_end;
}
}
}
}
buffer_find_string_end:
if (pos >= end_pos - len + 1) pos = end_pos;
return(pos);
}
internal_4tech int
buffer_rfind_string(Buffer_Type *buffer, int start_pos, char *str, int len, char *spare){
Buffer_Backify_Type loop;
char *data;
int end, size;
int pos;
size = buffer_size(buffer);
pos = start_pos;
if (pos > size - len) pos = size - len;
if (len > 0){
for (loop = buffer_backify_loop(buffer, start_pos, 0);
buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= end; --pos){
if (*str == data[pos]){
buffer_stringify(buffer, pos, pos + len, spare);
if (is_match(str, spare, len))
goto buffer_rfind_string_end;
}
}
}
}
buffer_rfind_string_end:
return(pos);
}
internal_4tech int
buffer_find_string_insensitive(Buffer_Type *buffer, int start_pos, int end_pos, char *str, int len, char *spare){
Buffer_Stringify_Type loop;
char *data;
int end, pos;
pos = start_pos;
if (len > 0){
for (loop = buffer_stringify_loop(buffer, start_pos, end_pos - len + 1);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end; ++pos){
if (to_upper(*str) == to_upper(data[pos])){
buffer_stringify(buffer, pos, pos + len, spare);
if (is_match_insensitive(str, spare, len))
goto buffer_find_string_end;
}
}
}
}
buffer_find_string_end:
if (pos >= end_pos - len + 1) pos = end_pos;
return(pos);
}
internal_4tech int
buffer_rfind_string_insensitive(Buffer_Type *buffer, int start_pos, char *str, int len, char *spare){
Buffer_Backify_Type loop;
char *data;
int end, size;
int pos;
size = buffer_size(buffer);
pos = start_pos;
if (pos > size - len) pos = size - len;
if (len > 0){
for (loop = buffer_backify_loop(buffer, start_pos, 0);
buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= end; --pos){
if (to_upper(*str) == to_upper(data[pos])){
buffer_stringify(buffer, pos, pos + len, spare);
if (is_match_insensitive(str, spare, len))
goto buffer_rfind_string_end;
}
}
}
}
buffer_rfind_string_end:
return(pos);
}
#ifndef NON_ABSTRACT_4TECH
typedef struct Buffer_Measure_Starts{
int i;

View File

@ -67,6 +67,18 @@ char_is_slash(char c)
return (c == '\\' || c == '/');
}
FSTRING_INLINE fstr_bool
char_is_upper(char c)
/* DOC(If c is an uppercase letter this call returns true.) */{
return (c >= 'A' && c <= 'Z');
}
FSTRING_INLINE fstr_bool
char_is_lower(char c)
/* DOC(If c is a lower letter this call returns true.) */{
return (c >= 'a' && c <= 'z');
}
FSTRING_INLINE char
char_to_upper(char c)
/* DOC(If c is a lowercase letter this call returns the uppercase equivalent, otherwise it returns c.) */{

View File

@ -16,6 +16,8 @@ Allen Webster
#include "4coder_default_include.cpp"
#include <stdio.h>
#include <intrin.h>
#pragma intrinsic(__rdtsc)
@ -80,11 +82,97 @@ CUSTOM_COMMAND_SIG(run_all_tests){
exec_command(app, reopen_test);
}
#if 0
CUSTOM_COMMAND_SIG(generate_stop_spots_test_data){
Buffer_Summary buffer = app->create_buffer(app, literal(LOTS_OF_FILES "/4ed.cpp"), 0);
View_Summary view = app->get_active_view(app, AccessAll);
app->view_set_buffer(app, &view, buffer.buffer_id, 0);
FILE *file = fopen(TEST_FILES "/stop_spots_data", "wb");
if (file){
Partial_Cursor curs;
int32_t pos;
app->buffer_compute_cursor(app, &buffer, seek_line_char(316, 29), &curs);
fwrite(&curs.pos, 4, 1, file);
static Seek_Boundary_Flag flag_set[] = {
BoundaryWhitespace,
BoundaryToken,
BoundaryAlphanumeric,
BoundaryCamelCase,
BoundaryWhitespace | BoundaryToken,
BoundaryWhitespace | BoundaryAlphanumeric,
BoundaryToken | BoundaryCamelCase,
};
for (int32_t flag_i = 0; flag_i < ArrayCount(flag_set); ++flag_i){
for (int32_t seek_forward = 0; seek_forward <= 1; ++seek_forward){
pos = curs.pos;
for (int32_t i = 0; i < 100; ++i){
pos = app->buffer_boundary_seek(app, &buffer, pos, seek_forward, flag_set[flag_i]);
fwrite(&pos, 4, 1, file);
}
}
}
fclose(file);
}
}
#endif
static void
fcheck(int32_t x, FILE *file){
int32_t x0 = 0;
fread(&x0, 4, 1, file);
Assert(x == x0);
}
CUSTOM_COMMAND_SIG(stop_spots_test){
Buffer_Summary buffer = app->create_buffer(app, literal(LOTS_OF_FILES "/4ed.cpp"), 0);
View_Summary view = app->get_active_view(app, AccessAll);
app->view_set_buffer(app, &view, buffer.buffer_id, 0);
FILE *file = fopen(TEST_FILES "/stop_spots_data", "rb");
if (file){
Partial_Cursor curs;
int32_t pos;
app->buffer_compute_cursor(app, &buffer, seek_line_char(316, 29), &curs);
fcheck(curs.pos, file);
static Seek_Boundary_Flag flag_set[] = {
BoundaryWhitespace,
BoundaryToken,
BoundaryAlphanumeric,
BoundaryCamelCase,
BoundaryWhitespace | BoundaryToken,
BoundaryWhitespace | BoundaryAlphanumeric,
BoundaryToken | BoundaryCamelCase,
};
for (int32_t flag_i = 0; flag_i < ArrayCount(flag_set); ++flag_i){
for (int32_t seek_forward = 0; seek_forward <= 1; ++seek_forward){
pos = curs.pos;
for (int32_t i = 0; i < 100; ++i){
pos = buffer_boundary_seek(app, &buffer, pos, seek_forward, flag_set[flag_i]);
fcheck(pos, file);
}
}
}
fclose(file);
}
}
static void
test_get_bindings(Bind_Helper *context){
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);
}

View File

@ -1833,7 +1833,9 @@ Win32Callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
win32vars.input_chunk.pers.mouse_l = 0;
win32vars.input_chunk.pers.mouse_r = 0;
win32vars.input_chunk.pers.control_keys[MDFR_SHIFT_INDEX] = 0;
for (int32_t i = 0; i < MDFR_INDEX_COUNT; ++i){
win32vars.input_chunk.pers.control_keys[i] = 0;
}
win32vars.input_chunk.pers.controls = null_control_keys;
}break;