§5.4.1: cpp_get_token
Cpp_Get_Token_Result cpp_get_token(
Cpp_Token_Array *token_array_in,
int32_t pos
)
Parameters
token_array
The array of tokens from which to get a token.
pos
The position, measured in bytes, to get the token for.
Return
A Cpp_Get_Token_Result struct is returned containing the index
of a token and a flag indicating whether the pos is contained in the token
diff --git a/4coder_custom_api.h b/4coder_custom_api.h
index 5dfc3251..96b386ce 100644
--- a/4coder_custom_api.h
+++ b/4coder_custom_api.h
@@ -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;\
diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp
index f1d507d2..82414d4e 100644
--- a/4coder_default_include.cpp
+++ b/4coder_default_include.cpp
@@ -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);
diff --git a/4coder_string.h b/4coder_string.h
index d521319c..eeafb33b 100644
--- a/4coder_string.h
+++ b/4coder_string.h
@@ -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)
diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp
index 9926bb6d..5b5a14f8 100644
--- a/4ed_api_implementation.cpp
+++ b/4ed_api_implementation.cpp
@@ -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.)
diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp
index dd927a89..96e80cc9 100644
--- a/buffer/4coder_buffer_abstract.cpp
+++ b/buffer/4coder_buffer_abstract.cpp
@@ -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;
diff --git a/internal_4coder_string.cpp b/internal_4coder_string.cpp
index fd24b4b3..d0791c98 100644
--- a/internal_4coder_string.cpp
+++ b/internal_4coder_string.cpp
@@ -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.) */{
diff --git a/internal_4coder_tests.cpp b/internal_4coder_tests.cpp
index eec071a9..8ca0fa52 100644
--- a/internal_4coder_tests.cpp
+++ b/internal_4coder_tests.cpp
@@ -16,6 +16,8 @@ Allen Webster
#include "4coder_default_include.cpp"
+#include
+
#include
#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);
}
diff --git a/win32_4ed.cpp b/win32_4ed.cpp
index f89ebf40..312bbf2e 100644
--- a/win32_4ed.cpp
+++ b/win32_4ed.cpp
@@ -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;