/**************************************************************************** * * earray : euler's array of command, output and comment strings * ****************************************************************************/ #include "earray.h" #include #include #include #include #include #define ALLOC_CHUNK 16 #define ALLOC_SIZE(n) (ALLOC_CHUNK*(((n)/ALLOC_CHUNK)+1)) typedef struct estring { GString * str; int type; } estring; struct earray { estring * data; int len; int alloc; }; static int watchforrealloc(earray *a, int n); /*--------------------------------------------------------------------------- * constructor / destructor *---------------------------------------------------------------------------*/ earray * e_new() { earray *a; a = (earray*)malloc(sizeof(earray)); if (a) { a->data = (estring*)malloc(ALLOC_CHUNK*sizeof(estring)); if (a->data) { a->alloc = ALLOC_CHUNK; a->len = 0; return a; } free(a); } return NULL; } void e_free(earray *a) { int i; if (!a) return; for (i=0 ; ilen ; i++) { g_string_free(a->data[i].str,TRUE); } free(a->data); free(a); } int e_load(earray *a, char *filename) { FILE *in; DIR *dir; char line[1024]; int type; if (!a) return 0; /* try to see if it is not a directory (because fopen succeeds even if it is a directory... */ dir = opendir(filename); if (dir) { fprintf(stderr,"It must be a file. I can't open %s !\n",filename); closedir(dir); return 0; } /* load the notebook */ in=fopen(filename,"r"); if (!in) { fprintf(stderr,"Could not open the file %s !\n",filename); return 0; } /* clear the old notebook */ e_clear(a); while (!feof(in)) { int n; if (!fgets(line,1024,in)) break; n=strlen(line); if (n>=2 && line[n-2]=='\r') line[n-2]=0; if (line[n-1]=='\n') line[n-1]=0; switch (line[0]) { case '>':type=E_PROMPT;break; case '$':type=E_UDF;break; case '%':type=E_COMMENT;break; default:type=E_OUTPUT; } e_append(a,line,type); } fclose(in); /* if the notebook file was empty... */ if (!a->len) e_append(a,"",E_OUTPUT); return 1; } int e_save(earray *a, char *filename) { FILE *out; int i; if (!a) return 0; out=fopen(filename,"w"); if (!out) { fprintf(stderr,"Could not save to the file %s !\n",filename); return 0; } for (i=0 ; ilen ; i++) { char ch = a->data[i].str->str[0]; if (a->data[i].type==E_OUTPUT && (ch=='>' || ch=='$' || ch=='%')) fputc(' ',out); fputs(a->data[i].str->str,out); fputc('\n',out); } fclose(out); return 1; } int e_get_length(earray *a) { if (a) return a->len; return 0; } /*--------------------------------------------------------------------------- * add / remove lines to the array *---------------------------------------------------------------------------*/ void e_clear(earray *a) { int i; if (!a) return; for (i=0 ; ilen ; i++) { g_string_free(a->data[i].str,TRUE); } a->len = 0; watchforrealloc(a,0); } int e_append(earray *a, char *text, int type) { if (a) { GString *s = g_string_new(text); if (s) { if (watchforrealloc(a,a->len+1)) { a->data[a->len].str = s; a->data[a->len].type = type; a->len++; return 1; } g_string_free(s,TRUE); } } return 0; } int e_insert(earray *a, int index, char *text, int type) { if (a) { GString *s; if (index>=a->len) return e_append(a,text,type); if (index<0) index=0; s = g_string_new(text); if (s) { if (watchforrealloc(a,a->len+1)) { memmove(&(a->data[index+1]),&(a->data[index]),(a->len-index)*sizeof(estring)); a->data[index].str = s; a->data[index].type = type; a->len++; return 1; } g_string_free(s,TRUE); } } return 0; } void e_remove(earray *a, int index) { if (!a) return; if (index<0 || index>=a->len-1) return; memmove(&(a->data[index]),&(a->data[index+1]),(a->len-index)*sizeof(estring)); a->len--; watchforrealloc(a,a->len); } /*--------------------------------------------------------------------------- * set / get things in specified line in the array *---------------------------------------------------------------------------*/ void e_set_type(earray *a, int index, int type) { if (!a) return; if (index<0 || index>=a->len) return; a->data[index].type = type; } int e_get_type(earray *a, int index) { if (a && index>=0 && indexlen) return a->data[index].type; return 0; } void e_set_text(earray *a, int index, char *text) { if (!a) return; if (index<0 || index>=a->len) return; g_string_assign(a->data[index].str,text); } char * e_get_text(earray *a, int index) { if (a && index>=0 && indexlen) return a->data[index].str->str; return NULL; } void e_append_char(earray *a, int index, char c) { if (a && index>=0 && indexlen) g_string_append_c(a->data[index].str,c); } void e_append_text(earray *a, int index, char *text) { if (a && index>=0 && indexlen) g_string_append(a->data[index].str,text); } void e_insert_char(earray *a, int index, int pos, char c) { if (a && index>=0 && indexlen) g_string_insert_c(a->data[index].str,pos,c); } void e_insert_text(earray *a, int index, int pos, char *text) { if (a && index>=0 && indexlen) g_string_insert(a->data[index].str,pos,text); } void e_remove_text(earray *a, int index, int pos, int len) { if (a && index>=0 && indexlen) g_string_erase(a->data[index].str,pos,len); } int e_get_text_length(earray *a, int index) { return a->data[index].str->len; } /*--------------------------------------------------------------------------- * watch if the array should be resized *---------------------------------------------------------------------------*/ static int watchforrealloc(earray *a, int n) { int alloc = ALLOC_SIZE(n); if (alloc!=a->alloc) { estring *data; data = (estring*)realloc(a->data,alloc*sizeof(estring)); if (data) { a->data = data; a->alloc = alloc; return 1; } return 0; } return 1; }