|
@@ -75,7 +75,7 @@ when 'syntax_active' is FALSE, we'll change it to true, so 'atexit' won't be exe |
|
|
we're just deallocating (freeing) the memory, so we don't leak it and generate Valgrind warnings. |
|
|
we're just deallocating (freeing) the memory, so we don't leak it and generate Valgrind warnings. |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
void syntax_delete (void) { |
|
|
|
|
|
|
|
|
static void syntax_delete (void) { |
|
|
int offset; |
|
|
int offset; |
|
|
|
|
|
|
|
|
if (syntax_count == 0) { // If syntax "library" wasn't used, we don't want to deallocate memory, we just return. |
|
|
if (syntax_count == 0) { // If syntax "library" wasn't used, we don't want to deallocate memory, we just return. |
|
@@ -160,8 +160,8 @@ This is more complex, but if you use your eyes to look, your brain to comprehend |
|
|
int syntax_select (char * string, int * length) { |
|
|
int syntax_select (char * string, int * length) { |
|
|
int offset, select; |
|
|
int offset, select; |
|
|
|
|
|
|
|
|
if (syntax_count == 0) { // Don't select without rules, return! |
|
|
|
|
|
return (0); |
|
|
|
|
|
|
|
|
if (syntax_count == 0) { // Don't select without rules, return! |
|
|
|
|
|
return (syntax_count); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fatal_failure (string == NULL, "syntax_select: String is null."); |
|
|
fatal_failure (string == NULL, "syntax_select: String is null."); |
|
@@ -171,30 +171,34 @@ int syntax_select (char * string, int * length) { |
|
|
// choosing whether to compare any of the characters, or full string, depending on 'syntax_enrange' value which is essentially boolean, true or false, which I express with |
|
|
// choosing whether to compare any of the characters, or full string, depending on 'syntax_enrange' value which is essentially boolean, true or false, which I express with |
|
|
// 'int' type for "type-safety simplicity". Keep in mind that we're not returning or modifying the string we provided, so it won't be null-terminated, instead I think |
|
|
// 'int' type for "type-safety simplicity". Keep in mind that we're not returning or modifying the string we provided, so it won't be null-terminated, instead I think |
|
|
// it's best to modify only variable 'length', hence we check with 'string_compare_limit' function. |
|
|
// it's best to modify only variable 'length', hence we check with 'string_compare_limit' function. |
|
|
for (select = offset = 0; select != syntax_count; ++select) { // We're looping defined syntax rules: |
|
|
|
|
|
if (syntax_enrange [select] == FALSE) { // Choosing the comparisson: |
|
|
|
|
|
if (syntax_derange [select] == FALSE) { |
|
|
|
|
|
if (string_compare_limit (string, syntax_begin [select], string_length (syntax_begin [select])) == TRUE) { // Limiting our string comparisson. |
|
|
|
|
|
break; // If strings are same, we exit the loop. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (select = offset = 0; select != syntax_count; ++select) { // We're looping defined syntax rules: |
|
|
|
|
|
int begin = string_length (syntax_begin [select]); |
|
|
|
|
|
|
|
|
|
|
|
if (syntax_enrange [select] == FALSE) { // Choosing the comparisson based on 'syntax_enrange': |
|
|
|
|
|
if (syntax_derange [select] == FALSE) { // Either full string, or any character in it. |
|
|
|
|
|
if (string_compare_limit (string, syntax_begin [select], begin) == TRUE) { // Limiting our string comparisson. |
|
|
|
|
|
break; // If strings are same, we exit the loop. |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
if ((string_compare_limit (string, syntax_begin [select], string_length (syntax_begin [select])) == TRUE) |
|
|
|
|
|
&& (character_compare_array (string [offset + string_length (syntax_begin [select])], syntax_end [select]) == TRUE)) { |
|
|
|
|
|
|
|
|
if ((string_compare_limit (string, syntax_begin [select], begin) == TRUE) // We need to see if we found our string, and: |
|
|
|
|
|
&& (character_compare_array (string [offset + begin], syntax_end [select]) == TRUE)) { // If next character, after the string is in 'syntax_end'. |
|
|
break; |
|
|
break; |
|
|
} |
|
|
|
|
|
|
|
|
} // Otherwise, we implcitly continue the loop. |
|
|
} |
|
|
} |
|
|
} else { // Else, we compare any character. |
|
|
|
|
|
if (character_compare_array (string [offset], syntax_begin [select]) == TRUE) { // With our obviously named function... |
|
|
|
|
|
break; // We found it, exit the loop! |
|
|
|
|
|
} // If we didn't, just continue. |
|
|
|
|
|
|
|
|
} else { // Else, we compare any character. |
|
|
|
|
|
if (character_compare_array (string [offset], syntax_begin [select]) == TRUE) { // With our obviously named function... |
|
|
|
|
|
break; // We found it, exit the loop! |
|
|
|
|
|
} // If we didn't, just continue. |
|
|
} |
|
|
} |
|
|
} // And now we have our 'select' value. |
|
|
|
|
|
|
|
|
} // And now we have our 'select' value. |
|
|
|
|
|
|
|
|
// If there was no syntax rule detected, we need to return from a function, and increment the offset by setting variable 'length' to 1. If we don't increment it, at the |
|
|
// If there was no syntax rule detected, we need to return from a function, and increment the offset by setting variable 'length' to 1. If we don't increment it, at the |
|
|
// first unrecognized character, our second nested-loop inside function 'syntax_render_file' would use uninitialized or zero value, depending on how we structured our code |
|
|
// first unrecognized character, our second nested-loop inside function 'syntax_render_file' would use uninitialized or zero value, depending on how we structured our code |
|
|
// before that. We also return 'syntax_count' as the syntax rule index, which is invalid, and would produce Valgrind warning if we didn't handle it. In my unimportant |
|
|
// before that. We also return 'syntax_count' as the syntax rule index, which is invalid, and would produce Valgrind warning if we didn't handle it. In my unimportant |
|
|
// opinion, this if statement is the ugliest part of the function. |
|
|
// opinion, this if statement is the ugliest part of the function. |
|
|
if (select >= syntax_count) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (select >= syntax_count) { // If we didn't found our string, return. |
|
|
* length = 1; |
|
|
* length = 1; |
|
|
return (syntax_count); |
|
|
return (syntax_count); |
|
|
} |
|
|
} |
|
@@ -203,30 +207,33 @@ int syntax_select (char * string, int * length) { |
|
|
// to again, separate two cases for matching any character or full string, except that we use it to determine its' match-length. Important difference is also that there's |
|
|
// to again, separate two cases for matching any character or full string, except that we use it to determine its' match-length. Important difference is also that there's |
|
|
// special case where we have escape character matching, and where 'syntax_end' string is empty (but not NULL), so in that case we match only one character. We could have |
|
|
// special case where we have escape character matching, and where 'syntax_end' string is empty (but not NULL), so in that case we match only one character. We could have |
|
|
// nested loop there, and second loop would need goto statement to exit it, so we only use one loop. |
|
|
// nested loop there, and second loop would need goto statement to exit it, so we only use one loop. |
|
|
for (offset = 1; string [offset - 1] != '\0'; ++offset) { // Now, offset must be 1, and we loop... |
|
|
|
|
|
if (string [offset] == syntax_escape [select]) { // Here's our escape exception. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (offset = 1; string [offset - 1] != '\0'; ++offset) { // Now, offset must be 1, and we loop... |
|
|
|
|
|
int end = string_length (syntax_end [select]); |
|
|
|
|
|
|
|
|
|
|
|
if (string [offset] == syntax_escape [select]) { // Here's our escape exception. |
|
|
++offset; |
|
|
++offset; |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (syntax_derange [select] == FALSE) { // Choosing what to compare, yet again... |
|
|
|
|
|
if (string_compare_limit (& string [offset], syntax_end [select], string_length (syntax_end [select])) == TRUE) { // Again, we're comparing full string. |
|
|
|
|
|
* length = offset + string_length (syntax_end [select]); // We found it, yaay! |
|
|
|
|
|
|
|
|
if (syntax_derange [select] == FALSE) { // Choosing what to compare, yet again... |
|
|
|
|
|
if (string_compare_limit (& string [offset], syntax_end [select], end) == TRUE) { // Again, we're comparing full string. |
|
|
|
|
|
* length = offset + end; // We found it, yaay! |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
if (syntax_end [select] [0] == CHARACTER_NULL) { // And here's our empty string exception. |
|
|
|
|
|
* length = offset; |
|
|
|
|
|
|
|
|
if (syntax_end [select] [0] == CHARACTER_NULL) { // And here's our empty string exception. |
|
|
|
|
|
* length = offset; // On that case, we break from loop. |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
if (character_compare_array (string [offset], syntax_end [select]) == TRUE) { |
|
|
|
|
|
|
|
|
if (character_compare_array (string [offset], syntax_end [select]) == TRUE) { // Otherwise, we compare to see if the end is near! |
|
|
* length = offset; |
|
|
* length = offset; |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} // These two loops look similar, but no! |
|
|
|
|
|
} // And now we have our 'length' value. |
|
|
|
|
|
|
|
|
} // These two loops look similar, but no! |
|
|
|
|
|
} // And now we have our 'length' value. |
|
|
|
|
|
|
|
|
return (select); // Lastly, return syntax rule index. |
|
|
|
|
|
|
|
|
return (select); // Lastly, return syntax rule index. |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
@@ -253,12 +260,12 @@ void syntax_highlight_c (void) { |
|
|
|
|
|
|
|
|
int word; |
|
|
int word; |
|
|
|
|
|
|
|
|
if (syntax_count != 0) { |
|
|
|
|
|
syntax_delete (); |
|
|
|
|
|
|
|
|
if (syntax_count != 0) { // If syntax was used, free it, then we can redefine them. |
|
|
|
|
|
syntax_delete (); // This way, we won't mix syntaces if we use this multiple times. |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
syntax_define (FALSE, FALSE, "/*", "*/", '\0', COLOUR_GREY, EFFECT_BOLD); // Below, we're simply using our 'syntax_define' function. |
|
|
|
|
|
syntax_define (FALSE, FALSE, "//", "\n", '\0', COLOUR_GREY, EFFECT_BOLD); |
|
|
|
|
|
|
|
|
syntax_define (FALSE, FALSE, "/*", "*/", '\0', COLOUR_GREY, EFFECT_BOLD); // Below, we're simply using our 'syntax_define' function. |
|
|
|
|
|
syntax_define (FALSE, FALSE, "//", "\n", '\0', COLOUR_GREY, EFFECT_BOLD); // I really don't think I need to explain those, so... |
|
|
syntax_define (FALSE, FALSE, "#", "\n", '\\', COLOUR_YELLOW, EFFECT_ITALIC); |
|
|
syntax_define (FALSE, FALSE, "#", "\n", '\\', COLOUR_YELLOW, EFFECT_ITALIC); |
|
|
syntax_define (FALSE, FALSE, "'", "'", '\\', COLOUR_PINK, EFFECT_BOLD); |
|
|
syntax_define (FALSE, FALSE, "'", "'", '\\', COLOUR_PINK, EFFECT_BOLD); |
|
|
syntax_define (FALSE, FALSE, "\"", "\"", '\\', COLOUR_PINK, EFFECT_NORMAL); |
|
|
syntax_define (FALSE, FALSE, "\"", "\"", '\\', COLOUR_PINK, EFFECT_NORMAL); |
|
@@ -361,6 +368,7 @@ void syntax_render_file (char * text_file, int x, int y) { |
|
|
// Or, if you find this more intuitive: |
|
|
// Or, if you find this more intuitive: |
|
|
// colour = (select < syntax_count) ? syntax_colour [select] : COLOUR_WHITE; |
|
|
// colour = (select < syntax_count) ? syntax_colour [select] : COLOUR_WHITE; |
|
|
// effect = (select < syntax_count) ? syntax_effect [select] : EFFECT_NORMAL; |
|
|
// effect = (select < syntax_count) ? syntax_effect [select] : EFFECT_NORMAL; |
|
|
|
|
|
|
|
|
if (select >= syntax_count) { // Here, we're handling error value of 'syntax_select'. |
|
|
if (select >= syntax_count) { // Here, we're handling error value of 'syntax_select'. |
|
|
colour = COLOUR_WHITE; |
|
|
colour = COLOUR_WHITE; |
|
|
effect = EFFECT_NORMAL; |
|
|
effect = EFFECT_NORMAL; |
|
|