1761 lines
26 KiB
C
Executable File
1761 lines
26 KiB
C
Executable File
|
|
#include <math.h>
|
|
|
|
#include <index.h>
|
|
|
|
#include <text.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdarg.h> // va_list
|
|
|
|
#include <ctype.h> // isspace
|
|
|
|
#include <array.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
//#include <regex.h>
|
|
|
|
|
|
|
|
#define ARRAY_SIZE( arr ) ( sizeof( ( arr ) ) / sizeof( ( arr )[0] ) )
|
|
|
|
int text_findArgumentCloseIndex( char * body, int fromKey ) {
|
|
|
|
int depth = 0;
|
|
|
|
int hasStarted = -1;
|
|
|
|
int count = strlen( body );
|
|
|
|
int active = 1;
|
|
|
|
for (int i = fromKey; i < count; ++i)
|
|
{
|
|
|
|
|
|
int character = body[i];
|
|
|
|
if( character == 34 || character == 39 ) {
|
|
|
|
int previousCharacter = body[i-1];
|
|
|
|
if( previousCharacter != 92 ) {
|
|
|
|
if( active == 1 ) {
|
|
|
|
active = 0;
|
|
|
|
} else {
|
|
|
|
active = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// '('
|
|
if ( (int)body[i] == 40 ) {
|
|
|
|
depth++;
|
|
|
|
hasStarted = 1;
|
|
|
|
}
|
|
|
|
if( hasStarted == 1 && depth == 0 && active == 1 ) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
// ')'
|
|
if ( (int)body[i] == 41 ) {
|
|
|
|
depth--;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
void text_validateCurlyBrackets( char * source ) {
|
|
|
|
int depth = 0;
|
|
|
|
for (int j = 0; j < strlen( source ); ++j)
|
|
{
|
|
// '('
|
|
if ( (int)source[j] == 123 ) {
|
|
|
|
depth++;
|
|
|
|
}
|
|
|
|
// ')'
|
|
if ( (int)source[j] == 125 ) {
|
|
|
|
depth--;
|
|
|
|
}
|
|
|
|
if( depth < 0 ) {
|
|
|
|
//int lineNumber = text_countLineBreaks( source, j );
|
|
|
|
printf( ANSI_COLOR_RED "\n\n\n '}' is missing at line number. \n\n\n" ANSI_COLOR_RESET );
|
|
|
|
exit( 0 );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( depth > 0 ) {
|
|
|
|
printf( ANSI_COLOR_RED "\n\n\n\n\n\n '}' is missing. \n\n\n\n\n\n" ANSI_COLOR_RESET );
|
|
|
|
exit( 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// opnieuw
|
|
int text_isValidNumber( char * a )
|
|
{
|
|
|
|
for( int i = 0; i < strlen( a ); i++ )
|
|
{
|
|
//ASCII value of 0 = 48, 9 = 57. So if value is outside of numeric range then fail
|
|
//Checking for negative sign "-" could be added: ASCII value 45.
|
|
if (a[i] < 48 || a[i] > 57){
|
|
|
|
return -1;
|
|
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int text_findNumberOfLineBreaks( char * source ) {
|
|
|
|
int numberOfLineBreaks = 0;
|
|
|
|
for (int i = 0; i < strlen( source ); ++i)
|
|
{
|
|
if( (int)source[i] == 10 ) {
|
|
|
|
numberOfLineBreaks++;
|
|
|
|
}
|
|
}
|
|
|
|
return numberOfLineBreaks;
|
|
|
|
}
|
|
|
|
|
|
char * text_replaceChar( char * text, char needle, char replacement ) {
|
|
|
|
char * copy = text_copy( text );
|
|
|
|
for (int i = 0; i < strlen( text ); ++i)
|
|
{
|
|
if( copy[i] == needle ) {
|
|
|
|
copy[i] = replacement;
|
|
|
|
}
|
|
}
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
int text_findNextLineBreak( char * body, int currentKey ) {
|
|
|
|
int count = strlen( body );
|
|
|
|
for (int i = currentKey; i < count; ++i)
|
|
{
|
|
|
|
if( ( int ) body [ i ] == 10 ) {
|
|
|
|
return i;
|
|
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
// opnieuw
|
|
char * text_removeAllWhiteSpaces( char * str ) {
|
|
|
|
int i, j = 0;
|
|
|
|
for (i = 0; str[i] != '\0'; i++) {
|
|
|
|
if (str[i] != ' ') {
|
|
|
|
str[j++] = str[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
str[j] = '\0';
|
|
|
|
return str;
|
|
}
|
|
|
|
char * text_replace( char * haystack, char * needle, char * replaceWith )
|
|
{
|
|
int count = 0;
|
|
|
|
char * tmp = haystack;
|
|
|
|
int needleLength = strlen( needle );
|
|
|
|
struct array * keys = array_new();
|
|
|
|
while( tmp = strstr( tmp, needle ) ) {
|
|
|
|
int key = (int)( tmp - haystack );
|
|
|
|
array_add( keys, &key );
|
|
|
|
tmp++;
|
|
|
|
++count;
|
|
}
|
|
|
|
|
|
for (int i = count - 1; i >= 0; --i)
|
|
{
|
|
|
|
int currentKey = *( int * ) array_get( keys, i );
|
|
|
|
haystack = text_replaceAt( currentKey, currentKey + needleLength, haystack, replaceWith );
|
|
|
|
}
|
|
|
|
return haystack;
|
|
|
|
}
|
|
|
|
char * text_regexReplaceAll( char * haystack, char * needle, char * needleText, char * replacement ) {
|
|
|
|
|
|
//printf("\nreplace %s %s\n\n", needle, haystack);
|
|
char * text = text_copy( haystack );
|
|
|
|
int needleTextLength = strlen( needleText );
|
|
|
|
int length;
|
|
|
|
int * fromKeys = malloc( 1000 );
|
|
|
|
int * toKeys = malloc( 1000 );
|
|
|
|
int numberOfMatches = 0;
|
|
|
|
char * output = text;
|
|
|
|
int skipToEnd = 0;
|
|
/*
|
|
|
|
|
|
|
|
char * expression = needle;// "\\sclass\\s";
|
|
|
|
regex_t regex;
|
|
|
|
regmatch_t pmatch[1];
|
|
|
|
int offset = 0;
|
|
|
|
int length;
|
|
|
|
int needleTextLength = strlen( needleText );
|
|
|
|
char * output = text;
|
|
|
|
int * fromKeys = malloc( 1000 );
|
|
|
|
int * toKeys = malloc( 1000 );
|
|
|
|
int numberOfMatches = 0;
|
|
|
|
|
|
if ( regcomp( ®ex, expression, REG_NEWLINE ) ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
for ( int i = 0; ; i++ ) {
|
|
|
|
if ( regexec( ®ex, text, ARRAY_SIZE( pmatch ), pmatch, 0 ) ){
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
offset += ( int ) pmatch[0].rm_so;
|
|
|
|
length = needleTextLength;
|
|
|
|
int offsetFrom = offset;
|
|
|
|
offset += length;
|
|
|
|
int offsetTo = offset;
|
|
|
|
fromKeys[numberOfMatches] = offsetFrom;
|
|
|
|
toKeys[numberOfMatches] = offsetTo;
|
|
|
|
offset++;
|
|
|
|
numberOfMatches++;
|
|
|
|
text += ( int ) pmatch[0].rm_so + 1 + length;
|
|
|
|
}
|
|
*/
|
|
|
|
|
|
const char * error;
|
|
unsigned char *name_table;
|
|
unsigned int option_bits;
|
|
int erroffset;
|
|
int crlf_is_newline;
|
|
int ovector[OVECCOUNT];
|
|
int subject_length;
|
|
int rc;
|
|
int utf8;
|
|
|
|
char * subject = ( haystack );
|
|
|
|
subject_length = ( int ) strlen( subject );
|
|
|
|
pcre * re = pcre_compile( needle, /* the needle */
|
|
0, /* default options */
|
|
&error, /* for error message */
|
|
&erroffset, /* for error offset */
|
|
NULL); /* use default character tables */
|
|
|
|
if ( re == NULL )
|
|
{
|
|
|
|
printf( "PCRE compilation failed at offset %d: %s\n", erroffset, error );
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
rc = pcre_exec( re, /* the compiled needle */
|
|
NULL, /* no extra data - we didn't study the needle */
|
|
subject, /* the subject string */
|
|
subject_length, /* the length of the subject */
|
|
0, /* start at offset 0 in the subject */
|
|
0, /* default options */
|
|
ovector, /* output vector for substring information */
|
|
OVECCOUNT ); /* number of elements in the output vector */
|
|
|
|
|
|
if( rc < 0 ) {
|
|
|
|
switch( rc )
|
|
{
|
|
case PCRE_ERROR_NOMATCH:
|
|
|
|
//printf("No match\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("Matching error %d\n", rc);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pcre_free( re ); /* Release memory used for the compiled needle */
|
|
|
|
return output;
|
|
|
|
}
|
|
// printf("\nMatch succeeded at offset %d\n", ovector[0]);
|
|
|
|
//lexer_add( currentLexer, ovector[0], token );
|
|
|
|
if( skipToEnd == 0 ) {
|
|
|
|
int offset = ovector[0];
|
|
|
|
length = needleTextLength;
|
|
|
|
int offsetFrom = offset;
|
|
|
|
offset += length;
|
|
|
|
int offsetTo = offset;
|
|
|
|
fromKeys[numberOfMatches] = offsetFrom;
|
|
|
|
toKeys[numberOfMatches] = offsetTo;
|
|
|
|
offset++;
|
|
|
|
numberOfMatches++;
|
|
|
|
|
|
/* See if CRLF is a valid newline sequence. */
|
|
|
|
crlf_is_newline = option_bits == PCRE_NEWLINE_ANY ||
|
|
option_bits == PCRE_NEWLINE_CRLF ||
|
|
option_bits == PCRE_NEWLINE_ANYCRLF;
|
|
|
|
/* Loop for second and subsequent matches */
|
|
|
|
for (;;)
|
|
{
|
|
int options = 0; /* Normally no options */
|
|
int start_offset = ovector[1]; /* Start at end of previous match */
|
|
|
|
/* If the previous match was for an empty string, we are finished if we are
|
|
at the end of the subject. Otherwise, arrange to run another match at the
|
|
same point to see if a non-empty match can be found. */
|
|
|
|
if (ovector[0] == ovector[1])
|
|
{
|
|
if (ovector[0] == subject_length) break;
|
|
options = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED;
|
|
}
|
|
|
|
/* Run the next matching operation */
|
|
|
|
rc = pcre_exec(
|
|
re, /* the compiled needle */
|
|
NULL, /* no extra data - we didn't study the needle */
|
|
subject, /* the subject string */
|
|
subject_length, /* the length of the subject */
|
|
start_offset, /* starting offset in the subject */
|
|
options, /* options */
|
|
ovector, /* output vector for substring information */
|
|
OVECCOUNT); /* number of elements in the output vector */
|
|
|
|
|
|
if (rc == PCRE_ERROR_NOMATCH)
|
|
{
|
|
if (options == 0)
|
|
break; /* All matches found */
|
|
|
|
ovector[1] = start_offset + 1; /* Advance one byte */
|
|
|
|
if ( crlf_is_newline && /* If CRLF is newline & */
|
|
start_offset < subject_length - 1 && /* we are at CRLF, */
|
|
subject[start_offset] == '\r' &&
|
|
subject[start_offset + 1] == '\n') {
|
|
|
|
ovector[1] += 1; /* Advance by one more. */
|
|
|
|
} else if ( utf8 ) { /* Otherwise, ensure we */
|
|
/* advance a whole UTF-8 */
|
|
while (ovector[1] < subject_length) /* character. */
|
|
{
|
|
if ((subject[ovector[1]] & 0xc0) != 0x80)
|
|
break;
|
|
ovector[1] += 1;
|
|
}
|
|
|
|
}
|
|
|
|
continue; /* Go round the loop again */
|
|
}
|
|
|
|
/* Other matching errors are not recoverable. */
|
|
|
|
if (rc < 0)
|
|
{
|
|
printf("Matching error %d\n", rc);
|
|
|
|
pcre_free(re); /* Release memory used for the compiled needle */
|
|
|
|
return output;
|
|
}
|
|
|
|
/* Match succeeded */
|
|
|
|
//printf("\nMatch succeeded again at offset %d\n", ovector[0]);
|
|
|
|
offset = ovector[0];
|
|
|
|
length = needleTextLength;
|
|
|
|
offsetFrom = offset;
|
|
|
|
offset += length;
|
|
|
|
offsetTo = offset;
|
|
|
|
fromKeys[numberOfMatches] = offsetFrom;
|
|
|
|
toKeys[numberOfMatches] = offsetTo;
|
|
|
|
offset++;
|
|
|
|
numberOfMatches++;
|
|
|
|
|
|
|
|
/* The match succeeded, but the output vector wasn't big enough. */
|
|
}
|
|
|
|
printf( "\n" );
|
|
|
|
pcre_free( re ); /* Release memory used for the compiled needle */
|
|
|
|
}
|
|
|
|
//for (int i = 0; i < numberOfMatches; ++i)
|
|
//{
|
|
|
|
for (int i = numberOfMatches-1; i >= 0; i--)
|
|
{
|
|
int fromKey = fromKeys[i];
|
|
|
|
int toKey = toKeys[i];
|
|
|
|
printf("\n1111 %i %i\n\n", fromKey, toKey);
|
|
|
|
output = text_replaceAt( fromKey, toKey, output, replacement );
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
char * text_replaceAll( char * target, const char * needle, const char * replacement )
|
|
{
|
|
char buffer[1024] = { 0 };
|
|
char *insert_point = &buffer[0];
|
|
const char *tmp = target;
|
|
size_t needle_len = strlen(needle);
|
|
size_t repl_len = strlen(replacement);
|
|
|
|
while (1) {
|
|
const char *p = strstr(tmp, needle);
|
|
|
|
// walked past last occurrence of needle; copy remaining part
|
|
if (p == NULL) {
|
|
strcpy(insert_point, tmp);
|
|
break;
|
|
}
|
|
|
|
// copy part before needle
|
|
memcpy(insert_point, tmp, p - tmp);
|
|
insert_point += p - tmp;
|
|
|
|
// copy replacement string
|
|
memcpy(insert_point, replacement, repl_len);
|
|
insert_point += repl_len;
|
|
|
|
// adjust pointers, move on
|
|
tmp = p + needle_len;
|
|
}
|
|
|
|
// write altered string back to target
|
|
strcpy(target, buffer);
|
|
|
|
return target;
|
|
}
|
|
|
|
/*
|
|
char * text_regexReplaceAll2( char * haystack, char * needle, char * needleText, char * replacement ) {
|
|
|
|
printf("\nreplace %s %s\n\n", needle, haystack);
|
|
|
|
//text_regexReplaceAll2( haystack, needle, needleText, replacement );
|
|
|
|
char * expression = needle;// "\\sclass\\s";
|
|
|
|
regex_t regex;
|
|
|
|
regmatch_t pmatch[1];
|
|
|
|
int offset = 0;
|
|
|
|
int length;
|
|
|
|
int needleTextLength = strlen( needleText );
|
|
|
|
char * text = haystack;
|
|
|
|
char * output = haystack;
|
|
|
|
int * fromKeys = malloc( 1000 );
|
|
|
|
int * toKeys = malloc( 1000 );
|
|
|
|
int numberOfMatches = 0;
|
|
|
|
|
|
if ( regcomp( ®ex, expression, REG_NEWLINE ) ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
for ( int i = 0; ; i++ ) {
|
|
|
|
if ( regexec( ®ex, text, ARRAY_SIZE( pmatch ), pmatch, 0 ) ){
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
offset += ( int ) pmatch[0].rm_so;
|
|
|
|
length = needleTextLength;
|
|
|
|
int offsetFrom = offset;
|
|
|
|
offset += length;
|
|
|
|
int offsetTo = offset;
|
|
|
|
fromKeys[numberOfMatches] = offsetFrom;
|
|
|
|
toKeys[numberOfMatches] = offsetTo;
|
|
|
|
offset++;
|
|
|
|
numberOfMatches++;
|
|
|
|
text += ( int ) pmatch[0].rm_so + 1 + length;
|
|
|
|
}
|
|
|
|
for (int i = 0; i < numberOfMatches; ++i)
|
|
{
|
|
|
|
//for (int i = numberOfMatches-1; i >= 0; i--)
|
|
//{
|
|
int fromKey = fromKeys[i];
|
|
|
|
int toKey = toKeys[i];
|
|
|
|
printf("2222 %i %i\n\n", fromKey, toKey);
|
|
|
|
output = text_replaceAt( fromKey, toKey, output, replacement );
|
|
|
|
}
|
|
|
|
printf("\n\n\n");
|
|
|
|
return output;
|
|
|
|
}
|
|
*/
|
|
char * text_replaceAt( int fromKey, int toKey, char * target, char * source ) {
|
|
|
|
//char * newText = malloc( sizeof( char * ) * 10000 );
|
|
|
|
struct text * newText = text_new("");
|
|
|
|
int length = strlen( target );
|
|
|
|
char * beginText = text_slice( target, 0, fromKey - 1 );
|
|
|
|
char * endText = text_slice( target, toKey, length );
|
|
|
|
text_append( newText, beginText );
|
|
|
|
text_append( newText, source );
|
|
|
|
text_append( newText, endText );
|
|
|
|
return newText->value;
|
|
|
|
}
|
|
|
|
struct text * text_new( char * value ) {
|
|
|
|
text * pointer = malloc( sizeof( struct text ) );
|
|
|
|
pointer->length = strlen( value );
|
|
|
|
pointer->capacity = 256;
|
|
|
|
text_constructor( pointer , value );
|
|
|
|
return pointer;
|
|
|
|
}
|
|
|
|
void text_constructor( struct text * this, char * value ) {
|
|
|
|
if( this->length > this->capacity ) {
|
|
|
|
this->capacity = pow( 2, ceil( log( this->length ) / log( 2 ) ) ) * 2;
|
|
|
|
}
|
|
|
|
this->value = malloc( sizeof( char ) * this->capacity );
|
|
|
|
memcpy( this->value, value, this->length );
|
|
|
|
this->value[ this->length ] = 0;
|
|
|
|
}
|
|
|
|
void text_resize( struct text * this, int size ) {
|
|
|
|
//printf(" ----------- realocate: %i \n", size);
|
|
|
|
char * value = realloc( this->value, sizeof( char ) * size );
|
|
|
|
|
|
this->value = value;
|
|
|
|
this->capacity = size;
|
|
|
|
}
|
|
|
|
|
|
struct text * text_append( struct text * this, const char * value ) {
|
|
|
|
int originalLength = this->length;
|
|
|
|
int sourceLength = strlen( value );
|
|
|
|
this->length += sourceLength;
|
|
|
|
if( this->length + 1 >= this->capacity ) {
|
|
|
|
if( this->length + 1 > this->capacity * 2 ) {
|
|
|
|
this->capacity = pow( 2, ceil( log( this->length ) / log( 2 ) ) );
|
|
|
|
text_resize( this, this->capacity * 2 );
|
|
|
|
} else {
|
|
|
|
text_resize( this, this->capacity * 2 );
|
|
|
|
}
|
|
|
|
//printf("buffer has been resized: capacity %i length %i \n", this->capacity, this->length);
|
|
|
|
}
|
|
|
|
|
|
memcpy( this->value + originalLength, value, sourceLength );
|
|
|
|
this->value[this->length] = 0;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
void text_free( struct text * this ) {
|
|
|
|
free( this->value );
|
|
|
|
}
|
|
|
|
char * text_removeSlashFromStart( char * filePath ) {
|
|
|
|
if( filePath[0] == 47 ) {
|
|
|
|
memmove( filePath, filePath + 1, strlen( filePath ) );
|
|
|
|
}
|
|
|
|
return filePath;
|
|
|
|
//filePath[strlen( filePath )] = 0;
|
|
|
|
}
|
|
|
|
struct text * text_appendDebug( struct text * this, const char * value ) {
|
|
|
|
int originalLength = this->length;
|
|
|
|
int newValueLength = strlen( value );
|
|
|
|
this->length += newValueLength;
|
|
|
|
|
|
if( this->length > this->capacity ) {
|
|
|
|
if( this->length > this->capacity * 2 ) {
|
|
|
|
this->capacity = pow( 2, ceil( log( newValueLength ) / log( 2 ) ) );
|
|
|
|
text_resize( this, this->capacity * 2 );
|
|
|
|
} else {
|
|
|
|
text_resize( this, this->capacity * 2 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printf("debug append: this->value '%s' originalLength: '%i' target: '%s' newValueLength: '%i' \n\n\n\n\n", this->value, originalLength, value, newValueLength );
|
|
|
|
memmove( this->value + originalLength, value, newValueLength );
|
|
|
|
//this->value[this->length] = 0;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
int text_exists( char * phrase, char * word ) {
|
|
|
|
if ( strstr( phrase, word ) != NULL ) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
char * text_fromNumber( int number ) {
|
|
|
|
char * textNumber = malloc(sizeof(char)*20);
|
|
|
|
sprintf(textNumber, "%d", number);
|
|
|
|
return textNumber;
|
|
|
|
}
|
|
|
|
int text_findPreviousLineBreak( char * body, int currentKey ){
|
|
|
|
for (int i = currentKey; i >= 0; --i)
|
|
{
|
|
if( ( int ) body [ i ] == 10 ) {
|
|
|
|
return i;
|
|
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char * text_concatenate( char * a, char * b ) {
|
|
|
|
int lengthA = strlen( a );
|
|
|
|
int lengthB = strlen( b );
|
|
|
|
char * pointer = a;
|
|
|
|
char * copy = ( char * ) malloc( ( lengthA + lengthB + 1 ) * sizeof( char ) );
|
|
|
|
int idx = 0;
|
|
|
|
while ( * pointer != '\0' ){
|
|
|
|
copy[idx++] = *pointer++;
|
|
|
|
}
|
|
|
|
pointer = &b[0];
|
|
|
|
while (*pointer != '\0'){
|
|
|
|
copy[idx++] = *pointer++;
|
|
|
|
}
|
|
|
|
copy[idx++] = '\0';
|
|
|
|
return ©[0];
|
|
|
|
}
|
|
|
|
|
|
int text_findQuoteCloseIndex( char * body, int fromKey ) {
|
|
|
|
int hasStarted = -1;
|
|
|
|
int count = strlen( body );
|
|
|
|
int active = 1;
|
|
|
|
for (int i = fromKey; i < count; ++i)
|
|
{
|
|
|
|
|
|
int character = body[i];
|
|
|
|
if( character == 34 || character == 39 ) {
|
|
|
|
hasStarted = 1;
|
|
|
|
int previousCharacter = body[i-1];
|
|
|
|
if( previousCharacter != 92 ) {
|
|
|
|
if( active == 1 ) {
|
|
|
|
active = 0;
|
|
|
|
} else {
|
|
|
|
active = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( hasStarted == 1 && active == 1 ) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
int text_seekParenthesesLeftToRight( char * body, int currentKey ) {
|
|
|
|
int count = strlen( body );
|
|
|
|
for (int i = currentKey; i < count; ++i)
|
|
{
|
|
|
|
if( body[ i ] > 65 || body[ i ] == 34 ) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
int text_findFirstNextCharacterNotWhiteSpace( char * body, int fromKey ) {
|
|
|
|
|
|
|
|
int depth = 0;
|
|
|
|
int count = strlen( body );
|
|
|
|
for (int i = fromKey; i < count; ++i)
|
|
{
|
|
|
|
if( !isspace( body[i] ) ) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
int text_findFirstNextCharacterNotWhiteSpaceNotParenthesis( char * body, int fromKey ) {
|
|
|
|
int depth = 0;
|
|
|
|
int count = strlen( body );
|
|
|
|
for (int i = fromKey; i < count; ++i)
|
|
{
|
|
|
|
int character = body[i];
|
|
|
|
if( !isspace( character ) && character != 40 ) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
int text_text_findFirstCharacterIndexbackwards( char * body, int fromKey ) {
|
|
|
|
for (int i = fromKey; i >= 0; --i)
|
|
{
|
|
|
|
if( !isspace( body[i] ) ) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
int text_findFirstCharacterReverse( char * body, int fromKey ) {
|
|
|
|
int depth = 0;
|
|
|
|
int hasStarted = -1;
|
|
|
|
for (int i = fromKey; i >= 0; --i)
|
|
{
|
|
// ')'
|
|
if( !isspace( body[i] ) ) {
|
|
|
|
return body[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char * text_reverse( char * str ) {
|
|
char tmp, *src, *dst;
|
|
int len;
|
|
if (str != NULL)
|
|
{
|
|
len = strlen (str);
|
|
if (len > 1) {
|
|
src = str;
|
|
dst = src + len - 1;
|
|
while (src < dst) {
|
|
tmp = *src;
|
|
*src++ = *dst;
|
|
*dst-- = tmp;
|
|
}
|
|
}
|
|
}
|
|
return str;
|
|
}
|
|
|
|
char * text_copy( char * a ) {
|
|
|
|
char * newCopy = malloc( sizeof( char ) * strlen( a ) + 1 );
|
|
|
|
strcpy( newCopy, a );
|
|
|
|
return newCopy;
|
|
|
|
}
|
|
|
|
char * text_formatLength( char * a, int newLength ) {
|
|
|
|
char copyOfText[newLength];// = text_copy( a );
|
|
|
|
int length = strlen( a );
|
|
|
|
for (int i = 0; i < length; ++i)
|
|
{
|
|
copyOfText[i] = a[i];
|
|
}
|
|
|
|
for (int i = length; i < newLength; ++i)
|
|
{
|
|
copyOfText[i] = ( char ) 46;//32
|
|
}
|
|
|
|
//copyOfText[newLength] = ( char ) 0;
|
|
|
|
return copyOfText;
|
|
|
|
}
|
|
|
|
int text_text_findFirstCharacterIndexFromIndex( char * text, char * character, int fromIndex ) {
|
|
|
|
int firstKeyIsHit = -1;
|
|
|
|
int characterInteger = (int)character[0];
|
|
|
|
for (int i = fromIndex; i < strlen(text); ++i)
|
|
{
|
|
|
|
int charNumber = ( int ) text[i];
|
|
|
|
if( firstKeyIsHit == 1 ) {
|
|
|
|
if( (int)text[i] == characterInteger ) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if( charNumber > 47 ) {
|
|
|
|
firstKeyIsHit = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
int text_getIndexBeforeWord( char * body, int currentKey ) {
|
|
|
|
int firstKeyIsHit = -1;
|
|
|
|
int notWithinQuotes = 1;
|
|
|
|
for (int i = 1; i < 30; ++i)
|
|
{
|
|
int charNumber = (int)body[currentKey-i];
|
|
|
|
if( charNumber == 34 || charNumber == 39 ) {
|
|
|
|
int previousCharacter = body[i-1];
|
|
|
|
if( previousCharacter != 92 ) {
|
|
|
|
if( notWithinQuotes == 1 ) {
|
|
|
|
notWithinQuotes = 0;
|
|
|
|
} else {
|
|
|
|
notWithinQuotes = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if( firstKeyIsHit == 1 ) {
|
|
|
|
if( charNumber < 48 && charNumber != 60 && charNumber != 62 && notWithinQuotes ) {
|
|
|
|
return currentKey - i + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if( charNumber > 48 && charNumber != 60 && charNumber != 62 ) {
|
|
|
|
firstKeyIsHit = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
int text_indexOff( char * source, char * token, int fromIndex ) {
|
|
|
|
char * found;//= strstr( source, token );
|
|
|
|
if( fromIndex < 1) {
|
|
|
|
found = strstr( source, token );
|
|
|
|
} else {
|
|
|
|
found = strstr( source + fromIndex, token );
|
|
|
|
}
|
|
|
|
|
|
if (found != NULL)
|
|
{
|
|
|
|
return found - source;
|
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int text_findFirstCharacterIndex( char * text, char * character ) {
|
|
|
|
//char * e = strchr( text, character );
|
|
|
|
//int index = (int)(e - text);
|
|
|
|
return strcspn( text, character );
|
|
|
|
}
|
|
|
|
char * text_join( struct array * arrayInstance, char * separator ) {
|
|
|
|
int argumentCount = array_length( arrayInstance );
|
|
|
|
int totalCount = 0;
|
|
|
|
for (int j = 0; j < argumentCount; ++j)
|
|
{
|
|
char * argumentText = array_get( arrayInstance, j );
|
|
|
|
if( j != 0 ) {
|
|
|
|
totalCount++;
|
|
|
|
}
|
|
|
|
int currentCount = strlen( argumentText );
|
|
|
|
totalCount += currentCount;
|
|
|
|
//printf("totalCount: %i\n", totalCount);
|
|
|
|
}
|
|
|
|
char * output = ( char * ) malloc( totalCount );
|
|
|
|
totalCount = 0;
|
|
|
|
for (int j = 0; j < argumentCount; ++j)
|
|
{
|
|
char * argumentText = array_get( arrayInstance, j );
|
|
|
|
if( j != 0 ) {
|
|
|
|
//strcat( output, separator );
|
|
|
|
memcpy( output + totalCount, separator, 1 );
|
|
|
|
totalCount++;
|
|
|
|
}
|
|
|
|
//printf("?? %s\n", argumentText);
|
|
|
|
//strcat( output, text_copy( argumentText ) );
|
|
|
|
char * copy = text_copy(argumentText);
|
|
|
|
int currentCount = strlen( copy );
|
|
|
|
|
|
|
|
//printf("memcpy, %i, %s, %i", totalCount, copy, currentCount);
|
|
|
|
memcpy( output + totalCount, copy, currentCount );
|
|
|
|
totalCount += currentCount;
|
|
|
|
|
|
}
|
|
|
|
output[totalCount] = '\0';
|
|
|
|
//printf("concat %s\n", output);
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
int text_countLineBreaks( char * text, int toIndex ) {
|
|
|
|
int lineBreakCount = 0;
|
|
|
|
if( toIndex == -1 ) {
|
|
|
|
toIndex = strlen( text );
|
|
|
|
}
|
|
|
|
for (int j = 0; j < toIndex; ++j)
|
|
{
|
|
|
|
char currentCharacter = text[j];
|
|
|
|
if( ( int ) currentCharacter == 10 ) {
|
|
|
|
lineBreakCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return lineBreakCount;
|
|
|
|
}
|
|
|
|
|
|
struct array * text_splitArguments( char * argumentsText ) {
|
|
|
|
int count = strlen( argumentsText );
|
|
|
|
int active = 1;
|
|
|
|
int previousCharacterIndex = 0;
|
|
|
|
struct array * keys = array_new();
|
|
|
|
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
int character = argumentsText[i];
|
|
|
|
if( character == 34 || character == 39 ) {
|
|
|
|
int previousCharacter = argumentsText[i-1];
|
|
|
|
if( previousCharacter != 92 ) {
|
|
|
|
if( active == 1 ) {
|
|
|
|
active = 0;
|
|
|
|
} else {
|
|
|
|
active = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( active == 1 ) {
|
|
|
|
if( character == 44 ) {
|
|
|
|
//printf("%i\n", i);
|
|
|
|
//indices[index++] = i;
|
|
|
|
int wordLength = i - previousCharacterIndex;
|
|
|
|
char * word = malloc( wordLength + 1 );
|
|
|
|
memcpy( word, argumentsText + previousCharacterIndex, wordLength );
|
|
|
|
//printf(" %i %s\n", i, word);
|
|
|
|
array_add( keys, word );
|
|
|
|
previousCharacterIndex = i + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( previousCharacterIndex != 0 ) {
|
|
|
|
int wordLength = count - previousCharacterIndex;
|
|
|
|
char * word = malloc( wordLength + 1 );
|
|
|
|
memcpy( word, argumentsText + previousCharacterIndex, wordLength );
|
|
|
|
array_add( keys, word );
|
|
|
|
} else {
|
|
|
|
int hasOneArgument = -1;
|
|
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
|
|
char character = argumentsText[i];
|
|
|
|
if( !isspace( character ) ) {
|
|
|
|
hasOneArgument = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( hasOneArgument == 1 ) {
|
|
|
|
array_add( keys, argumentsText );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return keys;
|
|
|
|
}
|
|
/*
|
|
struct array * text_split( char * text, char * separator ) {
|
|
|
|
char * token;
|
|
|
|
token = strtok( text, separator );
|
|
|
|
struct array * parts = array_new();
|
|
|
|
|
|
while( token != NULL ) {
|
|
|
|
if( token ) {
|
|
|
|
array_add( parts, token );
|
|
|
|
}
|
|
|
|
token = strtok( NULL, separator );
|
|
|
|
}
|
|
|
|
return parts;
|
|
|
|
}
|
|
*/
|
|
struct array * text_split( char * haystack, char * needle )
|
|
{
|
|
struct array * keys = array_new();
|
|
|
|
char * haystackCopy = text_copy( haystack );
|
|
|
|
char * token = strtok( haystackCopy, needle);
|
|
|
|
int i = 0;
|
|
|
|
while( token ) {
|
|
|
|
array_add( keys, token );
|
|
|
|
token = ( char * ) strtok( NULL, needle );
|
|
|
|
}
|
|
|
|
return keys;
|
|
|
|
}
|
|
|
|
char * text_extractWordBeforeKey( char * body, int currentKey ) {
|
|
|
|
char * invertedName = malloc( sizeof( char * ) * 30 );
|
|
|
|
int firstKeyIsHit = -1;
|
|
|
|
for (int i = 1; i < 30; ++i)
|
|
{
|
|
int charNumber = (int)body[currentKey-i];
|
|
|
|
if( firstKeyIsHit == 1 ) {
|
|
|
|
if( charNumber < 47 ) {
|
|
|
|
invertedName[i-1] = '\0';
|
|
|
|
|
|
i = 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if( charNumber > 47 ) {
|
|
|
|
firstKeyIsHit = 1;
|
|
|
|
invertedName[i-1] = (char)body[currentKey-i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return text_reverse( text_removeWhiteSpaces( invertedName ) );
|
|
|
|
}
|
|
|
|
char * text_removeSpaces( char * s ) {
|
|
|
|
char* d = s;
|
|
|
|
do {
|
|
|
|
while (*d == ' ') {
|
|
|
|
++d;
|
|
|
|
}
|
|
|
|
} while (*s++ = *d++);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
int text_extractIndexAtWhiteSpace( char * body, int currentKey ) {
|
|
|
|
int firstKeyIsHit = -1;
|
|
|
|
for (int i = 1; i < 60; ++i)
|
|
{
|
|
int charNumber = ( int ) body[currentKey+i];
|
|
|
|
if( firstKeyIsHit == 1 ) {
|
|
|
|
if( charNumber < 47 || charNumber == 59 ) {
|
|
|
|
return i + currentKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if( body[currentKey+i] > 47 ) {
|
|
|
|
firstKeyIsHit = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
int text_extractIndexAfterWord( char * body, int currentKey ) {
|
|
|
|
int firstKeyIsHit = -1;
|
|
|
|
for (int i = 1; i < 60; ++i)
|
|
{
|
|
int charNumber = ( int ) body[currentKey+i];
|
|
|
|
if( firstKeyIsHit == 1 ) {
|
|
|
|
if( charNumber < 47 ) {
|
|
|
|
return i + currentKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if( charNumber > 47 ) {
|
|
|
|
firstKeyIsHit = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
char * text_extractWordAfterKey( char * body, int currentKey ) {
|
|
|
|
return "";
|
|
/*
|
|
char * invertedName = malloc( sizeof( char * ) * 30 );
|
|
|
|
int firstKeyIsHit = -1;
|
|
|
|
for (int i = 1; i < 30; ++i)
|
|
{
|
|
int charNumber = (int)body[currentKey-i];
|
|
|
|
if( firstKeyIsHit == 1 ) {
|
|
|
|
if( charNumber < 47 ) {
|
|
|
|
invertedName[i-1] = '\0';
|
|
|
|
|
|
i = 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if( charNumber > 47 ) {
|
|
|
|
firstKeyIsHit = 1;
|
|
|
|
invertedName[i-1] = (char)body[currentKey-i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return text_reverse(text_removeWhiteSpaces( invertedName ) );;
|
|
*/
|
|
}
|
|
|
|
char * text_concatenateMultiple(int count, ...)
|
|
{
|
|
va_list ap;
|
|
int i;
|
|
|
|
// Find required length to store merged string
|
|
int len = 1; // room for NULL
|
|
va_start(ap, count);
|
|
for(i=0 ; i<count ; i++)
|
|
len += strlen(va_arg(ap, char*));
|
|
va_end(ap);
|
|
|
|
// Allocate memory to concat strings
|
|
char *merged = calloc(sizeof(char),len);
|
|
int null_pos = 0;
|
|
|
|
// Actually concatenate strings
|
|
va_start(ap, count);
|
|
for(i=0 ; i<count ; i++)
|
|
{
|
|
char *s = va_arg(ap, char*);
|
|
strcpy(merged+null_pos, s);
|
|
null_pos += strlen(s);
|
|
}
|
|
va_end(ap);
|
|
|
|
return merged;
|
|
}
|
|
|
|
char * text_slice( char * str, int start, int end )
|
|
{
|
|
|
|
const int len = strlen(str);
|
|
|
|
char * buffer = malloc(sizeof( char ) * len);
|
|
|
|
int j = 0;
|
|
|
|
for ( int i = start; i <= end; ++i ) {
|
|
|
|
buffer[j++] = str[i];
|
|
|
|
}
|
|
|
|
buffer[j] = 0;
|
|
|
|
return buffer;
|
|
}
|
|
|
|
|
|
char * text_removeWhiteSpacesLeft(char *s)
|
|
{
|
|
|
|
while(isspace(*s)) s++;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
bool text_contains( char * s, char * needle ) {
|
|
|
|
if (strstr( s, needle ) != NULL ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
char * text_removeWhiteSpacesRight( char * s )
|
|
{
|
|
//char* back = s + strlen(s);
|
|
int length = strlen( s );
|
|
|
|
int sliceChars = 0;
|
|
|
|
for (int i = 0; i < length; ++i)
|
|
{
|
|
|
|
char currentChar = s[length - 1 - i];
|
|
|
|
sliceChars++;
|
|
|
|
|
|
if( !isspace( currentChar ) ) {
|
|
|
|
s[length - sliceChars + 1] = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
}
|
|
|
|
char * text_removeWhiteSpaces( char * s )
|
|
{
|
|
|
|
return text_removeWhiteSpacesRight( text_removeWhiteSpacesLeft( s ) );
|
|
|
|
} |