diff options
author | mongo <mongo@iomega> | 2016-04-15 16:20:17 -0300 |
---|---|---|
committer | mongo <mongo@iomega> | 2016-04-15 16:20:17 -0300 |
commit | f686ba184e0af3fd37aa8a743631a7a376f30843 (patch) | |
tree | e9a48dc691511a2961f93163944ba0ca1a84e5b3 /src/utils | |
parent | c0a088d7a4bc61e6e69fa5bd8964c39f68507c71 (diff) |
Renamed src.scim2 to src
Diffstat (limited to 'src/utils')
-rwxr-xr-x | src/utils/dictionary.c | 160 | ||||
-rwxr-xr-x | src/utils/dictionary.h | 18 | ||||
-rwxr-xr-x | src/utils/extra.c | 47 | ||||
-rwxr-xr-x | src/utils/extra.h | 5 | ||||
-rwxr-xr-x | src/utils/string.c | 337 | ||||
-rwxr-xr-x | src/utils/string.h | 28 |
6 files changed, 595 insertions, 0 deletions
diff --git a/src/utils/dictionary.c b/src/utils/dictionary.c new file mode 100755 index 0000000..d970cb2 --- /dev/null +++ b/src/utils/dictionary.c @@ -0,0 +1,160 @@ +// Dictionary implementation using malloc + +#include <stdlib.h> +#include <string.h> +#include "string.h" +#include "dictionary.h" + +struct dictionary * create_dictionary() { + struct dictionary * d = (struct dictionary *) malloc (sizeof (struct dictionary)); + d->len = 0; + d->list = NULL; + + return d; +} + +void put(struct dictionary * d, char * k, char * v) { + if ( ! strlen (k) || ! strlen(v) ) return; + //if ( ! strlen (k) ) return; + + struct nlist * nl; + + // Insert the first element + if (d->list == NULL) { + nl = (struct nlist *) malloc(sizeof(struct nlist)); + nl->next = NULL; + d->list = nl; + + d->len++; + char * key = (char *) malloc(sizeof(char) * strlen(k)+1); + key[0] = '\0'; + strcpy(key, k); + nl->key = key; + + // Duplicated keys are not allowed. + // If an existent key is inserted, the value is overwritten. + } else if ( get(d, k) != '\0' ) { + nl = get_nl(d, k); + free(nl->val); + + // If the key doesn't exists, Create it. + } else { + nl = (struct nlist *) malloc(sizeof(struct nlist)); + + // Insert at the beginning + if (strcmp(k, d->list->key) < 0) { + nl->next = d->list; + d->list = nl; + // Traverse and insert in the middle or at the end + } else { + struct nlist * nant = d->list; + struct nlist * nact = d->list->next; + while ( nact != NULL && strcmp(k, nact->key) > 0 ) { + nant = nact; + nact = nact->next; + } + nl->next = nact; + nant->next = nl; + } + + d->len++; + char * key = (char *) malloc(sizeof(char) * strlen(k)+1); + key[0] = '\0'; + strcpy(key, k); + nl->key = key; + } + + // Always save the value + char * val = (char *) malloc(sizeof(char) * strlen(v)+1); + val[0] = '\0'; + strcpy(val, v); + nl->val = val; + return; +} + +void destroy_dictionary(struct dictionary * d) { + //if (d == NULL) return; + struct nlist * nl; + struct nlist * n_next; + + nl = d->list; + while (nl != NULL) { + n_next = nl->next; + free(nl->key); + free(nl->val); + free(nl); + nl = n_next; + } + + free(d); + return; +} + +struct nlist * get_nl(struct dictionary * d, char * key) { + int i=0; + struct nlist * nl = d->list; + while ( i++ < d->len && strcmp(key, nl->key) >= 0 ) { + if (strcmp(nl->key, key) == 0) + return nl; + nl = nl->next; + } + return nl; // just in case d->list == NULL +} + +// Get the value for KEY +char * get(struct dictionary * d, char * key) { + int i=0; + if (d == NULL || d->list == NULL) return NULL; + + struct nlist * nl = d->list; + while ( i++ < d->len ) { // && strcmp(key, nl->key) >= 0 ) { + if (strcmp(nl->key, key) == 0) + return nl->val; + nl = nl->next; + } + return NULL; +} + +/* Get the key name from a value +char * get_key_name(struct dictionary * d, char * value) { + int i=0; + if (d == NULL || d->list == NULL) return NULL; + struct nlist * nl = d->list; + while ( i++ < d->len ) { + if (! strcmp(nl->val, value)) + return nl->key; + nl = nl->next; + } + return NULL; +} +*/ + + +// Save key/value pairs in D dictionary from a string STR +void parse_str(struct dictionary * d, char * str) { + char c = str[0]; + char key[30]; + char value[30]; + key[0] = '\0'; + value[0] = '\0'; + + // Create the dictionary + while (c != '\0') { + while (c != '=' && c != '\0') { + add_char(key, c, strlen(key)); + c = *++str; + } + if (c == '\0') break; + c = *++str; + while (c != ' ' && c != '\0') { + add_char(value, c, strlen(value)); + c = *++str; + } + if (c != '\0') c = *++str; + + put(d, key, value); + + key[0] = '\0'; + value[0] = '\0'; + } +} diff --git a/src/utils/dictionary.h b/src/utils/dictionary.h new file mode 100755 index 0000000..fb29621 --- /dev/null +++ b/src/utils/dictionary.h @@ -0,0 +1,18 @@ +struct dictionary { + int len; + struct nlist * list; +}; + +struct nlist { + char * key; + char * val; + struct nlist * next; +}; + +struct dictionary * create_dictionary(); +void put(struct dictionary * d, char * k, char * v); +void destroy_dictionary(struct dictionary * d); +char * get(struct dictionary * d, char * key); +//char * get_key_name(struct dictionary * d, char * value); +struct nlist * get_nl(struct dictionary * d, char * key); +void parse_str(struct dictionary * d, char * str); diff --git a/src/utils/extra.c b/src/utils/extra.c new file mode 100755 index 0000000..17ea057 --- /dev/null +++ b/src/utils/extra.c @@ -0,0 +1,47 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <curses.h> +#include "extra.h" +#include "../sc.h" +#include "../macros.h" +//#include "../range.h" + +extern int find_range(char * name, int len, struct ent * lmatch, struct ent * rmatch, struct range ** rng); + +#define freen(x) nofreeNULL(x) +void nofreeNULL(void *x) { + if (x != NULL) + free(x); + return; +} + +// Returns the ROW/COL cell name +// ex.: D4. +char * v_name(int row, int col) { + struct ent *v; + struct range *r; + static char buf[20]; + + v = lookat(row, col); + if ( ! find_range((char *) 0, 0, v, v, &r) ) { + return (r->r_name); + } else { + (void) sprintf(buf, "%s%d", coltoa(col), row); + return (buf); + } +} + +// Parse BUF_IN to get a cell name. Skip first blocks with IGNORE_FIRST_BLOCKS +char * parse_cell_name(int ignore_first_blocks, struct block * buf_in) { + struct block * b = buf_in; + static char cell_name[3]; //length of max col is 3 (ZZZ) + cell_name[0] = '\0'; + + while (ignore_first_blocks--) b = b->pnext; + while( b != NULL) { + (void) sprintf(cell_name + strlen(cell_name), "%c", b->value); + b = b->pnext; + } + return cell_name; +} diff --git a/src/utils/extra.h b/src/utils/extra.h new file mode 100755 index 0000000..552a23a --- /dev/null +++ b/src/utils/extra.h @@ -0,0 +1,5 @@ +#include "../buffer.h" + +void nofreeNULL(void *x); +char * v_name(int row, int col); // Returns the ROW/COL cell name +char * parse_cell_name(int ignore_first_blocks, struct block * buf_in); // Parse BUF_IN to get a cell name. Skip first blocks with IGNORE_FIRST_BLOCKS diff --git a/src/utils/string.c b/src/utils/string.c new file mode 100755 index 0000000..16eefff --- /dev/null +++ b/src/utils/string.c @@ -0,0 +1,337 @@ +#include <stdlib.h> +#include <string.h> +#include <ctype.h> // for isdigit +#include <wctype.h> // for iswprint +#include <wchar.h> +#include <stdio.h> +#include "string.h" +#include <curses.h> +#include "../sc.h" +#include "../macros.h" + +// Remove POSICION character of a cell (zero based) +// returns 0 on success, -1 otherwise +int del_char(char * str, int posicion) { + int i, slen = strlen(str); + + if ( posicion >= slen || posicion < 0 ) return -1; + for (i = posicion; i < slen - 1; i++) { + str[i] = str[i + 1]; + } + str[--slen] = '\0'; + return 0; +} + +// WIDE CHAR VERSION +// Remove POSICION character of a cell (zero based) +// returns 0 on success, -1 otherwise +int del_wchar(wchar_t * str, int posicion) { + int i, slen = wcslen(str); + + if ( posicion >= slen || posicion < 0 ) return -1; + for (i = posicion; i < slen - 1; i++) { + str[i] = str[i + 1]; + } + str[--slen] = '\0'; + return 0; +} + +// Remove D to H characters range of a cell +// returns 0 on success, -1 otherwise +int del_range_chars(char * str, int d, int h) { + int i = 0, j = 0, slen = strlen(str); + + if ( h >= slen || h < d ) return -1; + + for (j = 0; j <= (h-d); j++) + for (i = d; i < slen - 1; i++) { + str[i] = str[i+1]; + } + str[slen - (h - d) - 1] = '\0'; + return 0; +} + +// WIDE CHAR VERSION +// Remove D to H characters range of a cell +// returns 0 on success, -1 otherwise +int del_range_wchars(wchar_t * str, int d, int h) { + int i = 0, j = 0, slen = wcslen(str); + + if ( h >= slen || h < d ) return -1; + + for (j = 0; j <= (h-d); j++) + for (i = d; i < slen - 1; i++) { + str[i] = str[i+1]; + } + str[slen - (h - d) - 1] = L'\0'; + return 0; +} + +// WIDE CHAR VERSION +// Add a C character to a cell in POSICION +// STR should be previously allocated with enough memory +// returns 0 on success, -1 otherwise +int add_char(char * str, char c, int posicion) { + int slen = strlen(str); + int len = slen - posicion; + if (posicion > slen) return -1; + while (len) { + str[posicion + len] = str[posicion + len -1]; + len--; + } + str[++slen] = '\0'; + str[posicion] = c; + return 0; +} + +// WIDE CHAR VERSION +// Add a C character to a cell in POSICION +// STR should be previously allocated with enough memory +// returns 0 on success, -1 otherwise +int add_wchar(wchar_t * str, wchar_t c, int posicion) { + int slen = wcslen(str); + int len = slen - posicion; + if (posicion > slen) return -1; + while (len) { + str[posicion + len] = str[posicion + len -1]; + len--; + } + str[++slen] = L'\0'; + str[posicion] = c; + return 0; +} + +// Replace all matches FROM character TO character +void subst(char * s, char from, char to) { + while (*s == from) *s++ = to; + return; +} + +// Find string B inside string S +// returns S position in B , -1 otherwise +int str_in_str(char * s, char * b) { + int slen = strlen(s); + int blen = strlen(b); + + if (! slen || ! blen) return -1; + + int e = 0; + int i; + + while ( e <= slen-blen ) { + for (i=0; i<blen; i++) { + if (s[e+i] != b[i]) { + break; + } + } + if (i >= blen) return e; + else e++; + } + return -1; +} + +// WIDE CHAR VERSION +// Find string B inside string S +// returns S position in B , -1 otherwise +int wstr_in_wstr(wchar_t * s, wchar_t * b) { + int slen = wcslen(s); + int blen = wcslen(b); + + if (! slen || ! blen) return -1; + + int e = 0; + int i; + + while ( e <= slen-blen ) { + for (i=0; i<blen; i++) { + if (s[e+i] != b[i]) { + break; + } + } + if (i >= blen) return e; + else e++; + } + return -1; +} + +// Returns 1 if a special or control character is found +int is_idchar (int d) { + switch (d) { + case OKEY_LEFT: + case OKEY_RIGHT: + case OKEY_DOWN: + case OKEY_UP: + case OKEY_TAB: + case OKEY_BS: + case OKEY_HOME: + case OKEY_END: + case OKEY_PGUP: + case OKEY_PGDOWN: + case OKEY_DEL: + //case OKEY_ENTER: + case OKEY_ESC: + return 1; + } + return 0; +} + +char ** split(char *string, const char delimiter, int lastnull) { + int length = 0, count = 0, i = 0, j = 0; + while(*(string++)) { + if (*string == delimiter) count++; + length++; + } + string -= (length + 1); // string was incremented one more than length + char **array = (char **)malloc(sizeof(char *) * (length + 1 + lastnull)); + char ** base = array; + for(i = 0; i < (count + 1); i++) { + j = 0; + while(string[j] != delimiter) j++; + j++; + * array = (char *) malloc(sizeof(char) * j); + memcpy(*array, string, (j-1)); + (*array)[j-1] = '\0'; + string += j; + array++; + } + if (lastnull) { + *array = NULL; + array++; + } + *array = '\0'; + return base; +} + +char * rtrim(char * string, char junk) { + char * original = string + strlen(string); + while(*--original == junk); + *(original + 1) = '\0'; + return string; +} + +char * ltrim(char * string, char junk) { + char * original = string; + char * p = original; + int trimmed = 0; + do { + if (*original != junk || trimmed) { + trimmed = 1; + *p++ = *original; + } + } while (*original++ != '\0'); + return string; +} + +// this function tells is a string represents a numeric value +// returns 1 if that is the case. 0 otherwise +int isnumeric(char * string) { + int i, len = strlen(string); + int res = 1; + for (i=0; i<len; i++) { + if ( string[i] != '.' && string[i] != '-' && ! isdigit(string[i]) ) { + res = 0; + break; + } + } + return res; +} + +// clean \r and \n from a string +// returns 1 if changes were made +int clean_carrier(char * string) { + int i, changes = 0, len = strlen(string); + for (i=0; i<len; i++) { + if ( string[i] == '\r' || string[i] == '\n' ) { + del_char(string, i); + len--; + changes = 1; + } + } + return changes; +} + +/* + * * strtok version that handles null fields + * */ +char * xstrtok(char * line, char * delims) { + static char * saveline = NULL; + char * p; + int n; + + if (line != NULL) + saveline = line; + +/* + * *see if we have reached the end of the line + * */ + if (saveline == NULL || *saveline == '\0') + return(NULL); +/* + * *return the number of characters that aren't delims + * */ + n = strcspn(saveline, delims); + p = saveline; // save start of this token + + saveline += n; // bump past the delim + + if (*saveline != '\0') // trash the delim if necessary + *saveline++ = '\0'; + + return p; +} + +// Count number of occurences of word in s +// Not used +int count_word_occurrences(char * s, char * word, int overlap) { + int c = 0, l = strlen(word); + + while (*s != '\0') { + if (strncmp(s++, word, l)) continue; + if (!overlap) s += l - 1; + c++; + } + return c; +} + +// Search substr word inside string and replace all its occurrences with replacement +// it returns the resulting string +char * str_replace ( const char * string, const char * substr, const char * replacement){ + char * tok = NULL; + char * newstr = NULL; + char * oldstr = NULL; + char * head = NULL; + + /* if either substr or replacement is NULL, duplicate string a let caller handle it */ + if ( substr == NULL || replacement == NULL ) + return strdup (string); + newstr = strdup (string); + head = newstr; + while ( (tok = strstr ( head, substr ))) { + oldstr = newstr; + newstr = malloc ( strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) + 1 ); + /* failed to alloc mem, free old string and return NULL */ + if ( newstr == NULL ){ + free (oldstr); + return NULL; + } + memcpy ( newstr, oldstr, tok - oldstr ); + memcpy ( newstr + (tok - oldstr), replacement, strlen ( replacement ) ); + memcpy ( newstr + (tok - oldstr) + strlen( replacement ), tok + strlen ( substr ), strlen ( oldstr ) - strlen ( substr ) - ( tok - oldstr ) ); + memset ( newstr + strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) , 0, 1 ); + /* move back head right after the last replacement */ + head = newstr + (tok - oldstr) + strlen( replacement ); + free (oldstr); + } + return newstr; +} + +void uppercase(char * sPtr) { + for(; *sPtr != '\0'; ++sPtr) + *sPtr = toupper(*sPtr); +} + +int sc_isprint(int d) { + if ( ((d > 31) && (d < 127)) || ((d > 127) && (d < 255)) || iswprint(d) ) + return 1; + return 0; +} diff --git a/src/utils/string.h b/src/utils/string.h new file mode 100755 index 0000000..10815ad --- /dev/null +++ b/src/utils/string.h @@ -0,0 +1,28 @@ +#include <wchar.h> + +int wcswidth(const wchar_t * s, size_t n); +int wcwidth(const wchar_t wc); + +int del_char(char * str, int posicion); +int del_wchar(wchar_t * str, int posicion); + +int del_range_chars(char * str, int d, int h); +int del_range_wchars(wchar_t * str, int d, int h); + +int add_char(char * str, char c, int posicion); +int add_wchar(wchar_t * str, wchar_t c, int posicion); + +void subst(char * s, char from, char to); +int is_idchar (int d); +int str_in_str(char * s, char * b); +int wstr_in_wstr(wchar_t * s, wchar_t * b); +char ** split(char *string, const char delimiter, int lastnull); +char * ltrim(char *string, char junk); +char * rtrim(char * string, char junk); +int isnumeric(char * string); +int clean_carrier(char * string); +char * xstrtok(char * line, char * delims); +int count_word_occurrences(char * s, char * word, int overlap); +char * str_replace ( const char * string, const char * substr, const char * replacement); +void uppercase(char * sPtr); +int sc_isprint(int d); |