added clparams to app step on linux; got the lexer API working with a fixed with tb
This commit is contained in:
parent
b9536768f7
commit
1b03a6a2be
|
@ -292,7 +292,7 @@ It should point at the String in the first element of the array.</div></div></di
|
|||
words it should be the size of one element of the array.</div></div></div><div><div style='font-weight: 600;'>count</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The count parameter specifies the number of elements in the str_set array.</div></div></div><div><div style='font-weight: 600;'>str</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The str parameter specifies the string to match against the str_set.</div></div></div><div><div style='font-weight: 600;'>match_index</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>If this call succeeds match_index is filled with the index into str_set where the match occurred.</div></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;'>This call tries to see if str matches any of the strings in str_set. If there is a match the call
|
||||
succeeds and returns non-zero. The matching rule is equivalent to the matching rule for match.<br><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='#match_doc'>match</a></div></div></div><hr><div id='string_set_match_doc' style='margin-bottom: 1cm;'><h4>§4.3.116: string_set_match</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;'>fstr_bool string_set_match(<div style='margin-left: 4mm;'>String *str_set,<br>int32_t count,<br>String str,<br>int32_t *match_index<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>str_set</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The str_set parameter is an array of String structs specifying matchable strings.</div></div></div><div><div style='font-weight: 600;'>count</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The count parameter specifies the number of String structs in the str_set array.</div></div></div><div><div style='font-weight: 600;'>str</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The str parameter specifies the string to match against the str_set.</div></div></div><div><div style='font-weight: 600;'>match_index</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>If this call succeeds match_index is filled with the index into str_set where the match occurred.</div></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;'>This call tries to see if str matches any of the strings in str_set. If there is a match the call
|
||||
succeeds and returns non-zero. The matching rule is equivalent to the matching rule for match.<br><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='#match_doc'>match</a></div></div><hr>
|
||||
<h2 id='section_lexer_library'>§5 Lexer Library</h2><h3>§5.1 Lexer Intro</h3><div>The 4cpp lexer system provides a polished, fast, flexible system that takes in C/C++ and outputs a tokenization of the text data. There are two API levels. One level is setup to let you easily get a tokenization of the file. This level manages memory for you with malloc to make it as fast as possible to start getting your tokens. The second level enables deep integration by allowing control over allocation, data chunking, and output rate control.<br><br>To use the quick setup API you simply include 4cpp_lexer.h and read the documentation at <a href='#cpp_lex_file_doc'>cpp_lex_file</a>.<br><br>To use the the fancier API include 4cpp_lexer.h and read the documentation at <a href='#cpp_lex_step_doc'>cpp_lex_step</a>. If you want to be absolutely sure you are not including malloc into your program you can define FCPP_FORBID_MALLOC before the include and the "step" API will continue to work.<br><br>There are a few more features in 4cpp that are not documented yet. You are free to try to use these, but I am not totally sure they are ready yet, and when they are they will be documented.</div><h3>§5.2 Lexer Function List</h3><ul><li><a href='#cpp_get_token_doc'>cpp_get_token</a></li><li><a href='#cpp_lex_step_doc'>cpp_lex_step</a></li><li><a href='#cpp_lex_data_init_doc'>cpp_lex_data_init</a></li><li><a href='#cpp_lex_data_temp_size_doc'>cpp_lex_data_temp_size</a></li><li><a href='#cpp_lex_data_temp_read_doc'>cpp_lex_data_temp_read</a></li><li><a href='#cpp_lex_data_new_temp_doc'>cpp_lex_data_new_temp</a></li><li><a href='#cpp_get_relex_range_doc'>cpp_get_relex_range</a></li><li><a href='#cpp_relex_init_doc'>cpp_relex_init</a></li><li><a href='#cpp_relex_start_position_doc'>cpp_relex_start_position</a></li><li><a href='#cpp_relex_declare_first_chunk_position_doc'>cpp_relex_declare_first_chunk_position</a></li><li><a href='#cpp_relex_is_start_chunk_doc'>cpp_relex_is_start_chunk</a></li><li><a href='#cpp_relex_step_doc'>cpp_relex_step</a></li><li><a href='#cpp_relex_get_new_count_doc'>cpp_relex_get_new_count</a></li><li><a href='#cpp_relex_complete_doc'>cpp_relex_complete</a></li><li><a href='#cpp_relex_abort_doc'>cpp_relex_abort</a></li><li><a href='#cpp_make_token_array_doc'>cpp_make_token_array</a></li><li><a href='#cpp_free_token_array_doc'>cpp_free_token_array</a></li><li><a href='#cpp_resize_token_array_doc'>cpp_resize_token_array</a></li><li><a href='#cpp_lex_file_doc'>cpp_lex_file</a></li></ul><h3>§5.3 Lexer Types List</h3><ul><li><a href='#Cpp_Token_Type_doc'>Cpp_Token_Type</a></li><li><a href='#Cpp_Token_doc'>Cpp_Token</a></li><li><a href='#Cpp_Token_Flag_doc'>Cpp_Token_Flag</a></li><li><a href='#Cpp_Token_Array_doc'>Cpp_Token_Array</a></li><li><a href='#Cpp_Get_Token_Result_doc'>Cpp_Get_Token_Result</a></li><li><a href='#Cpp_Relex_Range_doc'>Cpp_Relex_Range</a></li><li><a href='#Cpp_Lex_Data_doc'>Cpp_Lex_Data</a></li><li><a href='#Cpp_Lex_Result_doc'>Cpp_Lex_Result</a></li><li><a href='#Cpp_Relex_Data_doc'>Cpp_Relex_Data</a></li></ul><h3>§5.4 Lexer Function Descriptions</h3><div id='cpp_get_token_doc' style='margin-bottom: 1cm;'><h4>§5.4.1: cpp_get_token</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;'>Cpp_Get_Token_Result cpp_get_token(<div style='margin-left: 4mm;'>Cpp_Token_Array *token_array_in,<br>int32_t pos<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>token_array</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The array of tokens from which to get a token.</div></div></div><div><div style='font-weight: 600;'>pos</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The position, measured in bytes, to get the token for.</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;'>A Cpp_Get_Token_Result struct is returned containing the index
|
||||
<h2 id='section_lexer_library'>§5 Lexer Library</h2><h3>§5.1 Lexer Intro</h3><div>The 4cpp lexer system provides a polished, fast, flexible system that takes in C/C++ and outputs a tokenization of the text data. There are two API levels. One level is setup to let you easily get a tokenization of the file. This level manages memory for you with malloc to make it as fast as possible to start getting your tokens. The second level enables deep integration by allowing control over allocation, data chunking, and output rate control.<br><br>To use the quick setup API you simply include 4cpp_lexer.h and read the documentation at <a href='#cpp_lex_file_doc'>cpp_lex_file</a>.<br><br>To use the the fancier API include 4cpp_lexer.h and read the documentation at <a href='#cpp_lex_step_doc'>cpp_lex_step</a>. If you want to be absolutely sure you are not including malloc into your program you can define FCPP_FORBID_MALLOC before the include and the "step" API will continue to work.<br><br>There are a few more features in 4cpp that are not documented yet. You are free to try to use these, but I am not totally sure they are ready yet, and when they are they will be documented.</div><h3>§5.2 Lexer Function List</h3><ul><li><a href='#cpp_get_token_doc'>cpp_get_token</a></li><li><a href='#cpp_lex_step_doc'>cpp_lex_step</a></li><li><a href='#cpp_lex_data_init_doc'>cpp_lex_data_init</a></li><li><a href='#cpp_lex_data_temp_size_doc'>cpp_lex_data_temp_size</a></li><li><a href='#cpp_lex_data_temp_read_doc'>cpp_lex_data_temp_read</a></li><li><a href='#cpp_lex_data_new_temp_DEP_doc'>cpp_lex_data_new_temp_DEP</a></li><li><a href='#cpp_get_relex_range_doc'>cpp_get_relex_range</a></li><li><a href='#cpp_relex_init_doc'>cpp_relex_init</a></li><li><a href='#cpp_relex_start_position_doc'>cpp_relex_start_position</a></li><li><a href='#cpp_relex_declare_first_chunk_position_doc'>cpp_relex_declare_first_chunk_position</a></li><li><a href='#cpp_relex_is_start_chunk_doc'>cpp_relex_is_start_chunk</a></li><li><a href='#cpp_relex_step_doc'>cpp_relex_step</a></li><li><a href='#cpp_relex_get_new_count_doc'>cpp_relex_get_new_count</a></li><li><a href='#cpp_relex_complete_doc'>cpp_relex_complete</a></li><li><a href='#cpp_relex_abort_doc'>cpp_relex_abort</a></li><li><a href='#cpp_make_token_array_doc'>cpp_make_token_array</a></li><li><a href='#cpp_free_token_array_doc'>cpp_free_token_array</a></li><li><a href='#cpp_resize_token_array_doc'>cpp_resize_token_array</a></li><li><a href='#cpp_lex_file_doc'>cpp_lex_file</a></li></ul><h3>§5.3 Lexer Types List</h3><ul><li><a href='#Cpp_Token_Type_doc'>Cpp_Token_Type</a></li><li><a href='#Cpp_Token_doc'>Cpp_Token</a></li><li><a href='#Cpp_Token_Flag_doc'>Cpp_Token_Flag</a></li><li><a href='#Cpp_Token_Array_doc'>Cpp_Token_Array</a></li><li><a href='#Cpp_Get_Token_Result_doc'>Cpp_Get_Token_Result</a></li><li><a href='#Cpp_Relex_Range_doc'>Cpp_Relex_Range</a></li><li><a href='#Cpp_Lex_Data_doc'>Cpp_Lex_Data</a></li><li><a href='#Cpp_Lex_Result_doc'>Cpp_Lex_Result</a></li><li><a href='#Cpp_Relex_Data_doc'>Cpp_Relex_Data</a></li></ul><h3>§5.4 Lexer Function Descriptions</h3><div id='cpp_get_token_doc' style='margin-bottom: 1cm;'><h4>§5.4.1: cpp_get_token</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;'>Cpp_Get_Token_Result cpp_get_token(<div style='margin-left: 4mm;'>Cpp_Token_Array *token_array_in,<br>int32_t pos<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>token_array</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The array of tokens from which to get a token.</div></div></div><div><div style='font-weight: 600;'>pos</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The position, measured in bytes, to get the token for.</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;'>A Cpp_Get_Token_Result struct is returned containing the index
|
||||
of a token and a flag indicating whether the pos is contained in the token
|
||||
or in whitespace after the token.</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 performs a binary search over all of the tokens looking
|
||||
for the token that contains the specified position. If the position
|
||||
|
@ -328,29 +328,22 @@ system says it needs a chunk. You may switch to or modify the output array in b
|
|||
The most basic use of this system is to get it all done in one big chunk and try to allocate a nearly "infinite" output
|
||||
array so that it will not run out of memory. This way you can get the entire job done in one call and then just assert
|
||||
to make sure it returns LexResult_Finished to you:<br><br>
|
||||
<br><br><div style='font-family: "Courier New", Courier, monospace; text-align: left;margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #EFEFDF; padding: 0.25em;'>Cpp_Token_Array lex_file(char *file_name){<br> File_Data file = read_whole_file(file_name);<br> <br> char *temp = (char*)malloc(4096); // hopefully big enough<br> Cpp_Lex_Data lex_state = cpp_lex_data_init(temp); <br> <br> Cpp_Token_Array array = {0};<br> array.tokens = (Cpp_Token*)malloc(1 << 20); // hopefully big enough<br> array.max_count = (1 << 20)/sizeof(Cpp_Token);<br> <br> Cpp_Lex_Result result = <br> cpp_lex_step(&lex_state, file.data, file.size, file.size,<br> &array, NO_OUT_LIMIT);<br> Assert(result == LexResult_Finished);<br> <br> free(temp);<br> <br> return(array);<br>}<br></div></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='#Cpp_Lex_Data_doc'>Cpp_Lex_Data</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Cpp_Lex_Result_doc'>Cpp_Lex_Result</a></div></div><hr><div id='cpp_lex_data_init_doc' style='margin-bottom: 1cm;'><h4>§5.4.3: cpp_lex_data_init</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;'>Cpp_Lex_Data cpp_lex_data_init(<div style='margin-left: 4mm;'>char *mem_buffer<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>mem_buffer</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The memory to use for initializing the lex state's temp memory buffer.</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;'>A brand new lex state ready to begin lexing a file from the beginning.</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;'>Creates a new lex state in the form of a Cpp_Lex_Data struct and returns the struct.
|
||||
<br><br><div style='font-family: "Courier New", Courier, monospace; text-align: left;margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #EFEFDF; padding: 0.25em;'>Cpp_Token_Array lex_file(char *file_name){<br> File_Data file = read_whole_file(file_name);<br> <br> char *temp = (char*)malloc(4096); // hopefully big enough<br> Cpp_Lex_Data lex_state = cpp_lex_data_init(temp); <br> <br> Cpp_Token_Array array = {0};<br> array.tokens = (Cpp_Token*)malloc(1 << 20); // hopefully big enough<br> array.max_count = (1 << 20)/sizeof(Cpp_Token);<br> <br> Cpp_Lex_Result result = <br> cpp_lex_step(&lex_state, file.data, file.size, file.size,<br> &array, NO_OUT_LIMIT);<br> Assert(result == LexResult_Finished);<br> <br> free(temp);<br> <br> return(array);<br>}<br></div></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='#Cpp_Lex_Data_doc'>Cpp_Lex_Data</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Cpp_Lex_Result_doc'>Cpp_Lex_Result</a></div></div><hr><div id='cpp_lex_data_init_doc' style='margin-bottom: 1cm;'><h4>§5.4.3: cpp_lex_data_init</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;'>Cpp_Lex_Data cpp_lex_data_init(<div style='margin-left: 4mm;'><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;'>A brand new lex state ready to begin lexing a file from the beginning.</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;'>Creates a new lex state in the form of a Cpp_Lex_Data struct and returns the struct.
|
||||
The system needs a temporary buffer that is as long as the longest token. 4096 is usually
|
||||
enough but the buffer is not checked, so to be 100% bullet proof it has to be the same length
|
||||
as the file being lexed.<br><br></div></div><hr><div id='cpp_lex_data_temp_size_doc' style='margin-bottom: 1cm;'><h4>§5.4.4: cpp_lex_data_temp_size</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 cpp_lex_data_temp_size(<div style='margin-left: 4mm;'>Cpp_Lex_Data *lex_data<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>lex_data</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The lex state from which to get the temporary buffer size.</div></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;'>This call gets the current size of the temporary buffer in the lexer state so
|
||||
that you can move to a new temporary buffer by copying the data over.<br><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='#cpp_lex_data_temp_read_doc'>cpp_lex_data_temp_read</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#cpp_lex_data_new_temp_doc'>cpp_lex_data_new_temp</a></div></div><hr><div id='cpp_lex_data_temp_read_doc' style='margin-bottom: 1cm;'><h4>§5.4.5: cpp_lex_data_temp_read</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 cpp_lex_data_temp_read(<div style='margin-left: 4mm;'>Cpp_Lex_Data *lex_data,<br>char *out_buffer<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>lex_data</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The lex state from which to read the temporary buffer.</div></div></div><div><div style='font-weight: 600;'>out_buffer</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The buffer into which the contents of the temporary buffer will be written.
|
||||
The size of the buffer must be at least the size as returned by cpp_lex_data_temp_size.</div></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;'>This call reads the current contents of the temporary buffer.<br><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='#cpp_lex_data_temp_size_doc'>cpp_lex_data_temp_size</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#cpp_lex_data_new_temp_doc'>cpp_lex_data_new_temp</a></div></div><hr><div id='cpp_lex_data_new_temp_doc' style='margin-bottom: 1cm;'><h4>§5.4.6: cpp_lex_data_new_temp</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 cpp_lex_data_new_temp(<div style='margin-left: 4mm;'>Cpp_Lex_Data *lex_data,<br>char *new_buffer<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>lex_data</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The lex state that will receive the new temporary buffer.</div></div></div><div><div style='font-weight: 600;'>new_buffer</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The new temporary buffer that has the same contents as the old temporary buffer.</div></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;'>This call can be used to set a new temporary buffer for the lex state. In cases where you want to
|
||||
discontinue lexing, store the state, and resume later. In such a situation it may be necessary for you
|
||||
to free the temp buffer that was originally used to make the lex state. This call allows you to supply
|
||||
a new temp buffer when you are ready to resume lexing.<br><br>
|
||||
However the new buffer needs to have the same contents the old buffer had. To ensure this you have to
|
||||
use cpp_lex_data_temp_size and cpp_lex_data_temp_read to get the relevant contents of the temp buffer
|
||||
before you free it.<br><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='#cpp_lex_data_temp_size_doc'>cpp_lex_data_temp_size</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#cpp_lex_data_temp_read_doc'>cpp_lex_data_temp_read</a></div></div><hr><div id='cpp_get_relex_range_doc' style='margin-bottom: 1cm;'><h4>§5.4.7: cpp_get_relex_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;'>Cpp_Relex_Range cpp_get_relex_range(<div style='margin-left: 4mm;'>Cpp_Token_Array *array,<br>int32_t start_pos,<br>int32_t end_pos<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>array</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>A pointer to the token array that will be modified by the relex,
|
||||
The size of the buffer must be at least the size as returned by cpp_lex_data_temp_size.</div></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;'>This call reads the current contents of the temporary buffer.<br><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='#cpp_lex_data_temp_size_doc'>cpp_lex_data_temp_size</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#cpp_lex_data_new_temp_doc'>cpp_lex_data_new_temp</a></div></div><hr><div id='cpp_lex_data_new_temp_DEP_doc' style='margin-bottom: 1cm;'><h4>§5.4.6: cpp_lex_data_new_temp_DEP</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 cpp_lex_data_new_temp_DEP(<div style='margin-left: 4mm;'>Cpp_Lex_Data *lex_data,<br>char *new_buffer<br></div>)</div></div><hr><div id='cpp_get_relex_range_doc' style='margin-bottom: 1cm;'><h4>§5.4.7: cpp_get_relex_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;'>Cpp_Relex_Range cpp_get_relex_range(<div style='margin-left: 4mm;'>Cpp_Token_Array *array,<br>int32_t start_pos,<br>int32_t end_pos<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>array</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>A pointer to the token array that will be modified by the relex,
|
||||
this array should already contain the tokens for the previous state of the file.</div></div></div><div><div style='font-weight: 600;'>start_pos</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The start position of the edited region of the file.
|
||||
The start and end points are based on the edited region of the file before the edit.</div></div></div><div><div style='font-weight: 600;'>end_pos</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The end position of the edited region of the file.
|
||||
In particular, end_pos is the first character after the edited region not effected by the edit.
|
||||
Thus if the edited region contained one character end_pos - start_pos should equal 1.
|
||||
The start and end points are based on the edited region of the file before the edit.</div></div></div></div><hr><div id='cpp_relex_init_doc' style='margin-bottom: 1cm;'><h4>§5.4.8: cpp_relex_init</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;'>Cpp_Relex_Data cpp_relex_init(<div style='margin-left: 4mm;'>Cpp_Token_Array *array,<br>int32_t start_pos,<br>int32_t end_pos,<br>int32_t character_shift_amount,<br>char *spare<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>array</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>A pointer to the token array that will be modified by the relex,
|
||||
The start and end points are based on the edited region of the file before the edit.</div></div></div></div><hr><div id='cpp_relex_init_doc' style='margin-bottom: 1cm;'><h4>§5.4.8: cpp_relex_init</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;'>Cpp_Relex_Data cpp_relex_init(<div style='margin-left: 4mm;'>Cpp_Token_Array *array,<br>int32_t start_pos,<br>int32_t end_pos,<br>int32_t character_shift_amount<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>array</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>A pointer to the token array that will be modified by the relex,
|
||||
this array should already contain the tokens for the previous state of the file.</div></div></div><div><div style='font-weight: 600;'>start_pos</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The start position of the edited region of the file.
|
||||
The start and end points are based on the edited region of the file before the edit.</div></div></div><div><div style='font-weight: 600;'>end_pos</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The end position of the edited region of the file.
|
||||
In particular, end_pos is the first character after the edited region not effected by the edit.
|
||||
Thus if the edited region contained one character end_pos - start_pos should equal 1.
|
||||
The start and end points are based on the edited region of the file before the edit.</div></div></div><div><div style='font-weight: 600;'>character_shift_amount</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The shift in the characters after the edited region.</div></div></div><div><div style='font-weight: 600;'>spare</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The spare space for the lexing state.
|
||||
Should be big enough to store the largest token in the file.</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;'>Returns a partially initialized relex state.</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 does the first setup step of initializing a relex state. To finish initializing the relex state
|
||||
The start and end points are based on the edited region of the file before the edit.</div></div></div><div><div style='font-weight: 600;'>character_shift_amount</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The shift in the characters after the edited region.</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;'>Returns a partially initialized relex state.</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 does the first setup step of initializing a relex state. To finish initializing the relex state
|
||||
you must tell the state about the positioning of the first chunk it will be fed. There are two methods of doing
|
||||
this, the direct method is with cpp_relex_declare_first_chunk_position, the method that is often more convenient
|
||||
is with cpp_relex_is_start_chunk. If the file is not chunked the second step of initialization can be skipped.<br><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='#cpp_relex_declare_first_chunk_position_doc'>cpp_relex_declare_first_chunk_position</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#cpp_relex_is_start_chunk_doc'>cpp_relex_is_start_chunk</a></div></div><hr><div id='cpp_relex_start_position_doc' style='margin-bottom: 1cm;'><h4>§5.4.9: cpp_relex_start_position</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 cpp_relex_start_position(<div style='margin-left: 4mm;'>Cpp_Relex_Data *S_ptr<br></div>)</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div><div style='font-weight: 600;'>S_ptr</div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'></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;'>Returns the first position in the file the relexer wants to read. This is usually a position slightly
|
||||
|
|
122
4cpp_lexer.h
122
4cpp_lexer.h
|
@ -314,7 +314,9 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz
|
|||
S.chunk_pos += size;
|
||||
DrYield(4, LexResult_NeedChunk);
|
||||
}
|
||||
else break;
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
--S.pos;
|
||||
if (S.pp_state >= LSPP_count){
|
||||
|
@ -333,7 +335,7 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz
|
|||
|
||||
for (; S.fsm.state < LS_count && S.pos < end_pos;){
|
||||
c = chunk[S.pos++];
|
||||
S.tb[S.tb_pos++] = c;
|
||||
S.tb[(S.tb_pos++) & (sizeof(S.tb)-1)] = c;
|
||||
|
||||
int32_t i = S.fsm.state + eq_classes[c];
|
||||
S.fsm.state = fsm_table[i];
|
||||
|
@ -346,7 +348,9 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz
|
|||
S.chunk_pos += size;
|
||||
DrYield(3, LexResult_NeedChunk);
|
||||
}
|
||||
else break;
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(S.fsm.emit_token == 1);
|
||||
|
@ -426,27 +430,29 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz
|
|||
|
||||
int32_t word_size = S.pos - S.token_start;
|
||||
|
||||
if (S.pp_state == LSPP_body_if){
|
||||
if (match_ss(make_string(S.tb, word_size), make_lit_string("defined"))){
|
||||
S.token.type = CPP_PP_DEFINED;
|
||||
S.token.flags = CPP_TFLAG_IS_OPERATOR | CPP_TFLAG_IS_KEYWORD;
|
||||
if (word_size < sizeof(S.tb)){
|
||||
if (S.pp_state == LSPP_body_if){
|
||||
if (match_ss(make_string(S.tb, word_size), make_lit_string("defined"))){
|
||||
S.token.type = CPP_PP_DEFINED;
|
||||
S.token.flags = CPP_TFLAG_IS_OPERATOR | CPP_TFLAG_IS_KEYWORD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t sub_match = -1;
|
||||
string_set_match_table(keywords, sizeof(*keywords), ArrayCount(keywords),
|
||||
make_string(S.tb, S.tb_pos-1), &sub_match);
|
||||
|
||||
if (sub_match != -1){
|
||||
String_And_Flag data = keywords[sub_match];
|
||||
S.token.type = (Cpp_Token_Type)data.flags;
|
||||
S.token.flags = CPP_TFLAG_IS_KEYWORD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t sub_match = -1;
|
||||
string_set_match_table(keywords, sizeof(*keywords), ArrayCount(keywords),
|
||||
make_string(S.tb, S.tb_pos-1), &sub_match);
|
||||
|
||||
if (sub_match != -1){
|
||||
String_And_Flag data = keywords[sub_match];
|
||||
S.token.type = (Cpp_Token_Type)data.flags;
|
||||
S.token.flags = CPP_TFLAG_IS_KEYWORD;
|
||||
}
|
||||
else{
|
||||
S.token.type = CPP_TOKEN_IDENTIFIER;
|
||||
S.token.flags = 0;
|
||||
}
|
||||
S.token.type = CPP_TOKEN_IDENTIFIER;
|
||||
S.token.flags = 0;
|
||||
}break;
|
||||
|
||||
case LS_pound:
|
||||
|
@ -471,28 +477,30 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz
|
|||
{
|
||||
--S.pos;
|
||||
|
||||
int32_t pos = S.tb_pos-1;
|
||||
int32_t i = 1;
|
||||
for (;i < pos; ++i){
|
||||
if (S.tb[i] != ' '){
|
||||
if (S.tb_pos < sizeof(S.tb)){
|
||||
int32_t pos = S.tb_pos-1;
|
||||
int32_t i = 1;
|
||||
for (;i < pos; ++i){
|
||||
if (S.tb[i] != ' '){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t sub_match = -1;
|
||||
string_set_match_table(preprops, sizeof(*preprops), ArrayCount(preprops),
|
||||
make_string(S.tb+i, pos-i), &sub_match);
|
||||
|
||||
if (sub_match != -1){
|
||||
String_And_Flag data = preprops[sub_match];
|
||||
S.token.type = (Cpp_Token_Type)data.flags;
|
||||
S.token.flags = CPP_TFLAG_PP_DIRECTIVE;
|
||||
S.pp_state = (uint8_t)cpp_pp_directive_to_state(S.token.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t sub_match = -1;
|
||||
string_set_match_table(preprops, sizeof(*preprops), ArrayCount(preprops),
|
||||
make_string(S.tb+i, pos-i), &sub_match);
|
||||
|
||||
if (sub_match != -1){
|
||||
String_And_Flag data = preprops[sub_match];
|
||||
S.token.type = (Cpp_Token_Type)data.flags;
|
||||
S.token.flags = CPP_TFLAG_PP_DIRECTIVE;
|
||||
S.pp_state = (uint8_t)cpp_pp_directive_to_state(S.token.type);
|
||||
}
|
||||
else{
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
S.token.flags = 0;
|
||||
}
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
S.token.flags = 0;
|
||||
}break;
|
||||
|
||||
case LS_number:
|
||||
|
@ -1034,8 +1042,7 @@ DOC_SEE(Cpp_Lex_Result)
|
|||
}
|
||||
|
||||
FCPP_LINK Cpp_Lex_Data
|
||||
cpp_lex_data_init(char *mem_buffer)/*
|
||||
DOC_PARAM(mem_buffer, The memory to use for initializing the lex state's temp memory buffer.)
|
||||
cpp_lex_data_init()/*
|
||||
DOC_RETURN(A brand new lex state ready to begin lexing a file from the beginning.)
|
||||
|
||||
DOC(Creates a new lex state in the form of a Cpp_Lex_Data struct and returns the struct.
|
||||
|
@ -1044,7 +1051,6 @@ enough but the buffer is not checked, so to be 100% bullet proof it has to be th
|
|||
as the file being lexed.)
|
||||
*/{
|
||||
Cpp_Lex_Data data = {0};
|
||||
data.tb = mem_buffer;
|
||||
return(data);
|
||||
}
|
||||
|
||||
|
@ -1079,24 +1085,8 @@ DOC_SEE(cpp_lex_data_new_temp)
|
|||
}
|
||||
|
||||
FCPP_LINK void
|
||||
cpp_lex_data_new_temp(Cpp_Lex_Data *lex_data, char *new_buffer)/*
|
||||
DOC_PARAM(lex_data, The lex state that will receive the new temporary buffer.)
|
||||
DOC_PARAM(new_buffer, The new temporary buffer that has the same contents as the old temporary buffer.)
|
||||
|
||||
DOC(This call can be used to set a new temporary buffer for the lex state. In cases where you want to
|
||||
discontinue lexing, store the state, and resume later. In such a situation it may be necessary for you
|
||||
to free the temp buffer that was originally used to make the lex state. This call allows you to supply
|
||||
a new temp buffer when you are ready to resume lexing.
|
||||
|
||||
However the new buffer needs to have the same contents the old buffer had. To ensure this you have to
|
||||
use cpp_lex_data_temp_size and cpp_lex_data_temp_read to get the relevant contents of the temp buffer
|
||||
before you free it.)
|
||||
|
||||
DOC_SEE(cpp_lex_data_temp_size)
|
||||
DOC_SEE(cpp_lex_data_temp_read)
|
||||
*/{
|
||||
lex_data->tb = new_buffer;
|
||||
}
|
||||
cpp_lex_data_new_temp_DEP(Cpp_Lex_Data *lex_data, char *new_buffer)
|
||||
/*DOC(Deprecated in 4cpp Lexer 1.0.1*/{}
|
||||
|
||||
FCPP_INTERNAL char
|
||||
cpp_token_get_pp_state(uint16_t bitfield){
|
||||
|
@ -1162,7 +1152,7 @@ The start and end points are based on the edited region of the file before the e
|
|||
}
|
||||
|
||||
FCPP_LINK Cpp_Relex_Data
|
||||
cpp_relex_init(Cpp_Token_Array *array, int32_t start_pos, int32_t end_pos, int32_t character_shift_amount, char *spare)
|
||||
cpp_relex_init(Cpp_Token_Array *array, int32_t start_pos, int32_t end_pos, int32_t character_shift_amount)
|
||||
/*
|
||||
DOC_PARAM(array, A pointer to the token array that will be modified by the relex,
|
||||
this array should already contain the tokens for the previous state of the file.)
|
||||
|
@ -1173,8 +1163,6 @@ In particular, end_pos is the first character after the edited region not effect
|
|||
Thus if the edited region contained one character end_pos - start_pos should equal 1.
|
||||
The start and end points are based on the edited region of the file before the edit.)
|
||||
DOC_PARAM(character_shift_amount, The shift in the characters after the edited region.)
|
||||
DOC_PARAM(spare, The spare space for the lexing state.
|
||||
Should be big enough to store the largest token in the file.)
|
||||
DOC_RETURN(Returns a partially initialized relex state.)
|
||||
|
||||
DOC(This call does the first setup step of initializing a relex state. To finish initializing the relex state
|
||||
|
@ -1200,7 +1188,7 @@ DOC_SEE(cpp_relex_is_start_chunk)
|
|||
|
||||
state.character_shift_amount = character_shift_amount;
|
||||
|
||||
state.lex = cpp_lex_data_init(spare);
|
||||
state.lex = cpp_lex_data_init();
|
||||
state.lex.pp_state = cpp_token_get_pp_state(array->tokens[state.start_token_index].state_flags);
|
||||
state.lex.pos = state.relex_start_position;
|
||||
|
||||
|
@ -1348,6 +1336,7 @@ DOC_SEE(cpp_relex_abort)
|
|||
*/{
|
||||
|
||||
Cpp_Relex_Data S = *S_ptr;
|
||||
Cpp_Lex_Result step_result = LexResult_Finished;
|
||||
|
||||
switch (S.__pc__){
|
||||
DrCase(1);
|
||||
|
@ -1359,7 +1348,7 @@ DOC_SEE(cpp_relex_abort)
|
|||
|
||||
// TODO(allen): This can be better I suspect.
|
||||
for (;;){
|
||||
Cpp_Lex_Result step_result =
|
||||
step_result =
|
||||
cpp_lex_nonalloc_no_null_out_limit(&S.lex, chunk, chunk_size, full_size,
|
||||
relex_array, 1);
|
||||
|
||||
|
@ -1564,8 +1553,7 @@ Cpp_Token_Array lex_file(char *file_name){
|
|||
)
|
||||
DOC_SEE(cpp_make_token_array)
|
||||
*/{
|
||||
Cpp_Lex_Data S = {0};
|
||||
S.tb = (char*)malloc(size);
|
||||
Cpp_Lex_Data S = cpp_lex_data_init();
|
||||
int32_t quit = 0;
|
||||
|
||||
char empty = 0;
|
||||
|
@ -1600,8 +1588,6 @@ DOC_SEE(cpp_make_token_array)
|
|||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
free(S.tb);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -332,8 +332,7 @@ The internals of the lex state should not be treated as a part of the public API
|
|||
DOC_SEE(cpp_lex_data_init)
|
||||
HIDE_MEMBERS()*/
|
||||
struct Cpp_Lex_Data{
|
||||
char *tb;
|
||||
|
||||
char tb[32];
|
||||
int32_t tb_pos;
|
||||
int32_t token_start;
|
||||
|
||||
|
|
|
@ -1127,20 +1127,18 @@ Job_Callback_Sig(job_full_lex){
|
|||
|
||||
i32 buffer_size = (text_size + 3)&(~3);
|
||||
|
||||
while (memory->size < buffer_size*2){
|
||||
while (memory->size < buffer_size){
|
||||
system->grow_thread_memory(memory);
|
||||
}
|
||||
|
||||
char *tb = (char*)memory->data;
|
||||
|
||||
Cpp_Token_Array tokens;
|
||||
tokens.tokens = (Cpp_Token*)((char*)memory->data + buffer_size);
|
||||
tokens.max_count = (memory->size - buffer_size) / sizeof(Cpp_Token);
|
||||
tokens.tokens = (Cpp_Token*)(memory->data);
|
||||
tokens.max_count = memory->size / sizeof(Cpp_Token);
|
||||
tokens.count = 0;
|
||||
|
||||
b32 still_lexing = 1;
|
||||
|
||||
Cpp_Lex_Data lex = cpp_lex_data_init(tb);
|
||||
Cpp_Lex_Data lex = cpp_lex_data_init();
|
||||
|
||||
// TODO(allen): deduplicate this against relex
|
||||
char *chunks[3];
|
||||
|
@ -1165,18 +1163,15 @@ Job_Callback_Sig(job_full_lex){
|
|||
cpp_lex_step(&lex, chunk, chunk_size, text_size, &tokens, 2048);
|
||||
|
||||
switch (result){
|
||||
case LexResult_NeedChunk:
|
||||
++chunk_index;
|
||||
break;
|
||||
case LexResult_NeedChunk: ++chunk_index; break;
|
||||
|
||||
case LexResult_NeedTokenMemory:
|
||||
if (system->check_cancel(thread)){
|
||||
return;
|
||||
}
|
||||
system->grow_thread_memory(memory);
|
||||
lex.tb = (char*)memory->data;
|
||||
tokens.tokens = (Cpp_Token*)((char*)memory->data + buffer_size);
|
||||
tokens.max_count = (memory->size - buffer_size) / sizeof(Cpp_Token);
|
||||
tokens.tokens = (Cpp_Token*)(memory->data);
|
||||
tokens.max_count = memory->size / sizeof(Cpp_Token);
|
||||
break;
|
||||
|
||||
case LexResult_HitTokenLimit:
|
||||
|
@ -1294,9 +1289,8 @@ file_relex_parallel(System_Functions *system,
|
|||
relex_array.tokens = push_array(part, Cpp_Token, relex_array.max_count);
|
||||
|
||||
i32 size = buffer_size(buffer);
|
||||
char *spare = push_array(part, char, size+1);
|
||||
|
||||
Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount, spare);
|
||||
Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount);
|
||||
|
||||
char *chunks[3];
|
||||
i32 chunk_sizes[3];
|
||||
|
|
|
@ -3470,7 +3470,8 @@ main(int argc, char **argv)
|
|||
&linuxvars.target,
|
||||
&memory_vars,
|
||||
&linuxvars.input,
|
||||
&result
|
||||
&result,
|
||||
clparams
|
||||
);
|
||||
|
||||
if(result.perform_kill){
|
||||
|
|
|
@ -1,206 +1,206 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 12.12.2014
|
||||
*
|
||||
* Application layer for project codename "4ed"
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#include "4ed_meta.h"
|
||||
#include "4ed_dll_reader.h"
|
||||
#include "4ed_dll_reader.cpp"
|
||||
|
||||
i32
|
||||
compare(char *a, char *b, i32 len){
|
||||
i32 result;
|
||||
char *e;
|
||||
|
||||
result = 0;
|
||||
e = a + len;
|
||||
for (;a < e && *a == *b; ++a, ++b);
|
||||
if (a < e){
|
||||
if (*a < *b) result = -1;
|
||||
else result = 1;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
Data
|
||||
load_file(char *filename){
|
||||
Data result;
|
||||
FILE * file;
|
||||
|
||||
result = {};
|
||||
file = fopen(filename, "rb");
|
||||
if (!file){
|
||||
printf("file %s not found\n", filename);
|
||||
}
|
||||
else{
|
||||
fseek(file, 0, SEEK_END);
|
||||
result.size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
result.data = (byte*)malloc(result.size);
|
||||
fread(result.data, 1, result.size, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
void
|
||||
show_reloc_block(Data file, DLL_Data *dll, PE_Section_Definition *reloc_section){
|
||||
byte *base;
|
||||
Relocation_Block_Header *header;
|
||||
Relocation_Block_Entry *entry;
|
||||
u32 cursor;
|
||||
u32 bytes_in_table;
|
||||
u32 block_end;
|
||||
|
||||
base = file.data + reloc_section->disk_location;
|
||||
if (dll->is_64bit) bytes_in_table = dll->opt_header_64->data_directory[image_dir_base_reloc_table].size;
|
||||
else bytes_in_table = dll->opt_header_32->data_directory[image_dir_base_reloc_table].size;
|
||||
|
||||
for (cursor = 0; cursor < bytes_in_table;){
|
||||
header = (Relocation_Block_Header*)(base + cursor);
|
||||
block_end = cursor + header->block_size;
|
||||
cursor += sizeof(Relocation_Block_Header);
|
||||
|
||||
printf("block-size: %d\n", header->block_size);
|
||||
printf("offset-base: %d\n", header->page_base_offset);
|
||||
|
||||
for (;cursor < block_end;){
|
||||
entry = (Relocation_Block_Entry*)(base + cursor);
|
||||
cursor += sizeof(Relocation_Block_Entry);
|
||||
printf("reloc: type %d offset %d\n",
|
||||
(i32)(entry->entry & reloc_entry_type_mask) >> reloc_entry_type_shift,
|
||||
(i32)(entry->entry & reloc_entry_offset_mask));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef int32_t (Function)(int a, int b);
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#define UseWinDll 0
|
||||
|
||||
int
|
||||
main(int argc, char **argv){
|
||||
Function *func;
|
||||
i32 x;
|
||||
|
||||
#if UseWinDll
|
||||
HMODULE module;
|
||||
|
||||
if (argc < 2){
|
||||
printf("usage: dll_reader <dll-file>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
module = LoadLibraryA(argv[1]);
|
||||
|
||||
if (!module){
|
||||
printf("failed to load file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
func = (Function*)GetProcAddress(module, "test_func");
|
||||
|
||||
#else
|
||||
Data file, img;
|
||||
DLL_Data dll;
|
||||
DLL_Loaded dll_loaded;
|
||||
PE_Section_Definition *section_def;
|
||||
i32 error;
|
||||
i32 i;
|
||||
|
||||
if (argc < 2){
|
||||
printf("usage: dll_reader <dll-file>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
file = load_file(argv[1]);
|
||||
|
||||
if (!file.data){
|
||||
printf("failed to load file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!dll_parse_headers(file, &dll, &error)){
|
||||
printf("header error %d\n", error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("this appears to be a dll\n");
|
||||
|
||||
printf("symbol-count: %d symbol-addr: %d\n",
|
||||
dll.coff_header->number_of_symbols,
|
||||
dll.coff_header->pointer_to_symbol_table);
|
||||
|
||||
if (dll.is_64bit) printf("64bit\n");
|
||||
else printf("32bit\n");
|
||||
|
||||
printf("built for machine: %s\n", dll_machine_type_str(dll.coff_header->machine, 0));
|
||||
|
||||
if (dll.is_64bit){
|
||||
printf("number of directories: %d\n", dll.opt_header_64->number_of_rva_and_sizes);
|
||||
}
|
||||
else{
|
||||
printf("number of directories: %d\n", dll.opt_header_32->number_of_rva_and_sizes);
|
||||
}
|
||||
|
||||
printf("\nbeginning section decode now\n");
|
||||
|
||||
section_def = dll.section_defs;
|
||||
for (i = 0; i < dll.coff_header->number_of_sections; ++i, ++section_def){
|
||||
if (section_def->name[7] == 0){
|
||||
printf("name: %s\n", section_def->name);
|
||||
}
|
||||
else{
|
||||
printf("name: %.*s\n", 8, section_def->name);
|
||||
}
|
||||
printf("img-size: %d img-loc: %d\ndisk-size: %d disk-loc: %d\n",
|
||||
section_def->loaded_size, section_def->loaded_location,
|
||||
section_def->disk_size, section_def->disk_location);
|
||||
|
||||
if (compare(section_def->name, ".reloc", 6) == 0){
|
||||
show_reloc_block(file, &dll, section_def);
|
||||
}
|
||||
}
|
||||
|
||||
img.size = dll_total_loaded_size(&dll);
|
||||
printf("image size: %d\n", img.size);
|
||||
|
||||
img.data = (byte*)
|
||||
VirtualAlloc((LPVOID)Tbytes(3), img.size,
|
||||
MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_READWRITE);
|
||||
dll_load(img, &dll_loaded, file, &dll);
|
||||
|
||||
DWORD _extra;
|
||||
VirtualProtect(img.data + dll_loaded.text_start,
|
||||
dll_loaded.text_size,
|
||||
PAGE_EXECUTE_READ,
|
||||
&_extra);
|
||||
|
||||
func = (Function*)dll_load_function(&dll_loaded, "test_func", 9);
|
||||
#endif
|
||||
|
||||
x = func(10, 20);
|
||||
printf("%d\n", x);
|
||||
|
||||
x = func(1, 2);
|
||||
printf("%d\n", x);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 12.12.2014
|
||||
*
|
||||
* Application layer for project codename "4ed"
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#include "4ed_meta.h"
|
||||
#include "4ed_dll_reader.h"
|
||||
#include "4ed_dll_reader.cpp"
|
||||
|
||||
i32
|
||||
compare(char *a, char *b, i32 len){
|
||||
i32 result;
|
||||
char *e;
|
||||
|
||||
result = 0;
|
||||
e = a + len;
|
||||
for (;a < e && *a == *b; ++a, ++b);
|
||||
if (a < e){
|
||||
if (*a < *b) result = -1;
|
||||
else result = 1;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
Data
|
||||
load_file(char *filename){
|
||||
Data result;
|
||||
FILE * file;
|
||||
|
||||
result = {};
|
||||
file = fopen(filename, "rb");
|
||||
if (!file){
|
||||
printf("file %s not found\n", filename);
|
||||
}
|
||||
else{
|
||||
fseek(file, 0, SEEK_END);
|
||||
result.size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
result.data = (byte*)malloc(result.size);
|
||||
fread(result.data, 1, result.size, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
void
|
||||
show_reloc_block(Data file, DLL_Data *dll, PE_Section_Definition *reloc_section){
|
||||
byte *base;
|
||||
Relocation_Block_Header *header;
|
||||
Relocation_Block_Entry *entry;
|
||||
u32 cursor;
|
||||
u32 bytes_in_table;
|
||||
u32 block_end;
|
||||
|
||||
base = file.data + reloc_section->disk_location;
|
||||
if (dll->is_64bit) bytes_in_table = dll->opt_header_64->data_directory[image_dir_base_reloc_table].size;
|
||||
else bytes_in_table = dll->opt_header_32->data_directory[image_dir_base_reloc_table].size;
|
||||
|
||||
for (cursor = 0; cursor < bytes_in_table;){
|
||||
header = (Relocation_Block_Header*)(base + cursor);
|
||||
block_end = cursor + header->block_size;
|
||||
cursor += sizeof(Relocation_Block_Header);
|
||||
|
||||
printf("block-size: %d\n", header->block_size);
|
||||
printf("offset-base: %d\n", header->page_base_offset);
|
||||
|
||||
for (;cursor < block_end;){
|
||||
entry = (Relocation_Block_Entry*)(base + cursor);
|
||||
cursor += sizeof(Relocation_Block_Entry);
|
||||
printf("reloc: type %d offset %d\n",
|
||||
(i32)(entry->entry & reloc_entry_type_mask) >> reloc_entry_type_shift,
|
||||
(i32)(entry->entry & reloc_entry_offset_mask));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef int32_t (Function)(int a, int b);
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#define UseWinDll 0
|
||||
|
||||
int
|
||||
main(int argc, char **argv){
|
||||
Function *func;
|
||||
i32 x;
|
||||
|
||||
#if UseWinDll
|
||||
HMODULE module;
|
||||
|
||||
if (argc < 2){
|
||||
printf("usage: dll_reader <dll-file>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
module = LoadLibraryA(argv[1]);
|
||||
|
||||
if (!module){
|
||||
printf("failed to load file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
func = (Function*)GetProcAddress(module, "test_func");
|
||||
|
||||
#else
|
||||
Data file, img;
|
||||
DLL_Data dll;
|
||||
DLL_Loaded dll_loaded;
|
||||
PE_Section_Definition *section_def;
|
||||
i32 error;
|
||||
i32 i;
|
||||
|
||||
if (argc < 2){
|
||||
printf("usage: dll_reader <dll-file>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
file = load_file(argv[1]);
|
||||
|
||||
if (!file.data){
|
||||
printf("failed to load file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!dll_parse_headers(file, &dll, &error)){
|
||||
printf("header error %d\n", error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("this appears to be a dll\n");
|
||||
|
||||
printf("symbol-count: %d symbol-addr: %d\n",
|
||||
dll.coff_header->number_of_symbols,
|
||||
dll.coff_header->pointer_to_symbol_table);
|
||||
|
||||
if (dll.is_64bit) printf("64bit\n");
|
||||
else printf("32bit\n");
|
||||
|
||||
printf("built for machine: %s\n", dll_machine_type_str(dll.coff_header->machine, 0));
|
||||
|
||||
if (dll.is_64bit){
|
||||
printf("number of directories: %d\n", dll.opt_header_64->number_of_rva_and_sizes);
|
||||
}
|
||||
else{
|
||||
printf("number of directories: %d\n", dll.opt_header_32->number_of_rva_and_sizes);
|
||||
}
|
||||
|
||||
printf("\nbeginning section decode now\n");
|
||||
|
||||
section_def = dll.section_defs;
|
||||
for (i = 0; i < dll.coff_header->number_of_sections; ++i, ++section_def){
|
||||
if (section_def->name[7] == 0){
|
||||
printf("name: %s\n", section_def->name);
|
||||
}
|
||||
else{
|
||||
printf("name: %.*s\n", 8, section_def->name);
|
||||
}
|
||||
printf("img-size: %d img-loc: %d\ndisk-size: %d disk-loc: %d\n",
|
||||
section_def->loaded_size, section_def->loaded_location,
|
||||
section_def->disk_size, section_def->disk_location);
|
||||
|
||||
if (compare(section_def->name, ".reloc", 6) == 0){
|
||||
show_reloc_block(file, &dll, section_def);
|
||||
}
|
||||
}
|
||||
|
||||
img.size = dll_total_loaded_size(&dll);
|
||||
printf("image size: %d\n", img.size);
|
||||
|
||||
img.data = (byte*)
|
||||
VirtualAlloc((LPVOID)Tbytes(3), img.size,
|
||||
MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_READWRITE);
|
||||
dll_load(img, &dll_loaded, file, &dll);
|
||||
|
||||
DWORD _extra;
|
||||
VirtualProtect(img.data + dll_loaded.text_start,
|
||||
dll_loaded.text_size,
|
||||
PAGE_EXECUTE_READ,
|
||||
&_extra);
|
||||
|
||||
func = (Function*)dll_load_function(&dll_loaded, "test_func", 9);
|
||||
#endif
|
||||
|
||||
x = func(10, 20);
|
||||
printf("%d\n", x);
|
||||
|
||||
x = func(1, 2);
|
||||
printf("%d\n", x);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
Loading…
Reference in New Issue