/****************************************************************************
*
* earray : euler's array of command, output and comment strings
*
****************************************************************************/
#include "earray.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#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 ; i<a->len ; 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 ; i<a->len ; 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 ; i<a->len ; 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 && index<a->len)
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 && index<a->len)
return a->data[index].str->str;
return NULL;
}
void e_append_char(earray *a, int index, char c)
{
if (a && index>=0 && index<a->len)
g_string_append_c(a->data[index].str,c);
}
void e_append_text(earray *a, int index, char *text)
{
if (a && index>=0 && index<a->len)
g_string_append(a->data[index].str,text);
}
void e_insert_char(earray *a, int index, int pos, char c)
{
if (a && index>=0 && index<a->len)
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 && index<a->len)
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 && index<a->len)
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;
}
syntax highlighted by Code2HTML, v. 0.9.1