summaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authormongo <mongo@iomega>2016-04-15 16:20:17 -0300
committermongo <mongo@iomega>2016-04-15 16:20:17 -0300
commitf686ba184e0af3fd37aa8a743631a7a376f30843 (patch)
treee9a48dc691511a2961f93163944ba0ca1a84e5b3 /src/utils
parentc0a088d7a4bc61e6e69fa5bd8964c39f68507c71 (diff)
Renamed src.scim2 to src
Diffstat (limited to 'src/utils')
-rwxr-xr-xsrc/utils/dictionary.c160
-rwxr-xr-xsrc/utils/dictionary.h18
-rwxr-xr-xsrc/utils/extra.c47
-rwxr-xr-xsrc/utils/extra.h5
-rwxr-xr-xsrc/utils/string.c337
-rwxr-xr-xsrc/utils/string.h28
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);