| Jeroen Demeyer on Sun, 20 Sep 2015 14:44:07 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| Re: Reading a stream from a C string |
Hello, here is a new version, please have a look. Cheers, Jeroen.
commit f37d35d58083e413a62713f2f019f90a4751e58b
Author: Jeroen Demeyer <jdemeyer@cage.ugent.be>
Date: Thu Sep 10 19:35:22 2015 +0200
New function gp_read_str_multiline
diff --git a/src/headers/paridecl.h b/src/headers/paridecl.h
index b17bced..58a98cd 100644
--- a/src/headers/paridecl.h
+++ b/src/headers/paridecl.h
@@ -2459,6 +2459,7 @@ void err_flush(void);
void err_printf(const char* pat, ...);
GEN gp_getenv(const char *s);
GEN gp_read_file(const char *s);
+GEN gp_read_str_multiline(const char *s);
GEN gp_read_stream(FILE *f);
GEN gp_readvec_file(char *s);
GEN gp_readvec_stream(FILE *f);
diff --git a/src/headers/paripriv.h b/src/headers/paripriv.h
index e9526fb..a6548d4 100644
--- a/src/headers/paripriv.h
+++ b/src/headers/paripriv.h
@@ -482,15 +482,17 @@ void gp_expand_path(gp_path *p);
const char *pari_default_path(void);
int path_is_absolute(char *s);
+typedef char *(*fgets_t)(char *, int, void*);
+
typedef struct input_method {
+/* optional */
+ fgets_t fgets; /* like libc fgets() but last argument is (void*) */
/* mandatory */
- char * (*fgets)(char *,int,FILE*);
char * (*getline)(char**, int f, struct input_method*, filtre_t *F);
int free; /* boolean: must we free the output of getline() ? */
-/* for interactive methods */
+/* optional */
const char *prompt, *prompt_cont;
-/* for non-interactive methods */
- FILE *file;
+ void *file; /* can be used as last argument for fgets() */
} input_method;
int input_loop(filtre_t *F, input_method *IM);
diff --git a/src/language/es.c b/src/language/es.c
index 2ac5919..288016f 100644
--- a/src/language/es.c
+++ b/src/language/es.c
@@ -246,9 +246,9 @@ gp_read_stream_buf(FILE *fi, Buffer *b)
init_filtre(&F, b);
- IM.file = fi;
- IM.fgets= &fgets;
- IM.getline= &file_input;
+ IM.file = (void*)fi;
+ IM.fgets = (fgets_t)&fgets;
+ IM.getline = &file_input;
IM.free = 0;
return input_loop(&F,&IM);
}
@@ -261,6 +261,21 @@ gp_read_stream(FILE *fi)
delete_buffer(b); return x;
}
+static GEN
+gp_read_from_input(input_method* IM, int loop)
+{
+ Buffer *b = new_buffer();
+ GEN x = gnil;
+ filtre_t F;
+ do {
+ init_filtre(&F, b);
+ if (!input_loop(&F, IM)) break;
+ if (*(b->buf)) x = readseq(b->buf);
+ } while (loop);
+ delete_buffer(b);
+ return x;
+}
+
GEN
gp_read_file(const char *s)
{
@@ -283,6 +298,41 @@ gp_read_file(const char *s)
popinfile(); return x;
}
+static char*
+string_gets(char *s, int size, const char **ptr)
+{
+ /* f is actually a const char** */
+ const char *in = *ptr;
+ int i;
+ char c;
+
+ /* Copy from in to s */
+ for (i = 0; i+1 < size && in[i] != 0;)
+ {
+ s[i] = c = in[i]; i++;
+ if (c == '\n') break;
+ }
+ s[i] = 0; /* Terminating 0 byte */
+ if (i == 0) return NULL;
+
+ *ptr += i;
+ return s;
+}
+
+GEN
+gp_read_str_multiline(const char *s)
+{
+ input_method IM;
+ const char *ptr = s;
+
+ IM.file = (void*)(&ptr);
+ IM.fgets = (fgets_t)&string_gets;
+ IM.getline = &file_input;
+ IM.free = 0;
+
+ return gp_read_from_input(&IM, 1);
+}
+
GEN
gp_readvec_stream(FILE *fi)
{
@@ -4165,8 +4215,8 @@ get_lines(FILE *F)
GEN z = cgetg(nz + 1, t_VEC);
Buffer *b = new_buffer();
input_method IM;
- IM.fgets = &fgets;
- IM.file = F;
+ IM.fgets = (fgets_t)&fgets;
+ IM.file = (void*)F;
for(i = 1;;)
{
char *s = b->buf, *e;
diff --git a/src/language/gplib.c b/src/language/gplib.c
index c3bdc3e..dac1eff 100644
--- a/src/language/gplib.c
+++ b/src/language/gplib.c
@@ -1122,8 +1122,11 @@ get_line_from_file(const char *prompt, filtre_t *F, FILE *file)
char *s;
input_method IM;
- IM.file = file;
- IM.fgets= (file==stdin && cb_pari_fgets_interactive)? cb_pari_fgets_interactive: &fgets;
+ IM.file = (void*)file;
+ if (file==stdin && cb_pari_fgets_interactive)
+ IM.fgets = (fgets_t)cb_pari_fgets_interactive;
+ else
+ IM.fgets = (fgets_t)&fgets;
IM.getline = &file_input;
IM.free = 0;
if (! input_loop(F,&IM))