/** * StringLastIndexOf * * Returns the index (character number, not the byte!) of the * needle in the haystack. * * Usage: * 'find the needle' lastIndexOf: 'needle'. #9 */ ctr_object* ctr_string_last_index_of(ctr_object* myself, ctr_argument* argumentList) { ctr_object* sub = ctr_internal_cast2string(argumentList->object); long hlen = myself->value.svalue->vlen; long nlen = sub->value.svalue->vlen; ctr_size uchar_index; ctr_size byte_index; char* p = ctr_internal_memmem(myself->value.svalue->value, hlen, sub->value.svalue->value, nlen, 1); if (p == NULL) return ctr_build_number_from_float((float)-1); byte_index = (ctr_size) ( (uintptr_t) p - (uintptr_t) (myself->value.svalue->value) ); uchar_index = ctr_getutf8len(myself->value.svalue->value, byte_index); return ctr_build_number_from_float((float) uchar_index); }
/** * StringReplaceWith * * Replaces needle with replacement in original string and returns * the result as a new string object. * * Usage: * * 'LiLo BootLoader' replace: 'L' with: 'l'. #lilo Bootloader */ ctr_object* ctr_string_replace_with(ctr_object* myself, ctr_argument* argumentList) { ctr_object* needle = ctr_internal_cast2string(argumentList->object); ctr_object* replacement = ctr_internal_cast2string(argumentList->next->object); char* dest; char* odest; char* src = myself->value.svalue->value; char* ndl = needle->value.svalue->value; char* rpl = replacement->value.svalue->value; long hlen = myself->value.svalue->vlen; long nlen = needle->value.svalue->vlen; long rlen = replacement->value.svalue->vlen; long dlen = hlen; char* p; long i = 0; long offset = 0; long d; dest = (char*) malloc(dlen*sizeof(char)); odest = dest; if (nlen == 0 || hlen == 0) { return ctr_build_string(src, hlen); } while(1) { p = ctr_internal_memmem(src, hlen, ndl, nlen, 0); if (p == NULL) break; d = (dest - odest); if ((dlen - nlen + rlen)>dlen) { dlen = (dlen - nlen + rlen); odest = (char*) realloc(odest, dlen * sizeof(char)); dest = (odest + d); } else { dlen = (dlen - nlen + rlen); } offset = (p - src); memcpy(dest, src, offset); dest = dest + offset; memcpy(dest, rpl, rlen); dest = dest + rlen; hlen = hlen - (offset + nlen); src = src + (offset + nlen); i++; } memcpy(dest, src, hlen); return ctr_build_string(odest, dlen); }
/** * StringSplit * * Converts a string to an array by splitting the string using * the specified delimiter (also a string). */ ctr_object* ctr_string_split(ctr_object* myself, ctr_argument* argumentList) { char* str = myself->value.svalue->value; long len = myself->value.svalue->vlen; ctr_object* delimObject = ctr_internal_cast2string(argumentList->object); char* dstr = delimObject->value.svalue->value; long dlen = delimObject->value.svalue->vlen; ctr_argument* arg; char* elem; ctr_object* arr = ctr_array_new(CtrStdArray, NULL); long i; long j = 0; char* buffer = malloc(sizeof(char)*len); for(i=0; i<len; i++) { buffer[j] = str[i]; j++; if (ctr_internal_memmem(buffer, j, dstr, dlen, 0)!=NULL) { elem = malloc(sizeof(char)*(j-dlen)); memcpy(elem,buffer,j-dlen); arg = malloc(sizeof(ctr_argument)); arg->object = ctr_build_string(elem, j-dlen); ctr_array_push(arr, arg); free(arg); j=0; } } if (j>0) { elem = malloc(sizeof(char)*j); memcpy(elem,buffer,j); arg = malloc(sizeof(ctr_argument)); arg->object = ctr_build_string(elem, j); ctr_array_push(arr, arg); free(arg); } free(buffer); return arr; }
/** * Translates a word in the program using a dictionary and a context flag. * If the word is a keyword message and there is translation available, the remainder * gets filled for the next parts of the message to come. */ int ctr_translate_translate(char* v, ctr_size l, ctr_dict* dictionary, char context, char* remainder) { int found = 0; int i, p, q; ctr_dict* entry; char* buffer; char* warning; entry = dictionary; while( entry ) { ctr_size ml; ml = entry->wordLength; if ( l == entry->wordLength && context == entry->type && strncmp( entry->word, v, ml ) == 0 ) { if (context == 't') { if ((entry->translationLength == 1 && l > 1) || (entry->translationLength > 1 && l== 1)) { buffer = ctr_heap_allocate( 600 ); warning = CTR_TERR_TMISMAT; memcpy(buffer, warning, strlen(warning)); memcpy(buffer + (strlen(warning)), v, l); ctr_print_error( buffer, 1 ); } p = 0; q = 0; for (i = 0; i<entry->wordLength; i++) { if (*(entry->word + i)==':') p++; } for (i = 0; i<entry->translationLength; i++) { if (*(entry->translation + i)==':') q++; } if ( p != q ) { ctr_print_error(CTR_TERR_COLONS, 1); } for (i = 0; i<entry->translationLength; i++) { fwrite(entry->translation + i,1,1,stdout); if (*(entry->translation + i)==':' && entry->translationLength > (i+1)) { if ((entry->translationLength-i)>CTR_TRANSLATE_MAX_WORD_LEN) { ctr_print_error(CTR_TERR_BUFF, 1); } memcpy(remainder,entry->translation+i+1,(entry->translationLength-i-1)); break; } } } else { fwrite(entry->translation, entry->translationLength, 1,stdout); } found = 1; break; } entry = entry->next; } if (context == 't' && !found && ctr_internal_memmem(v,l,":",1,0)>((char*)NULL)) { for (i = 0; i<l; i++) { fwrite(v+i,1,1,stdout); if (*(v + i)==':') { memcpy(remainder,v+i+1,(l-i)); found = 1; break; } } } if (!found) { buffer = ctr_heap_allocate( 600 ); warning = CTR_TERR_WARN; memcpy(buffer, warning, strlen(warning)); memcpy(buffer + (strlen(warning)), v, l); ctr_print_error( buffer, -1 ); ctr_heap_free(buffer); } return found; }