move towards searching commands custom side and custom allocator
This commit is contained in:
parent
8f8f7ed5fd
commit
c479e14f25
204
4coder_API.html
204
4coder_API.html
|
@ -22,7 +22,7 @@ ul { list-style: none; padding: 0; margin: 0; }
|
|||
<h2 id='section_introduction'>§1 Introduction</h2>
|
||||
<div>
|
||||
<p>
|
||||
This is the documentation for alpha 4.0.9 super! The documentation is still under construction so some of the links are linking to sections that have not been written yet. What is here should be correct and I suspect useful even without some of the other sections. </p>
|
||||
This is the documentation for alpha 4.0.10 The documentation is still under construction so some of the links are linking to sections that have not been written yet. What is here should be correct and I suspect useful even without some of the other sections. </p>
|
||||
<p>
|
||||
If you have questions or discover errors please contact <span style='font-family: "Courier New", Courier, monospace; text-align: left;'>editor@4coder.net</span> or to get help from community members you can post on the 4coder forums hosted on handmade.network at <span style='font-family: "Courier New", Courier, monospace; text-align: left;'>4coder.handmade.network</span></p>
|
||||
</div>
|
||||
|
@ -34,9 +34,13 @@ Coming Soon</i><div>
|
|||
<ul>
|
||||
<li><a href='#exec_command_doc'>exec_command</a></li>
|
||||
<li><a href='#exec_system_command_doc'>exec_system_command</a></li>
|
||||
<li><a href='#memory_alloc_doc'>memory_alloc</a></li>
|
||||
<li><a href='#memory_set_protection_doc'>memory_set_protection</a></li>
|
||||
<li><a href='#memory_free_doc'>memory_free</a></li>
|
||||
<li><a href='#clipboard_post_doc'>clipboard_post</a></li>
|
||||
<li><a href='#clipboard_count_doc'>clipboard_count</a></li>
|
||||
<li><a href='#clipboard_index_doc'>clipboard_index</a></li>
|
||||
<li><a href='#get_buffer_count_doc'>get_buffer_count</a></li>
|
||||
<li><a href='#get_buffer_first_doc'>get_buffer_first</a></li>
|
||||
<li><a href='#get_buffer_next_doc'>get_buffer_next</a></li>
|
||||
<li><a href='#get_buffer_doc'>get_buffer</a></li>
|
||||
|
@ -101,6 +105,7 @@ Coming Soon</i><div>
|
|||
<li><a href='#Buffer_Seek_Type_doc'>Buffer_Seek_Type</a></li>
|
||||
<li><a href='#View_Split_Position_doc'>View_Split_Position</a></li>
|
||||
<li><a href='#Key_Modifier_Flag_doc'>Key_Modifier_Flag</a></li>
|
||||
<li><a href='#Memory_Protect_Flags_doc'>Memory_Protect_Flags</a></li>
|
||||
<li><a href='#Buffer_Create_Flag_doc'>Buffer_Create_Flag</a></li>
|
||||
<li><a href='#Buffer_Kill_Flag_doc'>Buffer_Kill_Flag</a></li>
|
||||
<li><a href='#Access_Flag_doc'>Access_Flag</a></li>
|
||||
|
@ -181,8 +186,26 @@ If the buffer is not already in an open view and the view parameter is not NULL,
|
|||
then the provided view will display the output buffer.
|
||||
|
||||
If the view parameter is NULL, no view will switch to the output.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Identifier_doc'>Buffer_Identifier</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Command_Line_Input_Flag_doc'>Command_Line_Input_Flag</a></div></div><hr>
|
||||
<div id='memory_alloc_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.3: memory_alloc</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void* app->memory_alloc(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>int32_t size<br></div>)
|
||||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div></div><hr>
|
||||
<div id='memory_set_protection_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.4: memory_set_protection</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>int32_t app->memory_set_protection(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>void *ptr,<br>int32_t size,<br>Memory_Protect_Flags flags<br></div>)
|
||||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div></div><hr>
|
||||
<div id='memory_free_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.5: memory_free</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->memory_free(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>void *mem<br></div>)
|
||||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div></div><hr>
|
||||
<div id='clipboard_post_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.3: clipboard_post</h4>
|
||||
<h4>§3.3.6: clipboard_post</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->clipboard_post(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>int32_t clipboard_id,<br>char *str,<br>int32_t len<br></div>)
|
||||
</div>
|
||||
|
@ -202,7 +225,7 @@ If the view parameter is NULL, no view will switch to the output.</div><div styl
|
|||
Also reports the copy to the operating system, so that it may
|
||||
be pasted into other applications.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#The_4coder_Clipboard_doc'>The_4coder_Clipboard</a></div></div><hr>
|
||||
<div id='clipboard_count_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.4: clipboard_count</h4>
|
||||
<h4>§3.3.7: clipboard_count</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>int32_t app->clipboard_count(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>int32_t clipboard_id<br></div>)
|
||||
</div>
|
||||
|
@ -212,7 +235,7 @@ be pasted into other applications.</div><div style='margin-top: 3mm; margin-bott
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns the number of items in the clipboard.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#The_4coder_Clipboard_doc'>The_4coder_Clipboard</a></div></div><hr>
|
||||
<div id='clipboard_index_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.5: clipboard_index</h4>
|
||||
<h4>§3.3.8: clipboard_index</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>int32_t app->clipboard_index(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>int32_t clipboard_id,<br>int32_t item_index,<br>char *out,<br>int32_t len<br></div>)
|
||||
</div>
|
||||
|
@ -235,8 +258,14 @@ be pasted into other applications.</div><div style='margin-top: 3mm; margin-bott
|
|||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns the size of the item associated with item_index.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This function always returns the size of the item even if the output buffer is NULL.
|
||||
If the output buffer is too small to contain the whole string, it is filled with the
|
||||
first len character of the clipboard contents. The output string is not null terminated.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#The_4coder_Clipboard_doc'>The_4coder_Clipboard</a></div></div><hr>
|
||||
<div id='get_buffer_count_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.9: get_buffer_count</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>int32_t app->get_buffer_count(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app<br></div>)
|
||||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div></div><hr>
|
||||
<div id='get_buffer_first_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.6: get_buffer_first</h4>
|
||||
<h4>§3.3.10: get_buffer_first</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>Buffer_Summary app->get_buffer_first(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Access_Flag access<br></div>)
|
||||
</div>
|
||||
|
@ -249,7 +278,7 @@ first len character of the clipboard contents. The output string is not null te
|
|||
If the buffer returned does not exist, the loop is finished.
|
||||
Buffers should not be killed durring a buffer loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_buffer_next_doc'>get_buffer_next</a></div></div><hr>
|
||||
<div id='get_buffer_next_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.7: get_buffer_next</h4>
|
||||
<h4>§3.3.11: get_buffer_next</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->get_buffer_next(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>Access_Flag access<br></div>)
|
||||
</div>
|
||||
|
@ -267,7 +296,7 @@ The global buffer order is kept roughly in the order of most recently used to le
|
|||
If the buffer outputted does not exist, the loop is finished.
|
||||
Buffers should not be killed or created durring a buffer loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_buffer_first_doc'>get_buffer_first</a></div></div><hr>
|
||||
<div id='get_buffer_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.8: get_buffer</h4>
|
||||
<h4>§3.3.12: get_buffer</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>Buffer_Summary app->get_buffer(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_ID buffer_id,<br>Access_Flag access<br></div>)
|
||||
</div>
|
||||
|
@ -281,7 +310,7 @@ Buffers should not be killed or created durring a buffer loop.</div><div style='
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the indicated buffer if it exists and is accessible.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_ID_doc'>Buffer_ID</a></div></div><hr>
|
||||
<div id='get_buffer_by_name_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.9: get_buffer_by_name</h4>
|
||||
<h4>§3.3.13: get_buffer_by_name</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>Buffer_Summary app->get_buffer_by_name(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *name,<br>int32_t len,<br>Access_Flag access<br></div>)
|
||||
</div>
|
||||
|
@ -299,7 +328,7 @@ Buffers should not be killed or created durring a buffer loop.</div><div style='
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the indicated buffer if it exists and is accessible.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
|
||||
<div id='buffer_boundary_seek_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.10: buffer_boundary_seek</h4>
|
||||
<h4>§3.3.14: buffer_boundary_seek</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>int32_t app->buffer_boundary_seek(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>int32_t start_pos,<br>bool32 seek_forward,<br>Seek_Boundary_Flag flags<br></div>)
|
||||
</div>
|
||||
|
@ -323,7 +352,7 @@ Buffers should not be killed or created durring a buffer loop.</div><div style='
|
|||
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.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Seek_Boundary_Flag_doc'>Seek_Boundary_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
|
||||
<div id='buffer_read_range_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.11: buffer_read_range</h4>
|
||||
<h4>§3.3.15: buffer_read_range</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->buffer_read_range(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>int32_t start,<br>int32_t end,<br>char *out<br></div>)
|
||||
</div>
|
||||
|
@ -349,7 +378,7 @@ The output is not null terminated.
|
|||
This call fails if the buffer does not exist,
|
||||
or if the read range is not within the bounds of the buffer.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
|
||||
<div id='buffer_replace_range_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.12: buffer_replace_range</h4>
|
||||
<h4>§3.3.16: buffer_replace_range</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->buffer_replace_range(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>int32_t start,<br>int32_t end,<br>char *str,<br>int32_t len<br></div>)
|
||||
</div>
|
||||
|
@ -382,7 +411,7 @@ from start to end.
|
|||
This call fails if the buffer does not exist, or if the replace
|
||||
range is not within the bounds of the buffer.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
|
||||
<div id='buffer_batch_edit_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.13: buffer_batch_edit</h4>
|
||||
<h4>§3.3.17: buffer_batch_edit</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->buffer_batch_edit(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>char *str,<br>int32_t str_len,<br>Buffer_Edit *edits,<br>int32_t edit_count,<br>Buffer_Batch_Edit_Type type<br></div>)
|
||||
</div>
|
||||
|
@ -406,9 +435,9 @@ range is not within the bounds of the buffer.</div><div style='margin-top: 3mm;
|
|||
<div style='font-weight: 600;'>type</div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This prameter specifies what type of batch edit to execute.</div></div>
|
||||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero if the batch edit succeeds.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Edit_doc'>Buffer_Edit</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Batch_Edit_Type_doc'>Buffer_Batch_Edit_Type</a></div></div><hr>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero if the batch edit succeeds.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Edit_doc'>Buffer_Edit</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Batch_Edit_Type_doc'>Buffer_Batch_Edit_Type</a></div></div><hr>
|
||||
<div id='buffer_set_setting_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.14: buffer_set_setting</h4>
|
||||
<h4>§3.3.18: buffer_set_setting</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->buffer_set_setting(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>Buffer_Setting_ID setting,<br>int32_t value<br></div>)
|
||||
</div>
|
||||
|
@ -426,7 +455,7 @@ range is not within the bounds of the buffer.</div><div style='margin-top: 3mm;
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Setting_ID_doc'>Buffer_Setting_ID</a></div></div><hr>
|
||||
<div id='buffer_auto_indent_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.15: buffer_auto_indent</h4>
|
||||
<h4>§3.3.19: buffer_auto_indent</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->buffer_auto_indent(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>int32_t start,<br>int32_t end,<br>int32_t tab_width,<br>Auto_Indent_Flag flags<br></div>)
|
||||
</div>
|
||||
|
@ -455,7 +484,7 @@ start to end by inserting spaces or tabs at the beginning of the lines.
|
|||
If the buffer does not have lexing enabled or the lexing job has not
|
||||
completed this function will fail.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Auto_Indent_Flag_doc'>Auto_Indent_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
|
||||
<div id='create_buffer_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.16: create_buffer</h4>
|
||||
<h4>§3.3.20: create_buffer</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>Buffer_Summary app->create_buffer(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *filename,<br>int32_t filename_len,<br>Buffer_Create_Flag flags<br></div>)
|
||||
</div>
|
||||
|
@ -477,7 +506,7 @@ If the buffer does not exist a new buffer is created and named after the given f
|
|||
the filename corresponds to a file on the disk that file is loaded and put into buffer, if
|
||||
the filename does not correspond to a file on disk the buffer is created empty.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Create_Flag_doc'>Buffer_Create_Flag</a></div></div><hr>
|
||||
<div id='save_buffer_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.17: save_buffer</h4>
|
||||
<h4>§3.3.21: save_buffer</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->save_buffer(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>char *filename,<br>int32_t filename_len,<br>uint32_t flags<br></div>)
|
||||
</div>
|
||||
|
@ -499,7 +528,7 @@ the filename does not correspond to a file on disk the buffer is created empty.<
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div></div><hr>
|
||||
<div id='kill_buffer_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.18: kill_buffer</h4>
|
||||
<h4>§3.3.22: kill_buffer</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->kill_buffer(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Identifier buffer,<br>View_ID view_id,<br>Buffer_Kill_Flag flags<br></div>)
|
||||
</div>
|
||||
|
@ -519,7 +548,7 @@ the filename does not correspond to a file on disk the buffer is created empty.<
|
|||
dialogue needs to be displayed the provided view is used to show the dialogue.
|
||||
If the view is not open the kill fails.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Kill_Flag_doc'>Buffer_Kill_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Identifier_doc'>Buffer_Identifier</a></div></div><hr>
|
||||
<div id='get_view_first_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.19: get_view_first</h4>
|
||||
<h4>§3.3.23: get_view_first</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>View_Summary app->get_view_first(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Access_Flag access<br></div>)
|
||||
</div>
|
||||
|
@ -532,7 +561,7 @@ If the view is not open the kill fails.</div><div style='margin-top: 3mm; margin
|
|||
If the View_Summary returned is a null summary, the loop is finished.
|
||||
Views should not be closed or opened durring a view loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_view_next_doc'>get_view_next</a></div></div><hr>
|
||||
<div id='get_view_next_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.20: get_view_next</h4>
|
||||
<h4>§3.3.24: get_view_next</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->get_view_next(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Access_Flag access<br></div>)
|
||||
</div>
|
||||
|
@ -549,7 +578,7 @@ Views should not be closed or opened durring a view loop.</div><div style='margi
|
|||
If the view outputted does not exist, the loop is finished.
|
||||
Views should not be closed or opened durring a view loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_view_first_doc'>get_view_first</a></div></div><hr>
|
||||
<div id='get_view_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.21: get_view</h4>
|
||||
<h4>§3.3.25: get_view</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>View_Summary app->get_view(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_ID view_id,<br>Access_Flag access<br></div>)
|
||||
</div>
|
||||
|
@ -563,7 +592,7 @@ Views should not be closed or opened durring a view loop.</div><div style='margi
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the indicated view if it is open and accessible.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
|
||||
<div id='get_active_view_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.22: get_active_view</h4>
|
||||
<h4>§3.3.26: get_active_view</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>View_Summary app->get_active_view(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Access_Flag access<br></div>)
|
||||
</div>
|
||||
|
@ -573,7 +602,7 @@ Views should not be closed or opened durring a view loop.</div><div style='margi
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the active view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#set_active_view_doc'>set_active_view</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
|
||||
<div id='open_view_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.23: open_view</h4>
|
||||
<h4>§3.3.27: open_view</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>View_Summary app->open_view(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view_location,<br>View_Split_Position position<br></div>)
|
||||
</div>
|
||||
|
@ -589,7 +618,7 @@ Views should not be closed or opened durring a view loop.</div><div style='margi
|
|||
returns a null summary.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>4coder is built with a limit of 16 views. If 16 views are already open when this is called the
|
||||
call will fail.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#View_Split_Position_doc'>View_Split_Position</a></div></div><hr>
|
||||
<div id='close_view_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.24: close_view</h4>
|
||||
<h4>§3.3.28: close_view</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->close_view(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view<br></div>)
|
||||
</div>
|
||||
|
@ -602,7 +631,7 @@ If the given view is the active view, the next active view in the global
|
|||
order of view will be made active.
|
||||
If the given view is the last open view in the system, the call will fail.</div></div><hr>
|
||||
<div id='set_active_view_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.25: set_active_view</h4>
|
||||
<h4>§3.3.29: set_active_view</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->set_active_view(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view<br></div>)
|
||||
</div>
|
||||
|
@ -614,7 +643,7 @@ If the given view is the last open view in the system, the call will fail.</div>
|
|||
active view, and takes subsequent commands and is returned
|
||||
from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_active_view_doc'>get_active_view</a></div></div><hr>
|
||||
<div id='view_set_setting_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.26: view_set_setting</h4>
|
||||
<h4>§3.3.30: view_set_setting</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_setting(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>View_Setting_ID setting,<br>int32_t value<br></div>)
|
||||
</div>
|
||||
|
@ -632,7 +661,7 @@ from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; colo
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#View_Setting_ID_doc'>View_Setting_ID</a></div></div><hr>
|
||||
<div id='view_set_split_proportion_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.27: view_set_split_proportion</h4>
|
||||
<h4>§3.3.31: view_set_split_proportion</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_split_proportion(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>float t<br></div>)
|
||||
</div>
|
||||
|
@ -646,7 +675,7 @@ from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; colo
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div></div><hr>
|
||||
<div id='view_compute_cursor_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.28: view_compute_cursor</h4>
|
||||
<h4>§3.3.32: view_compute_cursor</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_compute_cursor(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Buffer_Seek seek,<br>Full_Cursor *cursor_out<br></div>)
|
||||
</div>
|
||||
|
@ -664,7 +693,7 @@ from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; colo
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Computes a Full_Cursor for the given seek position with no side effects.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_doc'>Buffer_Seek</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Full_Cursor_doc'>Full_Cursor</a></div></div><hr>
|
||||
<div id='view_set_cursor_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.29: view_set_cursor</h4>
|
||||
<h4>§3.3.33: view_set_cursor</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_cursor(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Buffer_Seek seek,<br>bool32 set_preferred_x<br></div>)
|
||||
</div>
|
||||
|
@ -684,7 +713,7 @@ from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; colo
|
|||
unless the change in cursor position is is a vertical motion that tries to keep the
|
||||
cursor in the same column or x position.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_doc'>Buffer_Seek</a></div></div><hr>
|
||||
<div id='view_set_mark_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.30: view_set_mark</h4>
|
||||
<h4>§3.3.34: view_set_mark</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_mark(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Buffer_Seek seek<br></div>)
|
||||
</div>
|
||||
|
@ -698,7 +727,7 @@ cursor in the same column or x position.</div><div style='margin-top: 3mm; margi
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call sets the the view's mark position.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_doc'>Buffer_Seek</a></div></div><hr>
|
||||
<div id='view_set_highlight_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.31: view_set_highlight</h4>
|
||||
<h4>§3.3.35: view_set_highlight</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_highlight(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>int32_t start,<br>int32_t end,<br>bool32 turn_on<br></div>)
|
||||
</div>
|
||||
|
@ -723,7 +752,7 @@ is set to true the highlight will be shown and the cursor will be hidden. After
|
|||
that either setting the with view_set_cursor or calling view_set_highlight and
|
||||
the turn_on set to false, will switch back to showing the cursor.</div></div><hr>
|
||||
<div id='view_set_buffer_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.32: view_set_buffer</h4>
|
||||
<h4>§3.3.36: view_set_buffer</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_buffer(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Buffer_ID buffer_id,<br>Set_Buffer_Flag flags<br></div>)
|
||||
</div>
|
||||
|
@ -742,7 +771,7 @@ the turn_on set to false, will switch back to showing the cursor.</div></div><hr
|
|||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>On success view_set_buffer sets the specified view's current buffer and
|
||||
cancels and dialogue shown in the view and displays the file.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Set_Buffer_Flag_doc'>Set_Buffer_Flag</a></div></div><hr>
|
||||
<div id='view_post_fade_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.33: view_post_fade</h4>
|
||||
<h4>§3.3.37: view_post_fade</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_post_fade(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>float seconds,<br>int32_t start,<br>int32_t end,<br>int_color color<br></div>)
|
||||
</div>
|
||||
|
@ -768,7 +797,7 @@ cancels and dialogue shown in the view and displays the file.</div><div style='m
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#int_color_doc'>int_color</a></div></div><hr>
|
||||
<div id='get_user_input_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.34: get_user_input</h4>
|
||||
<h4>§3.3.38: get_user_input</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>User_Input app->get_user_input(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Input_Type_Flag get_type,<br>Input_Type_Flag abort_type<br></div>)
|
||||
</div>
|
||||
|
@ -786,19 +815,19 @@ command is executed an abort signal is returned. If an abort signal is ever ret
|
|||
command should finish execution without any more calls that preempt the command.
|
||||
If a get condition is met the user input is returned.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Input_Type_Flag_doc'>Input_Type_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#User_Input_doc'>User_Input</a></div></div><hr>
|
||||
<div id='get_command_input_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.35: get_command_input</h4>
|
||||
<h4>§3.3.39: get_command_input</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>User_Input app->get_command_input(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app<br></div>)
|
||||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns the input that triggered the currently executing command.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#User_Input_doc'>User_Input</a></div></div><hr>
|
||||
<div id='get_mouse_state_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.36: get_mouse_state</h4>
|
||||
<h4>§3.3.40: get_mouse_state</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>Mouse_State app->get_mouse_state(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app<br></div>)
|
||||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns the current mouse state as of the beginning of the frame.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Mouse_State_doc'>Mouse_State</a></div></div><hr>
|
||||
<div id='start_query_bar_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.37: start_query_bar</h4>
|
||||
<h4>§3.3.41: start_query_bar</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->start_query_bar(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Query_Bar *bar,<br>uint32_t flags<br></div>)
|
||||
</div>
|
||||
|
@ -818,7 +847,7 @@ can be changed after the call to start_query_bar and the query bar shown by 4cod
|
|||
will reflect the change. Since the bar stops showing when the command exits the
|
||||
only use for this call is in an interactive command that makes calls to get_user_input.</div></div><hr>
|
||||
<div id='end_query_bar_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.38: end_query_bar</h4>
|
||||
<h4>§3.3.42: end_query_bar</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->end_query_bar(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Query_Bar *bar,<br>uint32_t flags<br></div>)
|
||||
</div>
|
||||
|
@ -832,7 +861,7 @@ only use for this call is in an interactive command that makes calls to get_user
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Stops showing the particular query bar specified by the bar parameter.</div></div><hr>
|
||||
<div id='print_message_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.39: print_message</h4>
|
||||
<h4>§3.3.43: print_message</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->print_message(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *str,<br>int32_t len<br></div>)
|
||||
</div>
|
||||
|
@ -846,7 +875,7 @@ only use for this call is in an interactive command that makes calls to get_user
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call posts a string to the *messages* buffer.</div></div><hr>
|
||||
<div id='change_theme_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.40: change_theme</h4>
|
||||
<h4>§3.3.44: change_theme</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->change_theme(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *name,<br>int32_t len<br></div>)
|
||||
</div>
|
||||
|
@ -860,7 +889,7 @@ only use for this call is in an interactive command that makes calls to get_user
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call changes 4coder's theme to one of the built in themes.</div></div><hr>
|
||||
<div id='change_font_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.41: change_font</h4>
|
||||
<h4>§3.3.45: change_font</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->change_font(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *name,<br>int32_t len<br></div>)
|
||||
</div>
|
||||
|
@ -874,7 +903,7 @@ only use for this call is in an interactive command that makes calls to get_user
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call changes 4coder's font to one of the built in fonts.</div></div><hr>
|
||||
<div id='set_theme_colors_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.42: set_theme_colors</h4>
|
||||
<h4>§3.3.46: set_theme_colors</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->set_theme_colors(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Theme_Color *colors,<br>int32_t count<br></div>)
|
||||
</div>
|
||||
|
@ -890,7 +919,7 @@ only use for this call is in an interactive command that makes calls to get_user
|
|||
struct's tag is set to the color code in the struct. If the tag value is invalid
|
||||
no change is made to the color pallet.</div></div><hr>
|
||||
<div id='get_theme_colors_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.43: get_theme_colors</h4>
|
||||
<h4>§3.3.47: get_theme_colors</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->get_theme_colors(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Theme_Color *colors,<br>int32_t count<br></div>)
|
||||
</div>
|
||||
|
@ -906,7 +935,7 @@ no change is made to the color pallet.</div></div><hr>
|
|||
color from the slot in the main color pallet specified by the tag. If the tag
|
||||
value is invalid the color is filled with black.</div></div><hr>
|
||||
<div id='directory_get_hot_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.44: directory_get_hot</h4>
|
||||
<h4>§3.3.48: directory_get_hot</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>int32_t app->directory_get_hot(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *out,<br>int32_t capacity<br></div>)
|
||||
</div>
|
||||
|
@ -924,7 +953,7 @@ accessed in the GUI. Whenever the GUI is opened it shows the hot directory.
|
|||
In the future this will be deprecated and eliminated in favor of more flexible
|
||||
directories controlled on the custom side.</div></div><hr>
|
||||
<div id='get_file_list_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.45: get_file_list</h4>
|
||||
<h4>§3.3.49: get_file_list</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>File_List app->get_file_list(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *dir,<br>int32_t len<br></div>)
|
||||
</div>
|
||||
|
@ -940,7 +969,7 @@ directories controlled on the custom side.</div></div><hr>
|
|||
the specified directory. The File_List returned should be passed to free_file_list
|
||||
when it is no longer in use.</div></div><hr>
|
||||
<div id='free_file_list_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.46: free_file_list</h4>
|
||||
<h4>§3.3.50: free_file_list</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->free_file_list(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>File_List list<br></div>)
|
||||
</div>
|
||||
|
@ -950,7 +979,7 @@ when it is no longer in use.</div></div><hr>
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>After this call the file list passed in should not be read or written to.</div></div><hr>
|
||||
<div id='file_exists_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.47: file_exists</h4>
|
||||
<h4>§3.3.51: file_exists</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->file_exists(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *filename,<br>int len<br></div>)
|
||||
</div>
|
||||
|
@ -964,7 +993,7 @@ when it is no longer in use.</div></div><hr>
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero if and only if the file exists.</div></div><hr>
|
||||
<div id='directory_cd_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.48: directory_cd</h4>
|
||||
<h4>§3.3.52: directory_cd</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->directory_cd(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *dir,<br>int *len,<br>int capacity,<br>char *rel_path,<br>int rel_len<br></div>)
|
||||
</div>
|
||||
|
@ -997,7 +1026,7 @@ will contain "C:/Users/MySelf/Documents" and len will contain the length of that
|
|||
string. This call can also be used with rel set to ".." to traverse to parent
|
||||
folders.</div></div><hr>
|
||||
<div id='get_4ed_path_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.49: get_4ed_path</h4>
|
||||
<h4>§3.3.53: get_4ed_path</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->get_4ed_path(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *out,<br>int32_t capacity<br></div>)
|
||||
</div>
|
||||
|
@ -1011,7 +1040,7 @@ folders.</div></div><hr>
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div></div><hr>
|
||||
<div id='show_mouse_cursor_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.3.50: show_mouse_cursor</h4>
|
||||
<h4>§3.3.54: show_mouse_cursor</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->show_mouse_cursor(
|
||||
<div style='margin-left: 4mm;'>Application_Links *app,<br>Mouse_Cursor_Show_Type show<br></div>)
|
||||
</div>
|
||||
|
@ -1110,10 +1139,6 @@ the range [1,16].</div></div><hr>
|
|||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_history_forward unperforms the previous cmdid_history_backward step if possib.e</div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_clean_all_lines</span></span></div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_clean_all_lines deletes extra whitespace out the currently active buffer.</div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_interactive_new</span></span></div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_interactive_new begins an interactive dialogue to create a new buffer.</div></div>
|
||||
</div>
|
||||
|
@ -1207,11 +1232,12 @@ the range [1,16].</div></div><hr>
|
|||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Buffer_Batch_Edit_Type;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>A Buffer_Batch_Edit_Type is a type of batch operation.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Values</i></b></div><div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>BatchEdit_Normal</span></span></div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'></div></div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The BatchEdit_Normal operation is always correct but does the most work.</div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>BatchEdit_PreserveTokens</span></span></div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'></div></div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The BatchEdit_PreserveTokens operation is one in which none of the edits add, delete, or change any tokens.
|
||||
This usually applies when whitespace is being replaced with whitespace.</div></div>
|
||||
</div>
|
||||
</div><hr>
|
||||
<div id='Buffer_Setting_ID_doc' style='margin-bottom: 1cm;'>
|
||||
|
@ -1342,8 +1368,24 @@ Flags can be combined with bit or to specify a state with multiple modifiers.</d
|
|||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'></div></div>
|
||||
</div>
|
||||
</div><hr>
|
||||
<div id='Memory_Protect_Flags_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.17: Memory_Protect_Flags</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Memory_Protect_Flags;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Flags</i></b></div><div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>MemProtect_Read</span> = 0x1</span></div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'></div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>MemProtect_Write</span> = 0x2</span></div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'></div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>MemProtect_Execute</span> = 0x4</span></div>
|
||||
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'></div></div>
|
||||
</div>
|
||||
</div><hr>
|
||||
<div id='Buffer_Create_Flag_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.17: Buffer_Create_Flag</h4>
|
||||
<h4>§3.4.18: Buffer_Create_Flag</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Buffer_Create_Flag;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>A Buffer_Create_Flag field specifies how a buffer should be created.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Flags</i></b></div><div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>BufferCreate_Background</span> = 0x1</span></div>
|
||||
|
@ -1356,7 +1398,7 @@ Flags can be combined with bit or to specify a state with multiple modifiers.</d
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Buffer_Kill_Flag_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.18: Buffer_Kill_Flag</h4>
|
||||
<h4>§3.4.19: Buffer_Kill_Flag</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Buffer_Kill_Flag;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>A Buffer_Kill_Flag field specifies how a buffer should be killed.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Flags</i></b></div><div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>BufferKill_Background</span> = 0x1</span></div>
|
||||
|
@ -1369,7 +1411,7 @@ Flags can be combined with bit or to specify a state with multiple modifiers.</d
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Access_Flag_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.19: Access_Flag</h4>
|
||||
<h4>§3.4.20: Access_Flag</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Access_Flag;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>An Access_Flag field specifies what sort of permission you grant to an
|
||||
access call. An access call is usually one the returns a summary struct. If a
|
||||
|
@ -1399,7 +1441,7 @@ that protection flag, the object is still returned from the access call.</div><d
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Seek_Boundary_Flag_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.20: Seek_Boundary_Flag</h4>
|
||||
<h4>§3.4.21: Seek_Boundary_Flag</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Seek_Boundary_Flag;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>A Seek_Boundary_Flag field specifies a set of "boundary" types used in seeks for the
|
||||
beginning or end of different types of words.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Flags</i></b></div><div>
|
||||
|
@ -1420,7 +1462,7 @@ beginning or end of different types of words.</div><div style='margin-top: 3mm;
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Command_Line_Input_Flag_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.21: Command_Line_Input_Flag</h4>
|
||||
<h4>§3.4.22: Command_Line_Input_Flag</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Command_Line_Input_Flag;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>A Command_Line_Input_Flag field specifies the behavior of a call to a command line interface.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Flags</i></b></div><div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>CLI_OverlapWithConflict</span> = 0x1</span></div>
|
||||
|
@ -1441,7 +1483,7 @@ beginning or end of different types of words.</div><div style='margin-top: 3mm;
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Auto_Indent_Flag_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.22: Auto_Indent_Flag</h4>
|
||||
<h4>§3.4.23: Auto_Indent_Flag</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Auto_Indent_Flag;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>An Auto_Indent_Flag field specifies the behavior of an auto indentation operation.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Flags</i></b></div><div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>AutoIndent_ClearLine</span> = 0x1</span></div>
|
||||
|
@ -1457,7 +1499,7 @@ beginning or end of different types of words.</div><div style='margin-top: 3mm;
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Set_Buffer_Flag_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.23: Set_Buffer_Flag</h4>
|
||||
<h4>§3.4.24: Set_Buffer_Flag</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Set_Buffer_Flag;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>A Set_Buffer_Flag field specifies the behavior of an operation that sets the buffer of a view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Flags</i></b></div><div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>SetBuffer_KeepOriginalGUI</span> = 0x1</span></div>
|
||||
|
@ -1467,7 +1509,7 @@ beginning or end of different types of words.</div><div style='margin-top: 3mm;
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Input_Type_Flag_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.24: Input_Type_Flag</h4>
|
||||
<h4>§3.4.25: Input_Type_Flag</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>enum Input_Type_Flag;</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>A Input_Type_Flag field specifies a set of input event types.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Flags</i></b></div><div>
|
||||
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>EventOnAnyKey</span> = 0x1</span></div>
|
||||
|
@ -1507,7 +1549,7 @@ beginning or end of different types of words.</div><div style='margin-top: 3mm;
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Generic_Command_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.25: Generic_Command</h4>
|
||||
<h4>§3.4.26: Generic_Command</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>union Generic_Command {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
Command_ID cmdid;<br>
|
||||
|
@ -1528,7 +1570,7 @@ internal command or a custom command.</div><div style='margin-top: 3mm; margin-b
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Key_Event_Data_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.26: Key_Event_Data</h4>
|
||||
<h4>§3.4.27: Key_Event_Data</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Key_Event_Data {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
Key_Code keycode;<br>
|
||||
|
@ -1562,7 +1604,7 @@ at the time of the event.</div><div style='margin-top: 3mm; margin-bottom: 3mm;
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Mouse_State_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.27: Mouse_State</h4>
|
||||
<h4>§3.4.28: Mouse_State</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Mouse_State {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
char l;<br>
|
||||
|
@ -1622,7 +1664,7 @@ mouse if in the window.</div><div style='margin-top: 3mm; margin-bottom: 3mm; co
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Range_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.28: Range</h4>
|
||||
<h4>§3.4.29: Range</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>union Range {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
struct {<br>
|
||||
|
@ -1662,7 +1704,7 @@ Throughout the API ranges are thought of in the form [min,max</div><div style='m
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='File_Info_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.29: File_Info</h4>
|
||||
<h4>§3.4.30: File_Info</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct File_Info {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
char * filename;<br>
|
||||
|
@ -1685,7 +1727,7 @@ int folder;<br>
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#File_List_doc'>File_List</a></div></div><hr>
|
||||
<div id='File_List_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.30: File_List</h4>
|
||||
<h4>§3.4.31: File_List</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct File_List {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
void * block;<br>
|
||||
|
@ -1713,7 +1755,7 @@ int block_size;<br>
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Buffer_Identifier_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.31: Buffer_Identifier</h4>
|
||||
<h4>§3.4.32: Buffer_Identifier</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Buffer_Identifier {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
char * name;<br>
|
||||
|
@ -1738,7 +1780,7 @@ can either be a name or an id. If the</div><div style='margin-top: 3mm; margin-
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='GUI_Scroll_Vars_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.32: GUI_Scroll_Vars</h4>
|
||||
<h4>§3.4.33: GUI_Scroll_Vars</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct GUI_Scroll_Vars {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
float scroll_y;<br>
|
||||
|
@ -1776,7 +1818,7 @@ int32_t prev_target_x;<br>
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Full_Cursor_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.33: Full_Cursor</h4>
|
||||
<h4>§3.4.34: Full_Cursor</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Full_Cursor {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
int32_t pos;<br>
|
||||
|
@ -1820,7 +1862,7 @@ coordinate system supported by 4coder.</div><div style='margin-top: 3mm; margin-
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
|
||||
<div id='Buffer_Seek_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.34: Buffer_Seek</h4>
|
||||
<h4>§3.4.35: Buffer_Seek</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Buffer_Seek {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
Buffer_Seek_Type type;<br>
|
||||
|
@ -1885,7 +1927,7 @@ for concisely creating Buffer_Seek structs. They can be found in 4coder_buffer_
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_Type_doc'>Buffer_Seek_Type</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
|
||||
<div id='Buffer_Edit_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.35: Buffer_Edit</h4>
|
||||
<h4>§3.4.36: Buffer_Edit</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Buffer_Edit {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
int32_t str_start;<br>
|
||||
|
@ -1915,7 +1957,7 @@ will be replaced into the buffer.</div><div style='margin-top: 3mm; margin-botto
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Buffer_Summary_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.36: Buffer_Summary</h4>
|
||||
<h4>§3.4.37: Buffer_Summary</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Buffer_Summary {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
bool32 exists;<br>
|
||||
|
@ -1990,7 +2032,7 @@ bool32 unwrapped_lines;<br>
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
|
||||
<div id='View_Summary_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.37: View_Summary</h4>
|
||||
<h4>§3.4.38: View_Summary</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct View_Summary {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
bool32 exists;<br>
|
||||
|
@ -2060,7 +2102,7 @@ GUI_Scroll_Vars scroll_vars;<br>
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
|
||||
<div id='User_Input_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.38: User_Input</h4>
|
||||
<h4>§3.4.39: User_Input</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct User_Input {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
User_Input_Type_ID type;<br>
|
||||
|
@ -2097,7 +2139,7 @@ Generic_Command command;<br>
|
|||
</div>
|
||||
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#User_Input_Type_ID_doc'>User_Input_Type_ID</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Generic_Command_doc'>Generic_Command</a></div></div><hr>
|
||||
<div id='Query_Bar_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.39: Query_Bar</h4>
|
||||
<h4>§3.4.40: Query_Bar</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Query_Bar {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
String prompt;<br>
|
||||
|
@ -2116,7 +2158,7 @@ that will be displayed as a drop down bar durring an interactive command.</div><
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Event_Message_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.40: Event_Message</h4>
|
||||
<h4>§3.4.41: Event_Message</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Event_Message {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
int type;<br>
|
||||
|
@ -2129,7 +2171,7 @@ int type;<br>
|
|||
</div>
|
||||
</div><hr>
|
||||
<div id='Theme_Color_doc' style='margin-bottom: 1cm;'>
|
||||
<h4>§3.4.41: Theme_Color</h4>
|
||||
<h4>§3.4.42: Theme_Color</h4>
|
||||
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Theme_Color {<br>
|
||||
<div style='margin-left: 8mm;'>
|
||||
Style_Tag tag;<br>
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#define EXEC_COMMAND_SIG(n) bool32 n(Application_Links *app, Command_ID command_id)
|
||||
#define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Input_Flag flags)
|
||||
#define MEMORY_ALLOC_SIG(n) void* n(Application_Links *app, int32_t size)
|
||||
#define MEMORY_SET_PROTECTION_SIG(n) int32_t n(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags)
|
||||
#define MEMORY_FREE_SIG(n) void n(Application_Links *app, void *mem)
|
||||
#define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, int32_t clipboard_id, char *str, int32_t len)
|
||||
#define CLIPBOARD_COUNT_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id)
|
||||
#define CLIPBOARD_INDEX_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len)
|
||||
#define GET_BUFFER_COUNT_SIG(n) int32_t n(Application_Links *app)
|
||||
#define GET_BUFFER_FIRST_SIG(n) Buffer_Summary n(Application_Links *app, Access_Flag access)
|
||||
#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)
|
||||
|
@ -51,9 +55,13 @@
|
|||
extern "C"{
|
||||
typedef EXEC_COMMAND_SIG(Exec_Command_Function);
|
||||
typedef EXEC_SYSTEM_COMMAND_SIG(Exec_System_Command_Function);
|
||||
typedef MEMORY_ALLOC_SIG(Memory_Alloc_Function);
|
||||
typedef MEMORY_SET_PROTECTION_SIG(Memory_Set_Protection_Function);
|
||||
typedef MEMORY_FREE_SIG(Memory_Free_Function);
|
||||
typedef CLIPBOARD_POST_SIG(Clipboard_Post_Function);
|
||||
typedef CLIPBOARD_COUNT_SIG(Clipboard_Count_Function);
|
||||
typedef CLIPBOARD_INDEX_SIG(Clipboard_Index_Function);
|
||||
typedef GET_BUFFER_COUNT_SIG(Get_Buffer_Count_Function);
|
||||
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);
|
||||
|
@ -105,9 +113,13 @@ struct Application_Links{
|
|||
int memory_size;
|
||||
Exec_Command_Function *exec_command;
|
||||
Exec_System_Command_Function *exec_system_command;
|
||||
Memory_Alloc_Function *memory_alloc;
|
||||
Memory_Set_Protection_Function *memory_set_protection;
|
||||
Memory_Free_Function *memory_free;
|
||||
Clipboard_Post_Function *clipboard_post;
|
||||
Clipboard_Count_Function *clipboard_count;
|
||||
Clipboard_Index_Function *clipboard_index;
|
||||
Get_Buffer_Count_Function *get_buffer_count;
|
||||
Get_Buffer_First_Function *get_buffer_first;
|
||||
Get_Buffer_Next_Function *get_buffer_next;
|
||||
Get_Buffer_Function *get_buffer;
|
||||
|
@ -161,9 +173,13 @@ struct Application_Links{
|
|||
#define FillAppLinksAPI(app_links) do{\
|
||||
app_links->exec_command = Exec_Command;\
|
||||
app_links->exec_system_command = Exec_System_Command;\
|
||||
app_links->memory_alloc = Memory_Alloc;\
|
||||
app_links->memory_set_protection = Memory_Set_Protection;\
|
||||
app_links->memory_free = Memory_Free;\
|
||||
app_links->clipboard_post = Clipboard_Post;\
|
||||
app_links->clipboard_count = Clipboard_Count;\
|
||||
app_links->clipboard_index = Clipboard_Index;\
|
||||
app_links->get_buffer_count = Get_Buffer_Count;\
|
||||
app_links->get_buffer_first = Get_Buffer_First;\
|
||||
app_links->get_buffer_next = Get_Buffer_Next;\
|
||||
app_links->get_buffer = Get_Buffer;\
|
||||
|
|
|
@ -11,6 +11,414 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
//
|
||||
// Memory
|
||||
//
|
||||
|
||||
static Partition scratch;
|
||||
|
||||
|
||||
//
|
||||
// Buffer Streaming
|
||||
//
|
||||
|
||||
struct Stream_Chunk{
|
||||
Application_Links *app;
|
||||
Buffer_Summary *buffer;
|
||||
|
||||
char *base_data;
|
||||
int start, end;
|
||||
int min_start, max_end;
|
||||
int data_size;
|
||||
|
||||
char *data;
|
||||
};
|
||||
|
||||
int
|
||||
round_down(int x, int b){
|
||||
int r = 0;
|
||||
if (x >= 0){
|
||||
r = x - (x % b);
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
int
|
||||
round_up(int x, int b){
|
||||
int r = 0;
|
||||
if (x >= 0){
|
||||
r = x - (x % b) + b;
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
void
|
||||
refresh_buffer(Application_Links *app, Buffer_Summary *buffer){
|
||||
*buffer = app->get_buffer(app, buffer->buffer_id, AccessAll);
|
||||
}
|
||||
|
||||
void
|
||||
refresh_view(Application_Links *app, View_Summary *view){
|
||||
*view = app->get_view(app, view->view_id, AccessAll);
|
||||
}
|
||||
|
||||
int
|
||||
init_stream_chunk(Stream_Chunk *chunk,
|
||||
Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char *data, int size){
|
||||
int result = false;
|
||||
|
||||
refresh_buffer(app, buffer);
|
||||
if (pos >= 0 && pos < buffer->size && size > 0){
|
||||
chunk->app = app;
|
||||
chunk->buffer = buffer;
|
||||
chunk->base_data = data;
|
||||
chunk->data_size = size;
|
||||
chunk->start = round_down(pos, size);
|
||||
chunk->end = round_up(pos, size);
|
||||
|
||||
if (chunk->max_end > buffer->size
|
||||
|| chunk->max_end == 0){
|
||||
chunk->max_end = buffer->size;
|
||||
}
|
||||
|
||||
if (chunk->max_end && chunk->max_end < chunk->end){
|
||||
chunk->end = chunk->max_end;
|
||||
}
|
||||
if (chunk->min_start && chunk->min_start > chunk->start){
|
||||
chunk->start = chunk->min_start;
|
||||
}
|
||||
|
||||
if (chunk->start < chunk->end){
|
||||
app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data);
|
||||
chunk->data = chunk->base_data - chunk->start;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
int
|
||||
forward_stream_chunk(Stream_Chunk *chunk){
|
||||
Application_Links *app = chunk->app;
|
||||
Buffer_Summary *buffer = chunk->buffer;
|
||||
int result = false;
|
||||
|
||||
refresh_buffer(app, buffer);
|
||||
if (chunk->end < buffer->size){
|
||||
chunk->start = chunk->end;
|
||||
chunk->end += chunk->data_size;
|
||||
|
||||
if (chunk->max_end && chunk->max_end < chunk->end){
|
||||
chunk->end = chunk->max_end;
|
||||
}
|
||||
if (chunk->min_start && chunk->min_start > chunk->start){
|
||||
chunk->start = chunk->min_start;
|
||||
}
|
||||
|
||||
if (chunk->start < chunk->end){
|
||||
app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data);
|
||||
chunk->data = chunk->base_data - chunk->start;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
int
|
||||
backward_stream_chunk(Stream_Chunk *chunk){
|
||||
Application_Links *app = chunk->app;
|
||||
Buffer_Summary *buffer = chunk->buffer;
|
||||
int result = false;
|
||||
|
||||
refresh_buffer(app, buffer);
|
||||
if (chunk->start > 0){
|
||||
chunk->end = chunk->start;
|
||||
chunk->start -= chunk->data_size;
|
||||
|
||||
if (chunk->max_end && chunk->max_end < chunk->end){
|
||||
chunk->end = chunk->max_end;
|
||||
}
|
||||
if (chunk->min_start && chunk->min_start > chunk->start){
|
||||
chunk->start = chunk->min_start;
|
||||
}
|
||||
|
||||
if (chunk->start < chunk->end){
|
||||
app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data);
|
||||
chunk->data = chunk->base_data - chunk->start;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_seek_delimiter_forward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char delim, int *result){
|
||||
if (buffer->exists){
|
||||
char chunk[1024];
|
||||
int size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos < stream.end; ++pos){
|
||||
char at_pos = stream.data[pos];
|
||||
if (at_pos == delim){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
still_looping = forward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = buffer->size;
|
||||
|
||||
finished:;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_seek_delimiter_backward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char delim, int *result){
|
||||
if (buffer->exists){
|
||||
char chunk[1024];
|
||||
int size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos >= stream.start; --pos){
|
||||
char at_pos = stream.data[pos];
|
||||
if (at_pos == delim){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
still_looping = backward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = 0;
|
||||
|
||||
finished:;
|
||||
}
|
||||
|
||||
// TODO(allen): This duplication is driving me crazy... I've gotta
|
||||
// upgrade the meta programming system another level.
|
||||
|
||||
// NOTE(allen): This is limitted to a string size of 512.
|
||||
// You can push it up or do something more clever by just
|
||||
// replacing char read_buffer[512]; with more memory.
|
||||
void
|
||||
buffer_seek_string_forward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, int end, char *str, int size, int *result){
|
||||
char read_buffer[512];
|
||||
|
||||
if (size <= 0){
|
||||
*result = pos;
|
||||
}
|
||||
else if (size > sizeof(read_buffer)){
|
||||
*result = pos;
|
||||
}
|
||||
else{
|
||||
if (buffer->exists){
|
||||
String read_str = make_fixed_width_string(read_buffer);
|
||||
String needle_str = make_string(str, size);
|
||||
char first_char = str[0];
|
||||
|
||||
read_str.size = size;
|
||||
|
||||
char chunk[1024];
|
||||
int chunk_size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
stream.max_end = end;
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos < stream.end; ++pos){
|
||||
char at_pos = stream.data[pos];
|
||||
if (at_pos == first_char){
|
||||
app->buffer_read_range(app, buffer, pos, pos+size, read_buffer);
|
||||
if (match(needle_str, read_str)){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
still_looping = forward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
if (end == 0){
|
||||
*result = buffer->size;
|
||||
}
|
||||
else{
|
||||
*result = end;
|
||||
}
|
||||
|
||||
finished:;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): This is limitted to a string size of 512.
|
||||
// You can push it up or do something more clever by just
|
||||
// replacing char read_buffer[512]; with more memory.
|
||||
void
|
||||
buffer_seek_string_backward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, int min, char *str, int size, int *result){
|
||||
char read_buffer[512];
|
||||
if (size <= 0){
|
||||
*result = min-1;
|
||||
}
|
||||
else if (size > sizeof(read_buffer)){
|
||||
*result = min-1;
|
||||
}
|
||||
else{
|
||||
if (buffer->exists){
|
||||
String read_str = make_fixed_width_string(read_buffer);
|
||||
String needle_str = make_string(str, size);
|
||||
char first_char = str[0];
|
||||
|
||||
read_str.size = size;
|
||||
|
||||
char chunk[1024];
|
||||
int chunk_size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
stream.min_start = min;
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos >= stream.start; --pos){
|
||||
char at_pos = stream.data[pos];
|
||||
if (at_pos == first_char){
|
||||
app->buffer_read_range(app, buffer, pos, pos+size, read_buffer);
|
||||
if (match(needle_str, read_str)){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
still_looping = backward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = min-1;
|
||||
|
||||
finished:;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): This is limitted to a string size of 512.
|
||||
// You can push it up or do something more clever by just
|
||||
// replacing char read_buffer[512]; with more memory.
|
||||
void
|
||||
buffer_seek_string_insensitive_forward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char *str, int size, int *result){
|
||||
char read_buffer[512];
|
||||
char chunk[1024];
|
||||
int chunk_size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (size <= 0){
|
||||
*result = buffer->size;
|
||||
}
|
||||
else if (size > sizeof(read_buffer)){
|
||||
*result = buffer->size;
|
||||
}
|
||||
else{
|
||||
if (buffer->exists){
|
||||
String read_str = make_fixed_width_string(read_buffer);
|
||||
String needle_str = make_string(str, size);
|
||||
char first_char = char_to_upper(str[0]);
|
||||
|
||||
read_str.size = size;
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos < stream.end; ++pos){
|
||||
char at_pos = char_to_upper(stream.data[pos]);
|
||||
if (at_pos == first_char){
|
||||
app->buffer_read_range(app, buffer, pos, pos+size, read_buffer);
|
||||
if (match_insensitive(needle_str, read_str)){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
still_looping = forward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = buffer->size;
|
||||
|
||||
finished:;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): This is limitted to a string size of 512.
|
||||
// You can push it up or do something more clever by just
|
||||
// replacing char read_buffer[512]; with more memory.
|
||||
void
|
||||
buffer_seek_string_insensitive_backward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char *str, int size, int *result){
|
||||
char read_buffer[512];
|
||||
char chunk[1024];
|
||||
int chunk_size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (size <= 0){
|
||||
*result = -1;
|
||||
}
|
||||
else if (size > sizeof(read_buffer)){
|
||||
*result = -1;
|
||||
}
|
||||
else{
|
||||
if (buffer->exists){
|
||||
String read_str = make_fixed_width_string(read_buffer);
|
||||
String needle_str = make_string(str, size);
|
||||
char first_char = char_to_upper(str[0]);
|
||||
|
||||
read_str.size = size;
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos >= stream.start; --pos){
|
||||
char at_pos = char_to_upper(stream.data[pos]);
|
||||
if (at_pos == first_char){
|
||||
app->buffer_read_range(app, buffer, pos, pos+size, read_buffer);
|
||||
if (match_insensitive(needle_str, read_str)){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
still_looping = backward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = -1;
|
||||
|
||||
finished:;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Fundamental Editing
|
||||
//
|
||||
|
||||
inline float
|
||||
get_view_y(View_Summary view){
|
||||
float y = view.cursor.wrapped_y;
|
||||
|
@ -29,10 +437,6 @@ get_view_x(View_Summary view){
|
|||
return(x);
|
||||
}
|
||||
|
||||
//
|
||||
// Fundamental Editing
|
||||
//
|
||||
|
||||
CUSTOM_COMMAND_SIG(write_character){
|
||||
unsigned int access = AccessOpen;
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
@ -304,6 +708,12 @@ CUSTOM_COMMAND_SIG(cut){
|
|||
clipboard_cut(app, range.min, range.max, 0, access);
|
||||
}
|
||||
|
||||
enum Rewrite_Type{
|
||||
RewriteNone,
|
||||
RewritePaste,
|
||||
RewriteWordComplete
|
||||
};
|
||||
|
||||
struct View_Paste_Index{
|
||||
int rewrite;
|
||||
int next_rewrite;
|
||||
|
@ -319,7 +729,7 @@ CUSTOM_COMMAND_SIG(paste){
|
|||
if (count > 0){
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
view_paste_index[view.view_id].next_rewrite = true;
|
||||
view_paste_index[view.view_id].next_rewrite = RewritePaste;
|
||||
|
||||
int paste_index = 0;
|
||||
view_paste_index[view.view_id].index = paste_index;
|
||||
|
@ -355,11 +765,8 @@ CUSTOM_COMMAND_SIG(paste_next){
|
|||
if (count > 0){
|
||||
View_Summary view = app->get_active_view(app, access);
|
||||
|
||||
// NOTE(allen): THIS is a very temporary poop-sauce
|
||||
// system that I just threw in to get this working.
|
||||
// Please don't start calling it anywhere.
|
||||
if (view_paste_index[view.view_id].rewrite){
|
||||
view_paste_index[view.view_id].next_rewrite = true;
|
||||
if (view_paste_index[view.view_id].rewrite == RewritePaste){
|
||||
view_paste_index[view.view_id].next_rewrite = RewritePaste;
|
||||
|
||||
int paste_index = view_paste_index[view.view_id].index + 1;
|
||||
view_paste_index[view.view_id].index = paste_index;
|
||||
|
@ -823,8 +1230,9 @@ CUSTOM_COMMAND_SIG(if0_off){
|
|||
move_past_lead_whitespace(app, &view, &buffer);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Fast Deletes
|
||||
//
|
||||
|
||||
CUSTOM_COMMAND_SIG(backspace_word){
|
||||
|
@ -1009,6 +1417,28 @@ CUSTOM_COMMAND_SIG(open_file_in_quotes_regular){
|
|||
# define open_file_in_quotes open_file_in_quotes_regular
|
||||
#endif
|
||||
|
||||
CUSTOM_COMMAND_SIG(open_in_other_regular){
|
||||
exec_command(app, change_active_panel_regular);
|
||||
exec_command(app, cmdid_interactive_open);
|
||||
}
|
||||
|
||||
// TODO(allen): This is a bit nasty. I want a system for picking
|
||||
// the most advanced and correct version of a command to bind to a
|
||||
// name based on which files are included.
|
||||
#ifndef OPEN_IN_OTHER
|
||||
# define OPEN_IN_OTHER 1
|
||||
#elif OPEN_IN_OTHER <= 1
|
||||
# undef OPEN_IN_OTHER
|
||||
# define OPEN_IN_OTHER 1
|
||||
#endif
|
||||
|
||||
#if OPEN_IN_OTHER <= 1
|
||||
# ifdef open_in_other
|
||||
# undef open_in_other
|
||||
# endif
|
||||
# define open_in_other open_in_other_regular
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
CUSTOM_COMMAND_SIG(save_as){
|
||||
|
@ -1018,15 +1448,14 @@ CUSTOM_COMMAND_SIG(save_as){
|
|||
CUSTOM_COMMAND_SIG(goto_line){
|
||||
unsigned int access = AccessProtected;
|
||||
|
||||
int line_number;
|
||||
Query_Bar bar;
|
||||
Query_Bar bar = {0};
|
||||
char string_space[256];
|
||||
|
||||
bar.prompt = make_lit_string("Goto Line: ");
|
||||
bar.string = make_fixed_width_string(string_space);
|
||||
|
||||
if (query_user_number(app, &bar)){
|
||||
line_number = str_to_int(bar.string);
|
||||
int line_number = str_to_int(bar.string);
|
||||
active_view_to_line(app, access, line_number);
|
||||
}
|
||||
}
|
||||
|
@ -1070,6 +1499,7 @@ isearch(Application_Links *app, int start_reversed){
|
|||
|
||||
// NOTE(allen): If we're getting mouse events here it's a 4coder bug, because we
|
||||
// only asked to intercept key events.
|
||||
|
||||
assert(in.type == UserInputKey);
|
||||
|
||||
int made_change = 0;
|
||||
|
@ -1095,7 +1525,7 @@ isearch(Application_Links *app, int start_reversed){
|
|||
if ((in.command.command == reverse_search) ||
|
||||
in.key.keycode == key_page_up || in.key.keycode == key_up) step_backward = 1;
|
||||
|
||||
int start_pos = pos;
|
||||
start_pos = pos;
|
||||
if (step_forward && reverse){
|
||||
start_pos = match.start + 1;
|
||||
pos = start_pos;
|
||||
|
@ -1158,11 +1588,11 @@ isearch(Application_Links *app, int start_reversed){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(search){
|
||||
isearch(app, 0);
|
||||
isearch(app, false);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(reverse_search){
|
||||
isearch(app, 1);
|
||||
isearch(app, true);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(replace_in_range){
|
||||
|
@ -1193,14 +1623,15 @@ CUSTOM_COMMAND_SIG(replace_in_range){
|
|||
|
||||
int pos, new_pos;
|
||||
pos = range.min;
|
||||
buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos);
|
||||
|
||||
buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos);
|
||||
|
||||
while (new_pos + r.size <= range.end){
|
||||
app->buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size);
|
||||
refresh_view(app, &view);
|
||||
range = get_range(&view);
|
||||
pos = new_pos + w.size;
|
||||
buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos);
|
||||
buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1239,7 +1670,7 @@ CUSTOM_COMMAND_SIG(query_replace){
|
|||
buffer = app->get_buffer(app, view.buffer_id, access);
|
||||
|
||||
pos = view.cursor.pos;
|
||||
buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos);
|
||||
buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos);
|
||||
|
||||
User_Input in = {0};
|
||||
while (new_pos < buffer.size){
|
||||
|
@ -1260,7 +1691,7 @@ CUSTOM_COMMAND_SIG(query_replace){
|
|||
pos = match.max;
|
||||
}
|
||||
|
||||
buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos);
|
||||
buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos);
|
||||
}
|
||||
|
||||
app->view_set_highlight(app, &view, 0, 0, 0);
|
||||
|
@ -1269,6 +1700,10 @@ CUSTOM_COMMAND_SIG(query_replace){
|
|||
app->view_set_cursor(app, &view, seek_pos(pos), 1);
|
||||
}
|
||||
|
||||
//
|
||||
// Fast Buffer Management
|
||||
//
|
||||
|
||||
CUSTOM_COMMAND_SIG(close_all_code){
|
||||
String extension;
|
||||
Buffer_Summary buffer;
|
||||
|
@ -1340,8 +1775,8 @@ char command_space[1024];
|
|||
char hot_directory_space[1024];
|
||||
|
||||
CUSTOM_COMMAND_SIG(execute_any_cli){
|
||||
Query_Bar bar_out, bar_cmd;
|
||||
String hot_directory;
|
||||
Query_Bar bar_out = {0};
|
||||
Query_Bar bar_cmd = {0};
|
||||
|
||||
bar_out.prompt = make_lit_string("Output Buffer: ");
|
||||
bar_out.string = make_fixed_width_string(out_buffer_space);
|
||||
|
@ -1351,7 +1786,7 @@ CUSTOM_COMMAND_SIG(execute_any_cli){
|
|||
bar_cmd.string = make_fixed_width_string(command_space);
|
||||
if (!query_user_string(app, &bar_cmd)) return;
|
||||
|
||||
hot_directory = make_fixed_width_string(hot_directory_space);
|
||||
String hot_directory = make_fixed_width_string(hot_directory_space);
|
||||
hot_directory.size = app->directory_get_hot(app, hot_directory.str, hot_directory.memory_size);
|
||||
|
||||
unsigned int access = AccessAll;
|
||||
|
@ -1365,11 +1800,9 @@ CUSTOM_COMMAND_SIG(execute_any_cli){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(execute_previous_cli){
|
||||
String out_buffer, cmd, hot_directory;
|
||||
|
||||
out_buffer = make_string_slowly(out_buffer_space);
|
||||
cmd = make_string_slowly(command_space);
|
||||
hot_directory = make_string_slowly(hot_directory_space);
|
||||
String out_buffer = make_string_slowly(out_buffer_space);
|
||||
String cmd = make_string_slowly(command_space);
|
||||
String hot_directory = make_string_slowly(hot_directory_space);
|
||||
|
||||
if (out_buffer.size > 0 && cmd.size > 0 && hot_directory.size > 0){
|
||||
unsigned int access = AccessAll;
|
||||
|
@ -1383,28 +1816,6 @@ CUSTOM_COMMAND_SIG(execute_previous_cli){
|
|||
}
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(open_in_other_regular){
|
||||
exec_command(app, change_active_panel_regular);
|
||||
exec_command(app, cmdid_interactive_open);
|
||||
}
|
||||
|
||||
// TODO(allen): This is a bit nasty. I want a system for picking
|
||||
// the most advanced and correct version of a command to bind to a
|
||||
// name based on which files are included.
|
||||
#ifndef OPEN_IN_OTHER
|
||||
# define OPEN_IN_OTHER 1
|
||||
#elif OPEN_IN_OTHER <= 1
|
||||
# undef OPEN_IN_OTHER
|
||||
# define OPEN_IN_OTHER 1
|
||||
#endif
|
||||
|
||||
#if OPEN_IN_OTHER <= 1
|
||||
# ifdef open_in_other
|
||||
# undef open_in_other
|
||||
# endif
|
||||
# define open_in_other open_in_other_regular
|
||||
#endif
|
||||
|
||||
//
|
||||
// Auto Indenting and Whitespace
|
||||
//
|
||||
|
@ -1515,8 +1926,8 @@ CUSTOM_COMMAND_SIG(clean_all_lines){
|
|||
|
||||
// NOTE(allen|a4.0.9): This is provided to establish a default method of getting
|
||||
// a "build directory". This function tries to setup the build directory in the
|
||||
// directory of the given buffer, it cannot it get's the 4coder hot directory.
|
||||
// This behavior is a little different than previous versions of 4coder.
|
||||
// directory of the given buffer, if it cannot get that information it get's the
|
||||
// 4coder hot directory.
|
||||
//
|
||||
// There is no requirement that a custom build system in 4coder actually use the
|
||||
// directory given by this function.
|
||||
|
@ -1674,8 +2085,8 @@ execute_standard_build(Application_Links *app, View_Summary *view,
|
|||
char dir_space[512];
|
||||
String dir = make_fixed_width_string(dir_space);
|
||||
|
||||
char command_space[512];
|
||||
String command = make_fixed_width_string(command_space);
|
||||
char command_str_space[512];
|
||||
String command = make_fixed_width_string(command_str_space);
|
||||
|
||||
int build_dir_type = get_build_directory(app, active_buffer, &dir);
|
||||
|
||||
|
@ -1750,6 +2161,193 @@ CUSTOM_COMMAND_SIG(eol_nixify){
|
|||
app->buffer_set_setting(app, &buffer, BufferSetting_Eol, false);
|
||||
}
|
||||
|
||||
//
|
||||
// "Full Search" Based Commands
|
||||
//
|
||||
|
||||
#include "4coder_table.cpp"
|
||||
#include "4coder_search.cpp"
|
||||
|
||||
struct Word_Complete_State{
|
||||
Search_Set set;
|
||||
Search_Iter iter;
|
||||
Table hits;
|
||||
String_Space str;
|
||||
int word_start;
|
||||
int word_end;
|
||||
int initialized;
|
||||
};
|
||||
|
||||
static Word_Complete_State complete_state = {0};
|
||||
|
||||
CUSTOM_COMMAND_SIG(word_complete){
|
||||
View_Summary view = app->get_active_view(app, AccessOpen);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, AccessOpen);
|
||||
|
||||
// NOTE(allen): I just do this because this command is a lot of work
|
||||
// and there is no point in doing any of it if nothing will happen anyway.
|
||||
if (buffer.exists){
|
||||
int do_init = false;
|
||||
|
||||
if (view_paste_index[view.view_id].rewrite != RewriteWordComplete){
|
||||
do_init = true;
|
||||
}
|
||||
view_paste_index[view.view_id].next_rewrite != RewriteWordComplete;
|
||||
if (!complete_state.initialized){
|
||||
do_init = true;
|
||||
}
|
||||
|
||||
int word_end = 0;
|
||||
int word_start = 0;
|
||||
int cursor_pos = 0;
|
||||
int size = 0;
|
||||
|
||||
if (do_init){
|
||||
// NOTE(allen): Get the range where the
|
||||
// partial word is written.
|
||||
word_end = view.cursor.pos;
|
||||
word_start = word_end;
|
||||
cursor_pos = word_end - 1;
|
||||
|
||||
char space[1024];
|
||||
Stream_Chunk chunk = {0};
|
||||
if (init_stream_chunk(&chunk, app, &buffer,
|
||||
cursor_pos, space, sizeof(space))){
|
||||
int still_looping = true;
|
||||
do{
|
||||
for (; cursor_pos >= chunk.start; --cursor_pos){
|
||||
char c = chunk.data[cursor_pos];
|
||||
if (char_is_alpha(c)){
|
||||
word_start = cursor_pos;
|
||||
}
|
||||
else if (!char_is_numeric(c)){
|
||||
goto double_break;
|
||||
}
|
||||
}
|
||||
still_looping = backward_stream_chunk(&chunk);
|
||||
}while(still_looping);
|
||||
}
|
||||
double_break:;
|
||||
|
||||
size = word_end - word_start;
|
||||
|
||||
if (size == 0){
|
||||
complete_state.initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(allen): Initialize the search iterator
|
||||
// with the partial word.
|
||||
complete_state.initialized = true;
|
||||
search_iter_init(app, &complete_state.iter, size);
|
||||
app->buffer_read_range(app, &buffer, word_start, word_end,
|
||||
complete_state.iter.word.str);
|
||||
complete_state.iter.word.size = size;
|
||||
|
||||
// NOTE(allen): Initialize the set of ranges
|
||||
// to be searched.
|
||||
int buffer_count = app->get_buffer_count(app);
|
||||
search_set_init(app, &complete_state.set, buffer_count);
|
||||
|
||||
Search_Range *ranges = complete_state.set.ranges;
|
||||
ranges[0].type = SearchRange_Wave;
|
||||
ranges[0].buffer = buffer.buffer_id;
|
||||
ranges[0].start = 0;
|
||||
ranges[0].size = buffer.size;
|
||||
ranges[0].mid_start = word_start;
|
||||
ranges[0].mid_size = size;
|
||||
|
||||
int j = 1;
|
||||
for (Buffer_Summary buffer_it = app->get_buffer_first(app, AccessAll);
|
||||
buffer_it.exists;
|
||||
app->get_buffer_next(app, &buffer_it, AccessAll)){
|
||||
if (buffer.buffer_id != buffer_it.buffer_id){
|
||||
ranges[j].type = SearchRange_FrontToBack;
|
||||
ranges[j].buffer = buffer_it.buffer_id;
|
||||
ranges[j].start = 0;
|
||||
ranges[j].size = buffer_it.size;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
complete_state.set.count = j;
|
||||
|
||||
// NOTE(allen): Initialize the search hit table.
|
||||
search_hits_init(app, &complete_state.hits, &complete_state.str,
|
||||
100, (4 << 10));
|
||||
search_hit_add(app, &complete_state.hits, &complete_state.str,
|
||||
complete_state.iter.word.str,
|
||||
complete_state.iter.word.size);
|
||||
|
||||
complete_state.word_start = word_start;
|
||||
complete_state.word_end = word_end;
|
||||
}
|
||||
else{
|
||||
word_start = complete_state.word_start;
|
||||
word_end = complete_state.word_end;
|
||||
size = complete_state.iter.word.size;
|
||||
}
|
||||
|
||||
// NOTE(allen): Iterate through matches.
|
||||
if (size > 0){
|
||||
for (;;){
|
||||
int match_size = 0;
|
||||
Search_Match match =
|
||||
search_next_match(app, &complete_state.set,
|
||||
&complete_state.iter);
|
||||
|
||||
if (match.found_match){
|
||||
int match_size = match.end - match.start;
|
||||
char *spare = (char*)GET_MEMORY(match_size);
|
||||
|
||||
app->buffer_read_range(app, &match.buffer,
|
||||
match.start, match.end, spare);
|
||||
|
||||
if (search_hit_add(app, &complete_state.hits, &complete_state.str,
|
||||
spare, match_size)){
|
||||
app->buffer_replace_range(app, &buffer, word_start, word_end,
|
||||
spare, match_size);
|
||||
app->view_set_cursor(app, &view,
|
||||
seek_pos(word_start + match_size),
|
||||
true);
|
||||
|
||||
complete_state.word_end = word_start + match_size;
|
||||
complete_state.set.ranges[0].mid_size = match_size;
|
||||
FREE_MEMORY(spare);
|
||||
break;
|
||||
}
|
||||
FREE_MEMORY(spare);
|
||||
}
|
||||
else{
|
||||
complete_state.iter.pos = 0;
|
||||
complete_state.iter.i = 0;
|
||||
|
||||
search_hits_init(app, &complete_state.hits, &complete_state.str,
|
||||
100, (4 << 10));
|
||||
search_hit_add(app, &complete_state.hits, &complete_state.str,
|
||||
complete_state.iter.word.str,
|
||||
complete_state.iter.word.size);
|
||||
|
||||
match_size = complete_state.iter.word.size;
|
||||
char *str = complete_state.iter.word.str;
|
||||
app->buffer_replace_range(app, &buffer, word_start, word_end,
|
||||
str, match_size);
|
||||
app->view_set_cursor(app, &view,
|
||||
seek_pos(word_start + match_size),
|
||||
true);
|
||||
|
||||
complete_state.word_end = word_start + match_size;
|
||||
complete_state.set.ranges[0].mid_size = match_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
CUSTOM_COMMAND_SIG(execute_arbitrary_command){
|
||||
// NOTE(allen): This isn't a super powerful version of this command, I will expand
|
||||
// upon it so that it has all the cmdid_* commands by default. However, with this
|
||||
|
|
360
4coder_helper.h
360
4coder_helper.h
|
@ -417,365 +417,13 @@ get_active_buffer(Application_Links *app, unsigned int access){
|
|||
return(buffer);
|
||||
}
|
||||
|
||||
|
||||
struct Stream_Chunk{
|
||||
Application_Links *app;
|
||||
Buffer_Summary *buffer;
|
||||
|
||||
char *base_data;
|
||||
int start, end;
|
||||
int data_size;
|
||||
|
||||
char *data;
|
||||
};
|
||||
|
||||
int
|
||||
round_down(int x, int b){
|
||||
int r = 0;
|
||||
if (x >= 0){
|
||||
r = x - (x % b);
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
int
|
||||
round_up(int x, int b){
|
||||
int r = 0;
|
||||
if (x >= 0){
|
||||
r = x - (x % b) + b;
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
void
|
||||
refresh_buffer(Application_Links *app, Buffer_Summary *buffer){
|
||||
*buffer = app->get_buffer(app, buffer->buffer_id, AccessAll);
|
||||
}
|
||||
|
||||
void
|
||||
refresh_view(Application_Links *app, View_Summary *view){
|
||||
*view = app->get_view(app, view->view_id, AccessAll);
|
||||
}
|
||||
|
||||
int
|
||||
init_stream_chunk(Stream_Chunk *chunk,
|
||||
Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char *data, int size){
|
||||
int result = 0;
|
||||
|
||||
refresh_buffer(app, buffer);
|
||||
if (pos >= 0 && pos < buffer->size && size > 0){
|
||||
result = 1;
|
||||
chunk->app = app;
|
||||
chunk->buffer = buffer;
|
||||
chunk->base_data = data;
|
||||
chunk->data_size = size;
|
||||
chunk->start = round_down(pos, size);
|
||||
chunk->end = round_up(pos, size);
|
||||
if (chunk->end > buffer->size){
|
||||
chunk->end = buffer->size;
|
||||
}
|
||||
app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data);
|
||||
chunk->data = chunk->base_data - chunk->start;
|
||||
}
|
||||
inline char
|
||||
buffer_get_char(Application_Links *app, Buffer_Summary *buffer, int pos){
|
||||
char result = 0;
|
||||
app->buffer_read_range(app, buffer, pos, pos+1, &result);
|
||||
return(result);
|
||||
}
|
||||
|
||||
int
|
||||
forward_stream_chunk(Stream_Chunk *chunk){
|
||||
Application_Links *app = chunk->app;
|
||||
Buffer_Summary *buffer = chunk->buffer;
|
||||
int result = 0;
|
||||
|
||||
refresh_buffer(app, buffer);
|
||||
if (chunk->end < buffer->size){
|
||||
result = 1;
|
||||
chunk->start = chunk->end;
|
||||
chunk->end += chunk->data_size;
|
||||
if (chunk->end > buffer->size){
|
||||
chunk->end = buffer->size;
|
||||
}
|
||||
app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data);
|
||||
chunk->data = chunk->base_data - chunk->start;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
int
|
||||
backward_stream_chunk(Stream_Chunk *chunk){
|
||||
Application_Links *app = chunk->app;
|
||||
Buffer_Summary *buffer = chunk->buffer;
|
||||
int result = 0;
|
||||
|
||||
refresh_buffer(app, buffer);
|
||||
if (chunk->start > 0){
|
||||
result = 1;
|
||||
chunk->end = chunk->start;
|
||||
chunk->start -= chunk->data_size;
|
||||
if (chunk->start < 0){
|
||||
chunk->start = 0;
|
||||
}
|
||||
app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data);
|
||||
chunk->data = chunk->base_data - chunk->start;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_seek_delimiter_forward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char delim, int *result){
|
||||
if (buffer->exists){
|
||||
char chunk[1024];
|
||||
int size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos < stream.end; ++pos){
|
||||
char at_pos = stream.data[pos];
|
||||
if (at_pos == delim){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
still_looping = forward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = buffer->size;
|
||||
|
||||
finished:;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_seek_delimiter_backward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char delim, int *result){
|
||||
if (buffer->exists){
|
||||
char chunk[1024];
|
||||
int size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos >= stream.start; --pos){
|
||||
char at_pos = stream.data[pos];
|
||||
if (at_pos == delim){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
still_looping = backward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = 0;
|
||||
|
||||
finished:;
|
||||
}
|
||||
|
||||
// TODO(allen): This duplication is driving me crazy... I've gotta
|
||||
// upgrade the meta programming system another level.
|
||||
|
||||
// NOTE(allen): This is limitted to a string size of 512.
|
||||
// You can push it up or do something more clever by just
|
||||
// replacing char read_buffer[512]; with more memory.
|
||||
void
|
||||
buffer_seek_string_forward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char *str, int size, int *result){
|
||||
char read_buffer[512];
|
||||
char chunk[1024];
|
||||
int chunk_size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (size <= 0){
|
||||
*result = pos;
|
||||
}
|
||||
else if (size > sizeof(read_buffer)){
|
||||
*result = pos;
|
||||
}
|
||||
else{
|
||||
if (buffer->exists){
|
||||
String read_str = make_fixed_width_string(read_buffer);
|
||||
String needle_str = make_string(str, size);
|
||||
char first_char = str[0];
|
||||
|
||||
read_str.size = size;
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos < stream.end; ++pos){
|
||||
char at_pos = stream.data[pos];
|
||||
if (at_pos == first_char){
|
||||
app->buffer_read_range(app, buffer, pos, pos+size, read_buffer);
|
||||
if (match(needle_str, read_str)){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
still_looping = forward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = buffer->size;
|
||||
|
||||
finished:;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): This is limitted to a string size of 512.
|
||||
// You can push it up or do something more clever by just
|
||||
// replacing char read_buffer[512]; with more memory.
|
||||
void
|
||||
buffer_seek_string_backward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char *str, int size, int *result){
|
||||
char read_buffer[512];
|
||||
char chunk[1024];
|
||||
int chunk_size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (size <= 0){
|
||||
*result = 0;
|
||||
}
|
||||
else if (size > sizeof(read_buffer)){
|
||||
*result = 0;
|
||||
}
|
||||
else{
|
||||
if (buffer->exists){
|
||||
String read_str = make_fixed_width_string(read_buffer);
|
||||
String needle_str = make_string(str, size);
|
||||
char first_char = str[0];
|
||||
|
||||
read_str.size = size;
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos >= stream.start; --pos){
|
||||
char at_pos = stream.data[pos];
|
||||
if (at_pos == first_char){
|
||||
app->buffer_read_range(app, buffer, pos, pos+size, read_buffer);
|
||||
if (match(needle_str, read_str)){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
still_looping = backward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = 0;
|
||||
|
||||
finished:;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): This is limitted to a string size of 512.
|
||||
// You can push it up or do something more clever by just
|
||||
// replacing char read_buffer[512]; with more memory.
|
||||
void
|
||||
buffer_seek_string_insensitive_forward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char *str, int size, int *result){
|
||||
char read_buffer[512];
|
||||
char chunk[1024];
|
||||
int chunk_size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (size <= 0){
|
||||
*result = pos;
|
||||
}
|
||||
else if (size > sizeof(read_buffer)){
|
||||
*result = pos;
|
||||
}
|
||||
else{
|
||||
if (buffer->exists){
|
||||
String read_str = make_fixed_width_string(read_buffer);
|
||||
String needle_str = make_string(str, size);
|
||||
char first_char = char_to_upper(str[0]);
|
||||
|
||||
read_str.size = size;
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos < stream.end; ++pos){
|
||||
char at_pos = char_to_upper(stream.data[pos]);
|
||||
if (at_pos == first_char){
|
||||
app->buffer_read_range(app, buffer, pos, pos+size, read_buffer);
|
||||
if (match_insensitive(needle_str, read_str)){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
still_looping = forward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = buffer->size;
|
||||
|
||||
finished:;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): This is limitted to a string size of 512.
|
||||
// You can push it up or do something more clever by just
|
||||
// replacing char read_buffer[512]; with more memory.
|
||||
void
|
||||
buffer_seek_string_insensitive_backward(Application_Links *app, Buffer_Summary *buffer,
|
||||
int pos, char *str, int size, int *result){
|
||||
char read_buffer[512];
|
||||
char chunk[1024];
|
||||
int chunk_size = sizeof(chunk);
|
||||
Stream_Chunk stream = {0};
|
||||
|
||||
if (size <= 0){
|
||||
*result = -1;
|
||||
}
|
||||
else if (size > sizeof(read_buffer)){
|
||||
*result = -1;
|
||||
}
|
||||
else{
|
||||
if (buffer->exists){
|
||||
String read_str = make_fixed_width_string(read_buffer);
|
||||
String needle_str = make_string(str, size);
|
||||
char first_char = char_to_upper(str[0]);
|
||||
|
||||
read_str.size = size;
|
||||
|
||||
if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){
|
||||
int still_looping = 1;
|
||||
do{
|
||||
for(; pos >= stream.start; --pos){
|
||||
char at_pos = char_to_upper(stream.data[pos]);
|
||||
if (at_pos == first_char){
|
||||
app->buffer_read_range(app, buffer, pos, pos+size, read_buffer);
|
||||
if (match_insensitive(needle_str, read_str)){
|
||||
*result = pos;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
still_looping = backward_stream_chunk(&stream);
|
||||
}while (still_looping);
|
||||
}
|
||||
}
|
||||
|
||||
*result = -1;
|
||||
|
||||
finished:;
|
||||
}
|
||||
}
|
||||
|
||||
inline Buffer_Identifier
|
||||
buffer_identifier(char *str, int len){
|
||||
Buffer_Identifier identifier;
|
||||
|
|
174
4coder_mem.h
174
4coder_mem.h
|
@ -72,5 +72,179 @@ end_temp_memory(Temp_Memory temp){
|
|||
((Partition*)temp.handle)->pos = temp.pos;
|
||||
}
|
||||
|
||||
/*
|
||||
NOTE(allen):
|
||||
This is a very week general purpose allocator system.
|
||||
It should only be used for infrequent large allocations (4K+).
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
enum{
|
||||
MEM_BUBBLE_FLAG_INIT = 0x0,
|
||||
MEM_BUBBLE_USED = 0x1,
|
||||
};
|
||||
|
||||
struct Bubble{
|
||||
Bubble *prev;
|
||||
Bubble *next;
|
||||
int32_t size;
|
||||
uint32_t flags;
|
||||
uint32_t _unused_[2];
|
||||
};
|
||||
|
||||
struct General_Memory{
|
||||
Bubble sentinel;
|
||||
};
|
||||
|
||||
struct Mem_Options{
|
||||
Partition part;
|
||||
General_Memory general;
|
||||
};
|
||||
|
||||
inline void
|
||||
insert_bubble(Bubble *prev, Bubble *bubble){
|
||||
bubble->prev = prev;
|
||||
bubble->next = prev->next;
|
||||
bubble->prev->next = bubble;
|
||||
bubble->next->prev = bubble;
|
||||
}
|
||||
|
||||
inline void
|
||||
remove_bubble(Bubble *bubble){
|
||||
bubble->prev->next = bubble->next;
|
||||
bubble->next->prev = bubble->prev;
|
||||
}
|
||||
|
||||
static void
|
||||
general_memory_open(General_Memory *general, void *memory, int32_t size){
|
||||
general->sentinel.prev = &general->sentinel;
|
||||
general->sentinel.next = &general->sentinel;
|
||||
general->sentinel.flags = MEM_BUBBLE_USED;
|
||||
general->sentinel.size = 0;
|
||||
|
||||
Bubble *first = (Bubble*)memory;
|
||||
first->flags = (uint32_t)MEM_BUBBLE_FLAG_INIT;
|
||||
first->size = size - sizeof(Bubble);
|
||||
insert_bubble(&general->sentinel, first);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
general_memory_check(General_Memory *general){
|
||||
Bubble *sentinel = &general->sentinel;
|
||||
for (Bubble *bubble = sentinel->next;
|
||||
bubble != sentinel;
|
||||
bubble = bubble->next){
|
||||
assert(bubble);
|
||||
|
||||
Bubble *next = bubble->next;
|
||||
assert(bubble == next->prev);
|
||||
if (next != sentinel && bubble->prev != sentinel){
|
||||
assert(bubble->next > bubble);
|
||||
assert(bubble > bubble->prev);
|
||||
|
||||
char *end_ptr = (char*)(bubble + 1) + bubble->size;
|
||||
char *next_ptr = (char*)next;
|
||||
(void)(end_ptr);
|
||||
(void)(next_ptr);
|
||||
assert(end_ptr == next_ptr);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
#define BUBBLE_MIN_SIZE 1024
|
||||
|
||||
static void
|
||||
general_memory_attempt_split(Bubble *bubble, int32_t wanted_size){
|
||||
int32_t remaining_size = bubble->size - wanted_size;
|
||||
if (remaining_size >= BUBBLE_MIN_SIZE){
|
||||
bubble->size = wanted_size;
|
||||
Bubble *new_bubble = (Bubble*)((char*)(bubble + 1) + wanted_size);
|
||||
new_bubble->flags = (uint32_t)MEM_BUBBLE_FLAG_INIT;
|
||||
new_bubble->size = remaining_size - sizeof(Bubble);
|
||||
insert_bubble(bubble, new_bubble);
|
||||
}
|
||||
}
|
||||
|
||||
static void*
|
||||
general_memory_allocate(General_Memory *general, int32_t size){
|
||||
void *result = 0;
|
||||
for (Bubble *bubble = general->sentinel.next;
|
||||
bubble != &general->sentinel;
|
||||
bubble = bubble->next){
|
||||
if (!(bubble->flags & MEM_BUBBLE_USED)){
|
||||
if (bubble->size >= size){
|
||||
result = bubble + 1;
|
||||
bubble->flags |= MEM_BUBBLE_USED;
|
||||
general_memory_attempt_split(bubble, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void
|
||||
general_memory_do_merge(Bubble *left, Bubble *right){
|
||||
assert(left->next == right);
|
||||
assert(right->prev == left);
|
||||
left->size += sizeof(Bubble) + right->size;
|
||||
remove_bubble(right);
|
||||
}
|
||||
|
||||
inline void
|
||||
general_memory_attempt_merge(Bubble *left, Bubble *right){
|
||||
if (!(left->flags & MEM_BUBBLE_USED) &&
|
||||
!(right->flags & MEM_BUBBLE_USED)){
|
||||
general_memory_do_merge(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
general_memory_free(General_Memory *general, void *memory){
|
||||
Bubble *bubble = ((Bubble*)memory) - 1;
|
||||
bubble->flags &= ~MEM_BUBBLE_USED;
|
||||
Bubble *prev, *next;
|
||||
prev = bubble->prev;
|
||||
next = bubble->next;
|
||||
general_memory_attempt_merge(bubble, next);
|
||||
general_memory_attempt_merge(prev, bubble);
|
||||
}
|
||||
|
||||
static void*
|
||||
general_memory_reallocate(General_Memory *general, void *old, int32_t old_size, int32_t size){
|
||||
void *result = old;
|
||||
Bubble *bubble = ((Bubble*)old) - 1;
|
||||
int32_t additional_space = size - bubble->size;
|
||||
if (additional_space > 0){
|
||||
Bubble *next = bubble->next;
|
||||
if (!(next->flags & MEM_BUBBLE_USED) &&
|
||||
next->size + sizeof(Bubble) >= additional_space){
|
||||
general_memory_do_merge(bubble, next);
|
||||
general_memory_attempt_split(bubble, size);
|
||||
}
|
||||
else{
|
||||
result = general_memory_allocate(general, size);
|
||||
if (old_size) memcpy(result, old, old_size);
|
||||
general_memory_free(general, old);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void*
|
||||
general_memory_reallocate_nocopy(General_Memory *general, void *old, int32_t size){
|
||||
return general_memory_reallocate(general, old, 0, size);
|
||||
}
|
||||
|
||||
#define reset_temp_memory end_temp_memory
|
||||
|
||||
#define gen_struct(g, T) (T*)general_memory_allocate(g, sizeof(T), 0)
|
||||
#define gen_array(g, T, size) (T*)general_memory_allocate(g, sizeof(T)*(size))
|
||||
#define gen_block(g, size) general_memory_open(g, size, 0)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,406 @@
|
|||
|
||||
#ifndef FCODER_SEARCH
|
||||
#define FCODER_SEARCH
|
||||
|
||||
enum Search_Range_Type{
|
||||
SearchRange_FrontToBack,
|
||||
SearchRange_BackToFront,
|
||||
SearchRange_Wave,
|
||||
};
|
||||
|
||||
struct Search_Range{
|
||||
int type;
|
||||
int buffer;
|
||||
int start;
|
||||
int size;
|
||||
int mid_start;
|
||||
int mid_size;
|
||||
};
|
||||
|
||||
struct Search_Set{
|
||||
Search_Range *ranges;
|
||||
int count;
|
||||
int max;
|
||||
};
|
||||
|
||||
struct Search_Iter{
|
||||
String word;
|
||||
int pos;
|
||||
int back_pos;
|
||||
int i;
|
||||
int range_initialized;
|
||||
};
|
||||
|
||||
struct Search_Match{
|
||||
Buffer_Summary buffer;
|
||||
int start;
|
||||
int end;
|
||||
int found_match;
|
||||
};
|
||||
|
||||
// TODO(allen): HOW DO I WANT TO GET MEMORY CUSTOM SIDE??
|
||||
#define GET_MEMORY(a) (void*)(0)
|
||||
#define REGET_MEMORY(a,b) (void*)(0)
|
||||
#define REGET_NOCOPY_MEMORY(a,b) (void*)(0)
|
||||
#define FREE_MEMORY(a) (void)(a)
|
||||
|
||||
static void
|
||||
search_iter_init(Application_Links *app, Search_Iter *iter, int size){
|
||||
int str_max = size*2;
|
||||
if (iter->word.str == 0){
|
||||
iter->word.str = (char*)GET_MEMORY(str_max);
|
||||
iter->word.memory_size = str_max;
|
||||
}
|
||||
else if (iter->word.memory_size < size){
|
||||
iter->word.str = (char*)REGET_MEMORY(iter->word.str, str_max);
|
||||
iter->word.memory_size = str_max;
|
||||
}
|
||||
|
||||
iter->i = 0;
|
||||
iter->pos = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
search_set_init(Application_Links *app, Search_Set *set, int range_count){
|
||||
int max = range_count*2;
|
||||
|
||||
if (set->ranges == 0){
|
||||
set->ranges = (Search_Range*)GET_MEMORY(sizeof(Search_Range)*max);
|
||||
set->max = max;
|
||||
}
|
||||
else if (set->max < range_count){
|
||||
set->ranges = (Search_Range*)REGET_MEMORY(set->ranges, sizeof(Search_Range)*max);
|
||||
set->max = max;
|
||||
}
|
||||
|
||||
set->count = range_count;
|
||||
}
|
||||
|
||||
static void
|
||||
search_hits_table_alloc(Application_Links *app, Table *hits, int table_size){
|
||||
void *mem = 0;
|
||||
int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
|
||||
if (hits->hash_array == 0){
|
||||
mem = GET_MEMORY(mem_sze);
|
||||
}
|
||||
else{
|
||||
mem = REGET_NOCOPY_MEMORY(hits->hash_array, mem_sze);
|
||||
}
|
||||
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
|
||||
}
|
||||
|
||||
static void
|
||||
search_hits_init(Application_Links *app, Table *hits, String_Space *str, int table_size, int str_size){
|
||||
if (hits->hash_array == 0){
|
||||
search_hits_table_alloc(app, hits, table_size);
|
||||
}
|
||||
else{
|
||||
int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
|
||||
void *mem = REGET_NOCOPY_MEMORY(mem, mem_size);
|
||||
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
|
||||
}
|
||||
|
||||
if (str->space == 0){
|
||||
str->space = (char*)GET_MEMORY(str_size);
|
||||
str->max = str_size;
|
||||
}
|
||||
else if (str->max < str_size){
|
||||
str->space = (char*)REGET_NOCOPY_MEMORY(str->space, str_size);
|
||||
str->max = str_size;
|
||||
}
|
||||
|
||||
str->pos = str->new_pos = 0;
|
||||
table_clear(hits);
|
||||
}
|
||||
|
||||
static int
|
||||
search_hit_add(Application_Links *app, Table *hits, String_Space *space, char *str, int len){
|
||||
int result = false;
|
||||
|
||||
assert(len != 0);
|
||||
|
||||
Offset_String ostring = strspace_append(space, str, len);
|
||||
if (ostring.size == 0){
|
||||
int new_size = space->max*2;
|
||||
if (new_size < space->max + len){
|
||||
new_size = space->max + len;
|
||||
}
|
||||
space->space = (char*)REGET_MEMORY(space->space, new_size);
|
||||
ostring = strspace_append(space, str, len);
|
||||
}
|
||||
|
||||
assert(ostring.size != 0);
|
||||
|
||||
if (table_at_capacity(hits)){
|
||||
Table new_hits = {0};
|
||||
search_hits_table_alloc(app, &new_hits, hits->max*2);
|
||||
table_clear(&new_hits);
|
||||
table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare);
|
||||
FREE_MEMORY(hits->hash_array);
|
||||
*hits = new_hits;
|
||||
}
|
||||
|
||||
if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
|
||||
result = true;
|
||||
strspace_keep_prev(space);
|
||||
}
|
||||
else{
|
||||
strspace_discard_prev(space);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
buffer_seek_alpha_numeric_end(Application_Links *app, Buffer_Summary *buffer, int pos){
|
||||
char space[1024];
|
||||
Stream_Chunk chunk = {0};
|
||||
if (init_stream_chunk(&chunk, app, buffer, pos, space, sizeof(space))){
|
||||
int still_looping = true;
|
||||
do{
|
||||
for (; pos < chunk.end; ++pos){
|
||||
char at_pos = chunk.data[pos];
|
||||
if (!char_is_alpha_numeric(at_pos)) goto double_break;
|
||||
}
|
||||
still_looping = forward_stream_chunk(&chunk);
|
||||
}while(still_looping);
|
||||
}
|
||||
double_break:;
|
||||
return(pos);
|
||||
}
|
||||
|
||||
static void
|
||||
search_iter_next_range(Search_Iter *it){
|
||||
++it->i;
|
||||
it->pos = 0;
|
||||
it->back_pos = 0;
|
||||
it->range_initialized = 0;
|
||||
}
|
||||
|
||||
enum{
|
||||
FindResult_None,
|
||||
FindResult_FoundMatch,
|
||||
FindResult_PastEnd
|
||||
};
|
||||
|
||||
static int
|
||||
search_front_to_back_step(Application_Links *app,
|
||||
Search_Range *range,
|
||||
String word,
|
||||
int *pos,
|
||||
Search_Match *result_ptr){
|
||||
int found_match = FindResult_None;
|
||||
|
||||
Search_Match result = *result_ptr;
|
||||
|
||||
int end_pos = range->start + range->size;
|
||||
if (*pos + word.size < end_pos){
|
||||
int start_pos = *pos;
|
||||
if (start_pos < range->start){
|
||||
start_pos = range->start;
|
||||
}
|
||||
|
||||
result.buffer = app->get_buffer(app, range->buffer, AccessAll);
|
||||
buffer_seek_string_forward(app, &result.buffer,
|
||||
start_pos, end_pos,
|
||||
word.str, word.size,
|
||||
&result.start);
|
||||
|
||||
if (result.start < end_pos){
|
||||
*pos = result.start + 1;
|
||||
char prev = ' ';
|
||||
if (result.start > 0){
|
||||
prev = buffer_get_char(app, &result.buffer, result.start - 1);
|
||||
}
|
||||
if (!char_is_alpha_numeric(prev)){
|
||||
result.end =
|
||||
buffer_seek_alpha_numeric_end(
|
||||
app, &result.buffer, result.start);
|
||||
|
||||
if (result.end < end_pos){
|
||||
result.found_match = true;
|
||||
*pos = result.end;
|
||||
found_match = FindResult_FoundMatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
found_match = FindResult_PastEnd;
|
||||
}
|
||||
}
|
||||
else{
|
||||
found_match = FindResult_PastEnd;
|
||||
}
|
||||
|
||||
*result_ptr = result;
|
||||
|
||||
return(found_match);
|
||||
}
|
||||
|
||||
static int
|
||||
search_back_to_front_step(Application_Links *app,
|
||||
Search_Range *range,
|
||||
String word,
|
||||
int *pos,
|
||||
Search_Match *result_ptr){
|
||||
int found_match = FindResult_None;
|
||||
|
||||
Search_Match result = *result_ptr;
|
||||
|
||||
int end_pos = range->start + range->size;
|
||||
if (*pos > range->start){
|
||||
int start_pos = *pos;
|
||||
|
||||
result.buffer = app->get_buffer(app, range->buffer, AccessAll);
|
||||
buffer_seek_string_backward(app, &result.buffer,
|
||||
start_pos, range->start,
|
||||
word.str, word.size,
|
||||
&result.start);
|
||||
|
||||
if (result.start >= range->start){
|
||||
*pos = result.start - 1;
|
||||
char prev = ' ';
|
||||
if (result.start > 0){
|
||||
prev = buffer_get_char(app, &result.buffer, result.start - 1);
|
||||
}
|
||||
if (!char_is_alpha_numeric(prev)){
|
||||
result.end =
|
||||
buffer_seek_alpha_numeric_end(
|
||||
app, &result.buffer, result.start);
|
||||
|
||||
if (result.end < end_pos){
|
||||
result.found_match = true;
|
||||
*pos = result.start - word.size;
|
||||
found_match = FindResult_FoundMatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
found_match = FindResult_PastEnd;
|
||||
}
|
||||
}
|
||||
else{
|
||||
found_match = FindResult_PastEnd;
|
||||
}
|
||||
|
||||
*result_ptr = result;
|
||||
|
||||
return(found_match);
|
||||
}
|
||||
|
||||
static Search_Match
|
||||
search_next_match(Application_Links *app, Search_Set *set, Search_Iter *it_ptr){
|
||||
Search_Match result = {0};
|
||||
Search_Iter iter = *it_ptr;
|
||||
|
||||
char *spare = (char*)GET_MEMORY(iter.word.size);
|
||||
|
||||
int count = set->count;
|
||||
for (; iter.i < count;){
|
||||
Search_Range *range = set->ranges + iter.i;
|
||||
|
||||
int find_result = FindResult_None;
|
||||
|
||||
if (!iter.range_initialized){
|
||||
iter.range_initialized = true;
|
||||
switch (range->type){
|
||||
case SearchRange_BackToFront:
|
||||
{
|
||||
iter.back_pos = range->start+range->size-1;
|
||||
}break;
|
||||
|
||||
case SearchRange_Wave:
|
||||
{
|
||||
iter.back_pos = range->mid_start-1;
|
||||
iter.pos = range->mid_start + range->mid_size;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (range->type){
|
||||
case SearchRange_FrontToBack:
|
||||
{
|
||||
find_result =
|
||||
search_front_to_back_step(app, range,
|
||||
iter.word,
|
||||
&iter.pos,
|
||||
&result);
|
||||
}break;
|
||||
|
||||
case SearchRange_BackToFront:
|
||||
{
|
||||
find_result =
|
||||
search_back_to_front_step(app, range,
|
||||
iter.word,
|
||||
&iter.back_pos,
|
||||
&result);
|
||||
}break;
|
||||
|
||||
case SearchRange_Wave:
|
||||
{
|
||||
Search_Match forward_match = {0};
|
||||
int forward_result =
|
||||
search_front_to_back_step(app, range,
|
||||
iter.word,
|
||||
&iter.pos,
|
||||
&forward_match);
|
||||
|
||||
Search_Match backward_match = {0};
|
||||
int backward_result =
|
||||
search_back_to_front_step(app, range,
|
||||
iter.word,
|
||||
&iter.back_pos,
|
||||
&backward_match);
|
||||
|
||||
if (forward_result == FindResult_FoundMatch){
|
||||
if (backward_result == FindResult_FoundMatch){
|
||||
find_result = FindResult_FoundMatch;
|
||||
|
||||
int forward_start = range->mid_start + range->mid_size;
|
||||
int forward_distance = (forward_match.start - forward_start);
|
||||
int backward_distance = (forward_match.end - range->mid_start);
|
||||
|
||||
if (backward_distance < forward_distance){
|
||||
--iter.pos;
|
||||
result = forward_match;
|
||||
}
|
||||
else{
|
||||
++iter.back_pos;
|
||||
result = backward_match;
|
||||
}
|
||||
}
|
||||
else{
|
||||
find_result = FindResult_FoundMatch;
|
||||
result = forward_match;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (backward_result == FindResult_FoundMatch){
|
||||
find_result = FindResult_FoundMatch;
|
||||
result = backward_match;
|
||||
--iter.pos;
|
||||
}
|
||||
else{
|
||||
find_result = FindResult_PastEnd;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
}
|
||||
|
||||
if (find_result == FindResult_FoundMatch){
|
||||
goto double_break;
|
||||
}
|
||||
else if (find_result == FindResult_PastEnd){
|
||||
search_iter_next_range(&iter);
|
||||
}
|
||||
}
|
||||
double_break:;
|
||||
|
||||
FREE_MEMORY(spare);
|
||||
|
||||
*it_ptr = iter;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* 14.02.2016
|
||||
*
|
||||
* 4tech C style genereic hash table
|
||||
* C style genereic hash table
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -13,57 +13,57 @@
|
|||
#define TableHashDeleted 1
|
||||
#define TableHashMin 0x10000000
|
||||
|
||||
typedef u32 Hash_Function(void *item, void *arg);
|
||||
typedef i32 Compare_Function(void *key, void *item, void *arg);
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef uint32_t Hash_Function(void *item, void *arg);
|
||||
typedef int32_t Compare_Function(void *key, void *item, void *arg);
|
||||
|
||||
struct Table{
|
||||
u32 *hash_array;
|
||||
u8 *data_array;
|
||||
i32 count, max;
|
||||
i32 item_size;
|
||||
uint32_t *hash_array;
|
||||
char *data_array;
|
||||
int32_t count, max;
|
||||
int32_t item_size;
|
||||
};
|
||||
|
||||
internal i32
|
||||
table_required_mem_size(i32 table_size, i32 item_size){
|
||||
i32 mem_size, hash_size;
|
||||
hash_size = ((table_size * sizeof(u32)) + 7) & ~7;
|
||||
mem_size = hash_size + table_size * item_size;
|
||||
static int32_t
|
||||
table_required_mem_size(int32_t table_size, int32_t item_size){
|
||||
int32_t hash_size = ((table_size * sizeof(uint32_t)) + 7) & ~7;
|
||||
int32_t mem_size = hash_size + table_size * item_size;
|
||||
return(mem_size);
|
||||
}
|
||||
|
||||
internal void
|
||||
table_init_memory(Table *table, void *memory, i32 table_size, i32 item_size){
|
||||
i32 hash_size = table_size * sizeof(u32);
|
||||
static void
|
||||
table_init_memory(Table *table, void *memory, int32_t table_size, int32_t item_size){
|
||||
int32_t hash_size = table_size * sizeof(uint32_t);
|
||||
hash_size = (hash_size + 7) & ~7;
|
||||
|
||||
table->hash_array = (u32*)memory;
|
||||
table->data_array = (u8*)(table->hash_array) + hash_size;
|
||||
table->hash_array = (uint32_t*)memory;
|
||||
table->data_array = (char*)(table->hash_array) + hash_size;
|
||||
|
||||
table->count = 0;
|
||||
table->max = table_size;
|
||||
table->item_size = item_size;
|
||||
}
|
||||
|
||||
internal b32
|
||||
static int32_t
|
||||
table_at_capacity(Table *table){
|
||||
b32 result = 1;
|
||||
int32_t result = true;
|
||||
if (table->count * 8 < table->max * 7){
|
||||
result = 0;
|
||||
result = false;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
static int32_t
|
||||
table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
|
||||
u32 hash, *inspect;
|
||||
i32 i, start;
|
||||
assert(table->count * 8 < table->max * 7);
|
||||
|
||||
Assert(table->count * 8 < table->max * 7);
|
||||
|
||||
hash = (hash_func(item, arg) | TableHashMin);
|
||||
i = hash % table->max;
|
||||
start = i;
|
||||
inspect = table->hash_array + i;
|
||||
uint32_t hash = (hash_func(item, arg) | TableHashMin);
|
||||
int32_t i = hash % table->max;
|
||||
int32_t start = i;
|
||||
uint32_t *inspect = table->hash_array + i;
|
||||
|
||||
while (*inspect >= TableHashMin){
|
||||
if (*inspect == hash){
|
||||
|
@ -77,7 +77,7 @@ table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare
|
|||
i = 0;
|
||||
inspect = table->hash_array;
|
||||
}
|
||||
Assert(i != start);
|
||||
assert(i != start);
|
||||
}
|
||||
*inspect = hash;
|
||||
memcpy(table->data_array + i*table->item_size, item, table->item_size);
|
||||
|
@ -86,17 +86,14 @@ table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare
|
|||
return(0);
|
||||
}
|
||||
|
||||
internal b32
|
||||
table_find_pos(Table *table, void *search_key, void *arg, i32 *pos, i32 *index, Hash_Function *hash_func, Compare_Function *comp_func){
|
||||
u32 hash, *inspect;
|
||||
i32 i, start;
|
||||
static int32_t
|
||||
table_find_pos(Table *table, void *search_key, void *arg, int32_t *pos, int32_t *index, Hash_Function *hash_func, Compare_Function *comp_func){
|
||||
assert((table->count - 1) * 8 < table->max * 7);
|
||||
|
||||
Assert((table->count - 1) * 8 < table->max * 7);
|
||||
|
||||
hash = (hash_func(search_key, arg) | TableHashMin);
|
||||
i = hash % table->max;
|
||||
start = i;
|
||||
inspect = table->hash_array + i;
|
||||
uint32_t hash = (hash_func(search_key, arg) | TableHashMin);
|
||||
int32_t i = hash % table->max;
|
||||
int32_t start = i;
|
||||
uint32_t *inspect = table->hash_array + i;
|
||||
|
||||
while (*inspect != TableHashEmpty){
|
||||
if (*inspect == hash){
|
||||
|
@ -120,8 +117,8 @@ table_find_pos(Table *table, void *search_key, void *arg, i32 *pos, i32 *index,
|
|||
|
||||
inline void*
|
||||
table_find_item(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
|
||||
i32 pos;
|
||||
void *result = 0;
|
||||
int32_t pos;
|
||||
if (table_find_pos(table, search_key, arg, &pos, 0, hash_func, comp_func)){
|
||||
result = table->data_array + pos;
|
||||
}
|
||||
|
@ -129,18 +126,18 @@ table_find_item(Table *table, void *search_key, void *arg, Hash_Function *hash_f
|
|||
}
|
||||
|
||||
inline void
|
||||
table_remove_index(Table *table, i32 index){
|
||||
table_remove_index(Table *table, int32_t index){
|
||||
table->hash_array[index] = TableHashDeleted;
|
||||
--table->count;
|
||||
}
|
||||
|
||||
inline b32
|
||||
inline int32_t
|
||||
table_remove_match(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
|
||||
i32 index;
|
||||
b32 result = 0;
|
||||
int32_t result = false;
|
||||
int32_t index;
|
||||
if (table_find_pos(table, search_key, arg, 0, &index, hash_func, comp_func)){
|
||||
table_remove_index(table, index);
|
||||
result = 1;
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
@ -151,20 +148,18 @@ table_clear(Table *table){
|
|||
memset(table->hash_array, 0, table->max*sizeof(*table->hash_array));
|
||||
}
|
||||
|
||||
internal void
|
||||
static void
|
||||
table_rehash(Table *src, Table *dst, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
|
||||
i32 i, c, count, item_size;
|
||||
u32 *hash_item;
|
||||
u8 *data_item;
|
||||
assert((dst->count + src->count - 1) * 7 < dst->max * 8);
|
||||
assert(dst->item_size == src->item_size);
|
||||
|
||||
Assert((dst->count + src->count - 1) * 7 < dst->max * 8);
|
||||
Assert(dst->item_size == src->item_size);
|
||||
|
||||
count = src->count;
|
||||
hash_item = src->hash_array;
|
||||
data_item = src->data_array;
|
||||
item_size = src->item_size;
|
||||
for (i = 0, c = 0; c < count; ++i, ++hash_item, data_item += item_size){
|
||||
int32_t count = src->count;
|
||||
int32_t item_size = src->item_size;
|
||||
uint32_t *hash_item = src->hash_array;
|
||||
char *data_item = src->data_array;
|
||||
for (int32_t i = 0, c = 0;
|
||||
c < count;
|
||||
++i, ++hash_item, data_item += item_size){
|
||||
if (*hash_item >= TableHashMin){
|
||||
++c;
|
||||
table_add(dst, data_item, arg, hash_func, comp_func);
|
||||
|
@ -172,12 +167,12 @@ table_rehash(Table *src, Table *dst, void *arg, Hash_Function *hash_func, Compar
|
|||
}
|
||||
}
|
||||
|
||||
internal u32
|
||||
static uint32_t
|
||||
tbl_string_hash(void *item, void *arg){
|
||||
String *string = (String*)item;
|
||||
char *str;
|
||||
i32 i,len;
|
||||
u32 x = 5381;
|
||||
int32_t i,len;
|
||||
uint32_t x = 5381;
|
||||
char c;
|
||||
(void)arg;
|
||||
|
||||
|
@ -192,20 +187,20 @@ tbl_string_hash(void *item, void *arg){
|
|||
return(x);
|
||||
}
|
||||
|
||||
internal i32
|
||||
static int32_t
|
||||
tbl_string_compare(void *a, void *b, void *arg){
|
||||
String *stra = (String*)a;
|
||||
String *strb = (String*)b;
|
||||
i32 result = !match(*stra, *strb);
|
||||
int32_t result = !match(*stra, *strb);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal u32
|
||||
static uint32_t
|
||||
tbl_offset_string_hash(void *item, void *arg){
|
||||
Offset_String *string = (Offset_String*)item;
|
||||
char *str;
|
||||
i32 i,len;
|
||||
u32 x = 5381;
|
||||
int32_t i,len;
|
||||
uint32_t x = 5381;
|
||||
char c;
|
||||
|
||||
str = ((char*)arg) + string->offset;
|
||||
|
@ -219,23 +214,23 @@ tbl_offset_string_hash(void *item, void *arg){
|
|||
return(x);
|
||||
}
|
||||
|
||||
internal i32
|
||||
static int32_t
|
||||
tbl_offset_string_compare(void *a, void *b, void *arg){
|
||||
Offset_String *ostra = (Offset_String*)a;
|
||||
Offset_String *ostrb = (Offset_String*)b;
|
||||
String stra = make_string((char*)arg + ostra->offset, ostra->size);
|
||||
String strb = make_string((char*)arg + ostrb->offset, ostrb->size);
|
||||
i32 result = !match(stra, strb);
|
||||
int32_t result = !match(stra, strb);
|
||||
return(result);
|
||||
}
|
||||
|
||||
struct String_Space{
|
||||
char *space;
|
||||
i32 pos, new_pos, max;
|
||||
int32_t pos, new_pos, max;
|
||||
};
|
||||
|
||||
internal Offset_String
|
||||
strspace_append(String_Space *space, char *str, i32 len){
|
||||
static Offset_String
|
||||
strspace_append(String_Space *space, char *str, int32_t len){
|
||||
Offset_String result = {};
|
||||
if (space->new_pos + len <= space->max){
|
||||
result.offset = space->new_pos;
|
||||
|
@ -247,12 +242,12 @@ strspace_append(String_Space *space, char *str, i32 len){
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
static void
|
||||
strspace_keep_prev(String_Space *space){
|
||||
space->pos = space->new_pos;
|
||||
}
|
||||
|
||||
internal void
|
||||
static void
|
||||
strspace_discard_prev(String_Space *space){
|
||||
space->new_pos = space->pos;
|
||||
}
|
|
@ -98,6 +98,16 @@ ENUM(uint64_t, Command_ID){
|
|||
cmdid_count
|
||||
};
|
||||
|
||||
/* DOC(TODO) */
|
||||
FLAGENUM(Memory_Protect_Flags){
|
||||
/* DOC(TODO) */
|
||||
MemProtect_Read = 0x1,
|
||||
/* DOC(TODO) */
|
||||
MemProtect_Write = 0x2,
|
||||
/* DOC(TODO) */
|
||||
MemProtect_Execute = 0x4,
|
||||
};
|
||||
|
||||
/* DOC(User_Input_Type_ID specifies a type of user input event.) */
|
||||
ENUM(int32_t, User_Input_Type_ID){
|
||||
/* DOC(UserInputNone indicates that no event has occurred.) */
|
||||
|
|
1
4ed.cpp
1
4ed.cpp
|
@ -472,6 +472,7 @@ COMMAND_DECL(word_complete){
|
|||
|
||||
complete_state->word_end = word_start + match_size;
|
||||
complete_state->set.ranges[1].start = word_start + match_size;
|
||||
end_temp_memory(temp);
|
||||
break;
|
||||
}
|
||||
end_temp_memory(temp);
|
||||
|
|
|
@ -338,6 +338,28 @@ DOC_SEE(Command_Line_Input_Flag)
|
|||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT void*
|
||||
Memory_Alloc(Application_Links *app, int32_t size)/*
|
||||
DOC(TODO)
|
||||
*/{
|
||||
void *result = 0;
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT int32_t
|
||||
Memory_Set_Protection(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags)/*
|
||||
DOC(TODO)
|
||||
*/{
|
||||
int32_t result = 0;
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT void
|
||||
Memory_Free(Application_Links *app, void *mem)/*
|
||||
DOC(TODO)
|
||||
*/{
|
||||
}
|
||||
|
||||
API_EXPORT void
|
||||
Clipboard_Post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len)/*
|
||||
DOC_PARAM(clipboard_id, This parameter is set up to prepare for future features, it should always be 0 for now.)
|
||||
|
@ -405,6 +427,16 @@ DOC_SEE(The_4coder_Clipboard)
|
|||
return(size);
|
||||
}
|
||||
|
||||
API_EXPORT int32_t
|
||||
Get_Buffer_Count(Application_Links *app)/*
|
||||
DOC(TODO)
|
||||
*/{
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Working_Set *working_set = &cmd->models->working_set;
|
||||
int32_t result = working_set->file_count;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
internal_get_buffer_first(Working_Set *working_set, Buffer_Summary *buffer){
|
||||
if (working_set->file_count > 0){
|
||||
|
@ -710,7 +742,7 @@ DOC_PARAM(edits, This parameter provides about the source string and destination
|
|||
DOC_PARAM(edit_count, This parameter specifies the number of Buffer_Edit structs in edits.)
|
||||
DOC_PARAM(type, This prameter specifies what type of batch edit to execute.)
|
||||
DOC_RETURN(This call returns non-zero if the batch edit succeeds.)
|
||||
DOC()
|
||||
DOC(TODO)
|
||||
DOC_SEE(Buffer_Edit)
|
||||
DOC_SEE(Buffer_Batch_Edit_Type)
|
||||
*/{
|
||||
|
|
|
@ -19,14 +19,13 @@
|
|||
#define FSTRING_IMPLEMENTATION
|
||||
#include "4coder_string.h"
|
||||
|
||||
#include "4ed_mem.cpp"
|
||||
#include "4ed_math.cpp"
|
||||
|
||||
#include "4ed_system.h"
|
||||
#include "4ed_rendering.h"
|
||||
#include "4ed.h"
|
||||
|
||||
#include "4tech_table.cpp"
|
||||
#include "4coder_table.cpp"
|
||||
|
||||
#define FCPP_LEXER_IMPLEMENTATION
|
||||
//#include "test/4cpp_new_lexer.h"
|
||||
|
|
|
@ -528,7 +528,7 @@ working_set_init(Working_Set *working_set, Partition *partition, General_Memory
|
|||
|
||||
table_size = working_set->file_max;
|
||||
mem_size = table_required_mem_size(table_size, item_size);
|
||||
mem = general_memory_allocate(general, mem_size, 0);
|
||||
mem = general_memory_allocate(general, mem_size);
|
||||
memset(mem, 0, mem_size);
|
||||
table_init_memory(&working_set->table, mem, table_size, item_size);
|
||||
}
|
||||
|
@ -542,7 +542,7 @@ working_set__grow_if_needed(Table *table, General_Memory *general, void *arg, Ha
|
|||
if (table_at_capacity(table)){
|
||||
new_max = table->max * 2;
|
||||
mem_size = table_required_mem_size(new_max, table->item_size);
|
||||
mem = general_memory_allocate(general, mem_size, 0);
|
||||
mem = general_memory_allocate(general, mem_size);
|
||||
table_init_memory(&btable, mem, new_max, table->item_size);
|
||||
table_clear(&btable);
|
||||
table_rehash(table, &btable, 0, hash_func, comp_func);
|
||||
|
|
|
@ -848,7 +848,7 @@ file_save(System_Functions *system, Mem_Options *mem, Editing_File *file, char *
|
|||
|
||||
if (!data){
|
||||
used_general = 1;
|
||||
data = (char*)general_memory_allocate(&mem->general, max, 0);
|
||||
data = (char*)general_memory_allocate(&mem->general, max);
|
||||
}
|
||||
}
|
||||
Assert(data);
|
||||
|
@ -885,23 +885,12 @@ file_save_and_set_names(System_Functions *system, Mem_Options *mem,
|
|||
return result;
|
||||
}
|
||||
|
||||
enum File_Bubble_Type{
|
||||
BUBBLE_BUFFER = 1,
|
||||
BUBBLE_STARTS,
|
||||
BUBBLE_WIDTHS,
|
||||
BUBBLE_WRAPS,
|
||||
BUBBLE_TOKENS,
|
||||
BUBBLE_UNDO_STRING,
|
||||
BUBBLE_UNDO,
|
||||
BUBBLE_UNDO_CHILDREN,
|
||||
//
|
||||
FILE_BUBBLE_TYPE_END,
|
||||
enum{
|
||||
GROW_FAILED,
|
||||
GROW_NOT_NEEDED,
|
||||
GROW_SUCCESS,
|
||||
};
|
||||
|
||||
#define GROW_FAILED 0
|
||||
#define GROW_NOT_NEEDED 1
|
||||
#define GROW_SUCCESS 2
|
||||
|
||||
internal i32
|
||||
file_grow_starts_widths_as_needed(General_Memory *general, Buffer_Type *buffer, i32 additional_lines){
|
||||
b32 result = GROW_NOT_NEEDED;
|
||||
|
@ -915,11 +904,11 @@ file_grow_starts_widths_as_needed(General_Memory *general, Buffer_Type *buffer,
|
|||
|
||||
f32 *new_widths = (f32*)general_memory_reallocate(
|
||||
general, buffer->line_widths,
|
||||
sizeof(f32)*count, sizeof(f32)*max, BUBBLE_WIDTHS);
|
||||
sizeof(f32)*count, sizeof(f32)*max);
|
||||
|
||||
i32 *new_lines = (i32*)general_memory_reallocate(
|
||||
general, buffer->line_starts,
|
||||
sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS);
|
||||
sizeof(i32)*count, sizeof(i32)*max);
|
||||
|
||||
if (new_lines){
|
||||
buffer->line_starts = new_lines;
|
||||
|
@ -945,13 +934,13 @@ file_measure_starts_widths(System_Functions *system, General_Memory *general,
|
|||
Buffer_Type *buffer, float *advance_data){
|
||||
if (!buffer->line_starts){
|
||||
i32 max = buffer->line_max = Kbytes(1);
|
||||
buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32), BUBBLE_STARTS);
|
||||
buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32));
|
||||
TentativeAssert(buffer->line_starts);
|
||||
// TODO(allen): when unable to allocate?
|
||||
}
|
||||
if (!buffer->line_widths){
|
||||
i32 max = buffer->widths_max = Kbytes(1);
|
||||
buffer->line_widths = (f32*)general_memory_allocate(general, max*sizeof(f32), BUBBLE_WIDTHS);
|
||||
buffer->line_widths = (f32*)general_memory_allocate(general, max*sizeof(f32));
|
||||
TentativeAssert(buffer->line_starts);
|
||||
// TODO(allen): when unable to allocate?
|
||||
}
|
||||
|
@ -964,7 +953,7 @@ file_measure_starts_widths(System_Functions *system, General_Memory *general,
|
|||
|
||||
{
|
||||
i32 *new_lines = (i32*)general_memory_reallocate(
|
||||
general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS);
|
||||
general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max);
|
||||
|
||||
// TODO(allen): when unable to grow?
|
||||
TentativeAssert(new_lines);
|
||||
|
@ -975,7 +964,7 @@ file_measure_starts_widths(System_Functions *system, General_Memory *general,
|
|||
{
|
||||
f32 *new_lines = (f32*)
|
||||
general_memory_reallocate(general, buffer->line_widths,
|
||||
sizeof(f32)*count, sizeof(f32)*max, BUBBLE_WIDTHS);
|
||||
sizeof(f32)*count, sizeof(f32)*max);
|
||||
|
||||
// TODO(allen): when unable to grow?
|
||||
TentativeAssert(new_lines);
|
||||
|
@ -999,11 +988,11 @@ view_measure_wraps(General_Memory *general, View *view){
|
|||
i32 max = view->file_data.line_max = LargeRoundUp(line_count, Kbytes(1));
|
||||
if (view->file_data.line_wrap_y){
|
||||
view->file_data.line_wrap_y = (f32*)
|
||||
general_memory_reallocate_nocopy(general, view->file_data.line_wrap_y, sizeof(f32)*max, BUBBLE_WRAPS);
|
||||
general_memory_reallocate_nocopy(general, view->file_data.line_wrap_y, sizeof(f32)*max);
|
||||
}
|
||||
else{
|
||||
view->file_data.line_wrap_y = (f32*)
|
||||
general_memory_allocate(general, sizeof(f32)*max, BUBBLE_WRAPS);
|
||||
general_memory_allocate(general, sizeof(f32)*max);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1033,7 +1022,7 @@ file_create_from_string(System_Functions *system, Models *models,
|
|||
page_size = buffer_init_page_size(&init);
|
||||
page_size = LargeRoundUp(page_size, Kbytes(4));
|
||||
if (page_size < Kbytes(4)) page_size = Kbytes(4);
|
||||
void *data = general_memory_allocate(general, page_size, BUBBLE_BUFFER);
|
||||
void *data = general_memory_allocate(general, page_size);
|
||||
buffer_init_provide_page(&init, data, page_size);
|
||||
}
|
||||
|
||||
|
@ -1064,24 +1053,24 @@ file_create_from_string(System_Functions *system, Models *models,
|
|||
// TODO(allen): Redo undo system (if you don't mind the pun)
|
||||
i32 request_size = Kbytes(64);
|
||||
file->state.undo.undo.max = request_size;
|
||||
file->state.undo.undo.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING);
|
||||
file->state.undo.undo.strings = (u8*)general_memory_allocate(general, request_size);
|
||||
file->state.undo.undo.edit_max = request_size / sizeof(Edit_Step);
|
||||
file->state.undo.undo.edits = (Edit_Step*)general_memory_allocate(general, request_size, BUBBLE_UNDO);
|
||||
file->state.undo.undo.edits = (Edit_Step*)general_memory_allocate(general, request_size);
|
||||
|
||||
file->state.undo.redo.max = request_size;
|
||||
file->state.undo.redo.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING);
|
||||
file->state.undo.redo.strings = (u8*)general_memory_allocate(general, request_size);
|
||||
file->state.undo.redo.edit_max = request_size / sizeof(Edit_Step);
|
||||
file->state.undo.redo.edits = (Edit_Step*)general_memory_allocate(general, request_size, BUBBLE_UNDO);
|
||||
file->state.undo.redo.edits = (Edit_Step*)general_memory_allocate(general, request_size);
|
||||
|
||||
file->state.undo.history.max = request_size;
|
||||
file->state.undo.history.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING);
|
||||
file->state.undo.history.strings = (u8*)general_memory_allocate(general, request_size);
|
||||
file->state.undo.history.edit_max = request_size / sizeof(Edit_Step);
|
||||
file->state.undo.history.edits = (Edit_Step*)general_memory_allocate(general, request_size, BUBBLE_UNDO);
|
||||
file->state.undo.history.edits = (Edit_Step*)general_memory_allocate(general, request_size);
|
||||
|
||||
file->state.undo.children.max = request_size;
|
||||
file->state.undo.children.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING);
|
||||
file->state.undo.children.strings = (u8*)general_memory_allocate(general, request_size);
|
||||
file->state.undo.children.edit_max = request_size / sizeof(Buffer_Edit);
|
||||
file->state.undo.children.edits = (Buffer_Edit*)general_memory_allocate(general, request_size, BUBBLE_UNDO);
|
||||
file->state.undo.children.edits = (Buffer_Edit*)general_memory_allocate(general, request_size);
|
||||
|
||||
file->state.undo.history_block_count = 1;
|
||||
file->state.undo.history_head_block = 0;
|
||||
|
@ -1253,7 +1242,7 @@ Job_Callback_Sig(job_full_lex){
|
|||
{
|
||||
Assert(file->state.swap_stack.tokens == 0);
|
||||
file->state.swap_stack.tokens = (Cpp_Token*)
|
||||
general_memory_allocate(general, new_max*sizeof(Cpp_Token), BUBBLE_TOKENS);
|
||||
general_memory_allocate(general, new_max*sizeof(Cpp_Token));
|
||||
}
|
||||
system->release_lock(FRAME_LOCK);
|
||||
|
||||
|
@ -1368,7 +1357,7 @@ file_relex_parallel(System_Functions *system,
|
|||
stack->tokens = (Cpp_Token*)
|
||||
general_memory_reallocate(general, stack->tokens,
|
||||
stack->count*sizeof(Cpp_Token),
|
||||
new_max*sizeof(Cpp_Token), BUBBLE_TOKENS);
|
||||
new_max*sizeof(Cpp_Token));
|
||||
stack->max_count = new_max;
|
||||
}
|
||||
|
||||
|
@ -2109,7 +2098,7 @@ file_do_single_edit(System_Functions *system,
|
|||
part->base + part->pos, scratch_size, &request_amount)){
|
||||
void *new_data = 0;
|
||||
if (request_amount > 0){
|
||||
new_data = general_memory_allocate(general, request_amount, BUBBLE_BUFFER);
|
||||
new_data = general_memory_allocate(general, request_amount);
|
||||
}
|
||||
void *old_data = buffer_edit_provide_memory(&file->state.buffer, new_data, request_amount);
|
||||
if (old_data) general_memory_free(general, old_data);
|
||||
|
@ -2185,7 +2174,7 @@ file_do_white_batch_edit(System_Functions *system, Models *models, Editing_File
|
|||
scratch_size, &request_amount)){
|
||||
void *new_data = 0;
|
||||
if (request_amount > 0){
|
||||
new_data = general_memory_allocate(general, request_amount, BUBBLE_BUFFER);
|
||||
new_data = general_memory_allocate(general, request_amount);
|
||||
}
|
||||
void *old_data = buffer_edit_provide_memory(&file->state.buffer, new_data, request_amount);
|
||||
if (old_data) general_memory_free(general, old_data);
|
||||
|
@ -2258,6 +2247,7 @@ file_clear(System_Functions *system, Models *models, Editing_File *file){
|
|||
file_replace_range(system, models, file, 0, buffer_size(&file->state.buffer), 0, 0);
|
||||
}
|
||||
|
||||
// TODO(allen): get rid of this
|
||||
inline void
|
||||
view_replace_range(System_Functions *system, Models *models, View *view,
|
||||
i32 start, i32 end, char *str, i32 len){
|
||||
|
@ -3116,6 +3106,17 @@ view_show_file(View *view){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
internal String
|
||||
make_string_terminated(Partition *part, char *str, i32 len){
|
||||
char *space = (char*)push_array(part, char, len + 1);
|
||||
String string = make_string(str, len, len+1);
|
||||
copy_fast_unsafe(space, string);
|
||||
string.str = space;
|
||||
terminate_with_null(&string);
|
||||
return(string);
|
||||
}
|
||||
|
||||
internal void
|
||||
view_save_file(System_Functions *system, Models *models,
|
||||
Editing_File *file, View *view, String filename, b32 save_as){
|
||||
|
@ -4774,8 +4775,6 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
|
|||
|
||||
append_int_to_str(&string, bubble->size);
|
||||
append_padding(&string, ' ', 40);
|
||||
append(&string, " type: ");
|
||||
append_int_to_str(&string, bubble->type);
|
||||
gui_do_text_field(target, string, empty_str);
|
||||
}
|
||||
}break;
|
||||
|
@ -6011,12 +6010,12 @@ search_iter_init(General_Memory *general, Search_Iter *iter, i32 size){
|
|||
|
||||
if (iter->word.str == 0){
|
||||
str_max = size*2;
|
||||
iter->word.str = (char*)general_memory_allocate(general, str_max, 0);
|
||||
iter->word.str = (char*)general_memory_allocate(general, str_max);
|
||||
iter->word.memory_size = str_max;
|
||||
}
|
||||
else if (iter->word.memory_size < size){
|
||||
str_max = size*2;
|
||||
iter->word.str = (char*)general_memory_reallocate_nocopy(general, iter->word.str, str_max, 0);
|
||||
iter->word.str = (char*)general_memory_reallocate_nocopy(general, iter->word.str, str_max);
|
||||
iter->word.memory_size = str_max;
|
||||
}
|
||||
|
||||
|
@ -6030,13 +6029,13 @@ search_set_init(General_Memory *general, Search_Set *set, i32 set_count){
|
|||
|
||||
if (set->ranges == 0){
|
||||
max = set_count*2;
|
||||
set->ranges = (Search_Range*)general_memory_allocate(general, sizeof(Search_Range)*max, 0);
|
||||
set->ranges = (Search_Range*)general_memory_allocate(general, sizeof(Search_Range)*max);
|
||||
set->max = max;
|
||||
}
|
||||
else if (set->max < set_count){
|
||||
max = set_count*2;
|
||||
set->ranges = (Search_Range*)general_memory_reallocate_nocopy(
|
||||
general, set->ranges, sizeof(Search_Range)*max, 0);
|
||||
general, set->ranges, sizeof(Search_Range)*max);
|
||||
set->max = max;
|
||||
}
|
||||
|
||||
|
@ -6050,10 +6049,10 @@ search_hits_table_alloc(General_Memory *general, Table *hits, i32 table_size){
|
|||
|
||||
mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
|
||||
if (hits->hash_array == 0){
|
||||
mem = general_memory_allocate(general, mem_size, 0);
|
||||
mem = general_memory_allocate(general, mem_size);
|
||||
}
|
||||
else{
|
||||
mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size, 0);
|
||||
mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
|
||||
}
|
||||
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
|
||||
}
|
||||
|
@ -6068,16 +6067,16 @@ search_hits_init(General_Memory *general, Table *hits, String_Space *str, i32 ta
|
|||
}
|
||||
else if (hits->max < table_size){
|
||||
mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
|
||||
mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size, 0);
|
||||
mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
|
||||
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
|
||||
}
|
||||
|
||||
if (str->space == 0){
|
||||
str->space = (char*)general_memory_allocate(general, str_size, 0);
|
||||
str->space = (char*)general_memory_allocate(general, str_size);
|
||||
str->max = str_size;
|
||||
}
|
||||
else if (str->max < str_size){
|
||||
str->space = (char*)general_memory_reallocate_nocopy(general, str->space, str_size, 0);
|
||||
str->space = (char*)general_memory_reallocate_nocopy(general, str->space, str_size);
|
||||
str->max = str_size;
|
||||
}
|
||||
|
||||
|
@ -6097,7 +6096,7 @@ search_hit_add(General_Memory *general, Table *hits, String_Space *space, char *
|
|||
ostring = strspace_append(space, str, len);
|
||||
if (ostring.size == 0){
|
||||
new_size = Max(space->max*2, space->max + len);
|
||||
space->space = (char*)general_memory_reallocate(general, space->space, space->new_pos, new_size, 0);
|
||||
space->space = (char*)general_memory_reallocate(general, space->space, space->new_pos, new_size);
|
||||
ostring = strspace_append(space, str, len);
|
||||
}
|
||||
|
||||
|
@ -6210,7 +6209,7 @@ live_set_alloc_view(Live_Views *live_set, Panel *panel, Models *models){
|
|||
|
||||
{
|
||||
i32 gui_mem_size = Kbytes(32);
|
||||
void *gui_mem = general_memory_allocate(&models->mem.general, gui_mem_size + 8, 0);
|
||||
void *gui_mem = general_memory_allocate(&models->mem.general, gui_mem_size + 8);
|
||||
result.view->gui_mem = gui_mem;
|
||||
gui_mem = advance_to_alignment(gui_mem);
|
||||
result.view->gui_target.push = make_part(gui_mem, gui_mem_size);
|
||||
|
|
205
4ed_mem.cpp
205
4ed_mem.cpp
|
@ -1,205 +0,0 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 13.11.2015
|
||||
*
|
||||
* Memory utils for 4coder
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
enum Memory_Bubble_Flag{
|
||||
MEM_BUBBLE_USED = 0x1,
|
||||
MEM_BUBBLE_DEBUG = 0xD3000000,
|
||||
MEM_BUBBLE_SYS_DEBUG = 0x5D000000,
|
||||
MEM_BUBBLE_DEBUG_MASK = 0xFF000000
|
||||
};
|
||||
|
||||
struct Bubble{
|
||||
Bubble *prev;
|
||||
Bubble *next;
|
||||
u32 flags;
|
||||
i32 size;
|
||||
u32 type;
|
||||
u32 _unused_;
|
||||
};
|
||||
|
||||
struct General_Memory{
|
||||
Bubble sentinel;
|
||||
};
|
||||
|
||||
struct Mem_Options{
|
||||
Partition part;
|
||||
General_Memory general;
|
||||
};
|
||||
|
||||
inline void
|
||||
insert_bubble(Bubble *prev, Bubble *bubble){
|
||||
bubble->prev = prev;
|
||||
bubble->next = prev->next;
|
||||
bubble->prev->next = bubble;
|
||||
bubble->next->prev = bubble;
|
||||
}
|
||||
|
||||
inline void
|
||||
remove_bubble(Bubble *bubble){
|
||||
bubble->prev->next = bubble->next;
|
||||
bubble->next->prev = bubble->prev;
|
||||
}
|
||||
|
||||
#if FRED_INTERNAL
|
||||
#define MEM_BUBBLE_FLAG_INIT MEM_BUBBLE_DEBUG
|
||||
#else
|
||||
#define MEM_BUBBLE_FLAG_INIT 0
|
||||
#endif
|
||||
|
||||
internal void
|
||||
general_memory_open(General_Memory *general, void *memory, i32 size){
|
||||
general->sentinel.prev = &general->sentinel;
|
||||
general->sentinel.next = &general->sentinel;
|
||||
general->sentinel.flags = MEM_BUBBLE_USED;
|
||||
general->sentinel.size = 0;
|
||||
|
||||
Bubble *first = (Bubble*)memory;
|
||||
first->flags = (u32)MEM_BUBBLE_FLAG_INIT;
|
||||
first->size = size - sizeof(Bubble);
|
||||
insert_bubble(&general->sentinel, first);
|
||||
}
|
||||
|
||||
internal b32
|
||||
general_memory_check(General_Memory *general){
|
||||
Bubble *sentinel = &general->sentinel;
|
||||
for (Bubble *bubble = sentinel->next;
|
||||
bubble != sentinel;
|
||||
bubble = bubble->next){
|
||||
Assert(bubble);
|
||||
|
||||
Bubble *next = bubble->next;
|
||||
Assert(bubble == next->prev);
|
||||
if (next != sentinel && bubble->prev != sentinel){
|
||||
Assert(bubble->next > bubble);
|
||||
Assert(bubble > bubble->prev);
|
||||
|
||||
char *end_ptr = (char*)(bubble + 1) + bubble->size;
|
||||
char *next_ptr = (char*)next;
|
||||
AllowLocal(end_ptr);
|
||||
AllowLocal(next_ptr);
|
||||
Assert(end_ptr == next_ptr);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
#define BUBBLE_MIN_SIZE 1024
|
||||
|
||||
internal void
|
||||
general_memory_attempt_split(Bubble *bubble, i32 wanted_size){
|
||||
i32 remaining_size = bubble->size - wanted_size;
|
||||
if (remaining_size >= BUBBLE_MIN_SIZE){
|
||||
bubble->size = wanted_size;
|
||||
Bubble *new_bubble = (Bubble*)((u8*)(bubble + 1) + wanted_size);
|
||||
new_bubble->flags = (u32)MEM_BUBBLE_FLAG_INIT;
|
||||
new_bubble->size = remaining_size - sizeof(Bubble);
|
||||
insert_bubble(bubble, new_bubble);
|
||||
}
|
||||
}
|
||||
|
||||
internal void*
|
||||
general_memory_allocate(General_Memory *general, i32 size, u32 type = 0){
|
||||
void *result = 0;
|
||||
for (Bubble *bubble = general->sentinel.next;
|
||||
bubble != &general->sentinel;
|
||||
bubble = bubble->next){
|
||||
if (!(bubble->flags & MEM_BUBBLE_USED)){
|
||||
if (bubble->size >= size){
|
||||
result = bubble + 1;
|
||||
bubble->flags |= MEM_BUBBLE_USED;
|
||||
bubble->type = type;
|
||||
general_memory_attempt_split(bubble, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void
|
||||
general_memory_do_merge(Bubble *left, Bubble *right){
|
||||
Assert(left->next == right);
|
||||
Assert(right->prev == left);
|
||||
left->size += sizeof(Bubble) + right->size;
|
||||
remove_bubble(right);
|
||||
}
|
||||
|
||||
inline void
|
||||
general_memory_attempt_merge(Bubble *left, Bubble *right){
|
||||
if (!(left->flags & MEM_BUBBLE_USED) &&
|
||||
!(right->flags & MEM_BUBBLE_USED)){
|
||||
general_memory_do_merge(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
general_memory_free(General_Memory *general, void *memory){
|
||||
Bubble *bubble = ((Bubble*)memory) - 1;
|
||||
#if FRED_INTERNAL
|
||||
Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_DEBUG);
|
||||
#endif
|
||||
bubble->flags &= ~MEM_BUBBLE_USED;
|
||||
bubble->type = 0;
|
||||
Bubble *prev, *next;
|
||||
prev = bubble->prev;
|
||||
next = bubble->next;
|
||||
general_memory_attempt_merge(bubble, next);
|
||||
general_memory_attempt_merge(prev, bubble);
|
||||
}
|
||||
|
||||
internal void*
|
||||
general_memory_reallocate(General_Memory *general, void *old, i32 old_size, i32 size, u32 type = 0){
|
||||
void *result = old;
|
||||
Bubble *bubble = ((Bubble*)old) - 1;
|
||||
bubble->type = type;
|
||||
#if FRED_INTERNAL
|
||||
Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_DEBUG);
|
||||
#endif
|
||||
i32 additional_space = size - bubble->size;
|
||||
if (additional_space > 0){
|
||||
Bubble *next = bubble->next;
|
||||
if (!(next->flags & MEM_BUBBLE_USED) &&
|
||||
next->size + sizeof(Bubble) >= additional_space){
|
||||
general_memory_do_merge(bubble, next);
|
||||
general_memory_attempt_split(bubble, size);
|
||||
}
|
||||
else{
|
||||
result = general_memory_allocate(general, size, type);
|
||||
if (old_size) memcpy(result, old, old_size);
|
||||
general_memory_free(general, old);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void*
|
||||
general_memory_reallocate_nocopy(General_Memory *general, void *old, i32 size, u32 type = 0){
|
||||
return general_memory_reallocate(general, old, 0, size, type);
|
||||
}
|
||||
|
||||
#define reset_temp_memory end_temp_memory
|
||||
|
||||
#define gen_struct(g, T) (T*)general_memory_allocate(g, sizeof(T), 0)
|
||||
#define gen_array(g, T, size) (T*)general_memory_allocate(g, sizeof(T)*(size), 0)
|
||||
#define gen_block(g, size) general_memory_open(g, size, 0)
|
||||
|
||||
internal String
|
||||
make_string_terminated(Partition *part, char *str, int len){
|
||||
char *space = (char*)push_array(part, char, len + 1);
|
||||
String string = make_string(str, len, len+1);
|
||||
copy_fast_unsafe(space, string);
|
||||
string.str = space;
|
||||
terminate_with_null(&string);
|
||||
return(string);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
28
TODO.txt
28
TODO.txt
|
@ -174,24 +174,24 @@
|
|||
; [] tutorials
|
||||
; [] 4edT thing
|
||||
; [] unicode/UTF support
|
||||
; [] console emulator
|
||||
;
|
||||
|
||||
; INTERNAL TODOS
|
||||
; [X] switch building non-extensible version by statically linking to custom.cpp
|
||||
; [X] pack fonts more squarely
|
||||
; [] general parameter handling
|
||||
; [X] change job canceling to a polling based thing
|
||||
; [] hashed string pool for clipboard/filenames/etc
|
||||
; [] new profiling/debugging system
|
||||
; [] change job canceling to a polling based thing
|
||||
;
|
||||
|
||||
; EASY TODOS
|
||||
; [X] better messages for example not "BEHIND OS"
|
||||
; [X] shift backspace
|
||||
; [X] center view on cursor
|
||||
; [X] delta time in scroll interpolation
|
||||
; [] close editor command
|
||||
; [] panel grow/shrink commands
|
||||
; [] delta time in scroll interpolation
|
||||
;
|
||||
|
||||
; HARD BUGS
|
||||
|
@ -200,13 +200,12 @@
|
|||
; [] fyoucon's segfaults with malloc on win10
|
||||
; [] handling cursor in non-client part of window so it doesn't spaz
|
||||
; [] fill screen right away
|
||||
; [] how to get fast repaint (do I really need double buffering?)
|
||||
; [] history breaks when heavily used (disk swaping?)
|
||||
; [] history breaks when heavily used? (disk swaping?)
|
||||
;
|
||||
; [] minimize and reopen problem (reported by two users now, still not reproduced here)
|
||||
; [] minimize and reopen problem (still not reproduced here)
|
||||
;
|
||||
|
||||
; FANCY PANTS IDEAS
|
||||
; FANCY-PANTS IDEAS
|
||||
; [] pass messages to 'jobs' to try to avoid cancelling them
|
||||
; if the job still thinks it should be cancelled it will say so
|
||||
; but otherwise the job can try to incorporate the new info
|
||||
|
@ -225,27 +224,24 @@
|
|||
; [X] position in file to open
|
||||
; [X] invoking special tools
|
||||
; [X] transition Win32 layer to using system_shared stuff
|
||||
; [X] event driven file synchronization
|
||||
; [] user settings file
|
||||
; [] system fonts
|
||||
; [] file drag and drop
|
||||
; [] low latency stuff
|
||||
; [] event driven file synchronization
|
||||
; [] actually write the port
|
||||
; [X] 4coder code compiling
|
||||
; [X] opengl window up
|
||||
; [X] basic versions of system functions
|
||||
; [X] get 4coder to render to window
|
||||
; [X] keyboard and mouse input (TY:insofaras)
|
||||
; [X] file exchange (TY:insofaras)
|
||||
; [X] clipboard (TY:insofaras)
|
||||
; [X] keyboard and mouse input (TY:insofaras)
|
||||
; [X] file exchange (TY:insofaras)
|
||||
; [X] clipboard (TY:insofaras)
|
||||
; [X] background threads (TY:insofaras)
|
||||
; [X] cli stuff (TY:insofaras)
|
||||
; [X] cli stuff (TY:insofaras)
|
||||
; [X] event diven file synchronization (TY:insofaras)
|
||||
; [] system fonts
|
||||
; [] file drag and drop
|
||||
; [] low latency stuff
|
||||
; [] allow for multiple clipboards
|
||||
; [] event diven file synchronization
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#define FCPP_STRING_IMPLEMENTATION
|
||||
#include "4coder_string.h"
|
||||
|
||||
#include "4ed_mem.cpp"
|
||||
#include "4ed_math.cpp"
|
||||
|
||||
#include "4ed_system.h"
|
||||
|
@ -286,7 +285,7 @@ LinuxGetMemory_(i32 size, i32 line_number, char *file_name){
|
|||
result = mmap(0, size + sizeof(Sys_Bubble), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
|
||||
Sys_Bubble* bubble = (Sys_Bubble*)result;
|
||||
bubble->flags = MEM_BUBBLE_SYS_DEBUG;
|
||||
bubble->flags = 0;
|
||||
bubble->line_number = line_number;
|
||||
bubble->file_name = file_name;
|
||||
bubble->size = size;
|
||||
|
@ -316,7 +315,6 @@ LinuxFreeMemory(void *block){
|
|||
if (block){
|
||||
#if FRED_INTERNAL
|
||||
Sys_Bubble *bubble = ((Sys_Bubble*)block) - 1;
|
||||
Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_SYS_DEBUG);
|
||||
|
||||
size_t size = bubble->size + sizeof(Sys_Bubble);
|
||||
|
||||
|
@ -2453,7 +2451,7 @@ main(int argc, char **argv)
|
|||
#if FRED_INTERNAL
|
||||
linuxvars.internal_bubble.next = &linuxvars.internal_bubble;
|
||||
linuxvars.internal_bubble.prev = &linuxvars.internal_bubble;
|
||||
linuxvars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG;
|
||||
linuxvars.internal_bubble.flags = 0;
|
||||
|
||||
pthread_mutex_init(&linuxvars.DEBUG_sysmem_lock, 0);
|
||||
#endif
|
||||
|
|
|
@ -242,6 +242,9 @@ gcc_style_verify(String line, int colon_pos){
|
|||
else if (match_part(line_part, ": warning")){
|
||||
result = true;
|
||||
}
|
||||
else if (match_part(line_part, ": fatal")){
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#define FSTRING_IMPLEMENTATION
|
||||
#include "4coder_string.h"
|
||||
|
||||
#include "4ed_mem.cpp"
|
||||
#include "4ed_math.cpp"
|
||||
|
||||
#include "4ed_system.h"
|
||||
|
@ -245,7 +244,7 @@ Sys_Get_Memory_Sig(system_get_memory_){
|
|||
#if FRED_INTERNAL
|
||||
ptr = VirtualAlloc(0, size + sizeof(Sys_Bubble), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
Sys_Bubble *bubble = (Sys_Bubble*)ptr;
|
||||
bubble->flags = MEM_BUBBLE_SYS_DEBUG;
|
||||
bubble->flags = 0;
|
||||
bubble->line_number = line_number;
|
||||
bubble->file_name = file_name;
|
||||
bubble->size = size;
|
||||
|
@ -264,7 +263,6 @@ Sys_Free_Memory_Sig(system_free_memory){
|
|||
if (block){
|
||||
#if FRED_INTERNAL
|
||||
Sys_Bubble *bubble = ((Sys_Bubble*)block) - 1;
|
||||
Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_SYS_DEBUG);
|
||||
EnterCriticalSection(&win32vars.DEBUG_sysmem_lock);
|
||||
remove_bubble(bubble);
|
||||
LeaveCriticalSection(&win32vars.DEBUG_sysmem_lock);
|
||||
|
@ -1698,7 +1696,7 @@ WinMain(HINSTANCE hInstance,
|
|||
#if FRED_INTERNAL
|
||||
win32vars.internal_bubble.next = &win32vars.internal_bubble;
|
||||
win32vars.internal_bubble.prev = &win32vars.internal_bubble;
|
||||
win32vars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG;
|
||||
win32vars.internal_bubble.flags = 0;
|
||||
|
||||
InitializeCriticalSection(&win32vars.DEBUG_sysmem_lock);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue