Line-oriented i/o:

scm_gen_read_line
scm_read_line
scm_fgets
scm_generic_fgets
This commit is contained in:
Tim Pierce 1997-07-23 21:20:55 +00:00
commit 3cb988bd00
9 changed files with 166 additions and 2 deletions

View file

@ -1,3 +1,17 @@
Wed Jul 23 16:17:46 1997 Tim Pierce <twpierce@bio-5.bsd.uchicago.edu>
Supply an `fgets' method for port objects to do fast line i/o.
* ioext.c (scm_read_line): New function.
* genio.c (scm_gen_read_line): New function.
* fports.c (scm_fgets): New function.
(scm_fptob, scm_pipob): Add scm_fgets method.
* ports.c (fgets_void_port, scm_generic_fgets): New functions.
(void_port_ptob): Add void fgets method.
(scm_newptob): Initialize fgets method from ptob struct.
* ports.h (scm_ptobfuns): Add fgets method.
* vports.c (scm_sfptob): Supply generic fgets method.
* strports.c (scm_stptob): Supply generic fgets method.
Mon Jul 21 04:03:42 1997 Gary Houston <ghouston@actrix.gen.nz>
* ioext.h: removed scm_duplicate_port prototype.

View file

@ -262,6 +262,57 @@ scm_fgetc (s)
return fgetc (s);
}
/*
* The fgets method must take a port as its argument, rather than
* the underlying file handle. The reason is that we also provide
* a generic fgets method for ports which can't use fgets(3) (e.g.
* string ports). This generic method calls the port's own
* fgetc method. In order for it to know how to get that method,
* we must pass the original Scheme port object.
*/
static char * scm_fgets SCM_P ((SCM port));
static char *
scm_fgets (port)
SCM port;
{
FILE *f;
char *buf = NULL;
char *p; /* pointer to current buffer position */
int i = 0; /* index into current buffer position */
int limit = 80; /* current size of buffer */
int lp;
f = SCM_STREAM (port);
if (feof (f))
return NULL;
buf = (char *) scm_must_malloc (limit * sizeof(char), "fgets");
while (1) {
p = buf + i;
if (fgets (p, limit - i, f) == NULL) {
if (i)
return buf;
scm_must_free (buf);
return NULL;
}
if (strlen(p) < limit - i - 1)
return buf;
buf = (char *) scm_must_realloc (buf,
sizeof(char) * limit,
sizeof(char) * limit * 2,
"fgets");
i = limit - 1;
limit *= 2;
}
}
#ifdef vms
static scm_sizet pwrite SCM_P ((char *ptr, scm_sizet size, nitems, FILE *port));
@ -372,6 +423,7 @@ scm_ptobfuns scm_fptob =
(scm_sizet (*) SCM_P ((char *, scm_sizet, scm_sizet, SCM))) local_ffwrite,
(int (*) SCM_P ((SCM))) local_fflush,
(int (*) SCM_P ((SCM))) scm_fgetc,
(char * (*) SCM_P ((SCM))) scm_fgets,
(int (*) SCM_P ((SCM))) local_fclose
};
@ -387,6 +439,7 @@ scm_ptobfuns scm_pipob =
(scm_sizet (*) SCM_P ((char *, scm_sizet, scm_sizet, SCM))) local_ffwrite,
(int (*) SCM_P ((SCM))) local_fflush,
(int (*) SCM_P ((SCM))) scm_fgetc,
(char * (*) SCM_P ((SCM))) scm_fgets,
(int (*) SCM_P ((SCM))) local_pclose
};

View file

@ -507,3 +507,15 @@ scm_gen_ungetc (c, port)
}
char *
scm_gen_read_line (port)
SCM port;
{
char *s;
scm_sizet i;
i = SCM_PTOBNUM (port);
SCM_SYSCALL (s = (scm_ptobs[i].fgets) (port));
return s;
}

View file

@ -55,5 +55,6 @@ extern void scm_gen_puts SCM_P ((enum scm_string_representation_type rep,
extern void scm_gen_write SCM_P ((enum scm_string_representation_type rep, char *str_data, scm_sizet nitems, SCM port));
extern int scm_gen_getc SCM_P ((SCM port));
extern void scm_gen_ungetc SCM_P ((int c, SCM port));
extern char *scm_gen_read_line SCM_P ((SCM port));
#endif /* GENIOH */

View file

@ -138,6 +138,26 @@ scm_read_delimited_x (delims, buf, gobble, port, start, end)
return scm_cons (SCM_BOOL_F, scm_long2num (j - cstart));
}
SCM_PROC (s_read_line, "%read-line", 0, 1, 0, scm_read_line);
SCM
scm_read_line (port)
SCM port;
{
char *s;
if (SCM_UNBNDP (port))
port = scm_cur_inp;
else
{
SCM_ASSERT (SCM_NIMP (port) && SCM_OPINPORTP (port),
port, SCM_ARG1, s_read_line);
}
s = scm_gen_read_line (port);
return (s == NULL ? SCM_EOF_VAL : scm_makfrom0str (s));
}
SCM_PROC (s_write_line, "write-line", 1, 1, 0, scm_write_line);
SCM

View file

@ -114,6 +114,7 @@ scm_newptob (ptob)
scm_ptobs[scm_numptob].fwrite = ptob->fwrite;
scm_ptobs[scm_numptob].fflush = ptob->fflush;
scm_ptobs[scm_numptob].fgetc = ptob->fgetc;
scm_ptobs[scm_numptob].fgets = ptob->fgets;
scm_ptobs[scm_numptob].fclose = ptob->fclose;
scm_numptob++;
}
@ -567,6 +568,61 @@ scm_peek_char (port)
return SCM_MAKICHR (c);
}
/*
* A generic fgets method. We supply this method so that ports which
* can't use fgets(3) (like string ports or soft ports) can still use
* line-based i/o. The generic method calls the port's own fgetc method
* for input. It should be possible to write a more efficient
* method for any given port representation -- this is supplied just
* to ensure that you don't have to.
*/
char * scm_generic_fgets SCM_P ((SCM port));
char *
scm_generic_fgets (port)
SCM port;
{
SCM f = SCM_STREAM (port);
scm_sizet p = SCM_PTOBNUM (port);
char *buf = NULL;
int i = 0; /* index into current buffer position */
int limit = 80; /* current size of buffer */
int c;
if (feof ((FILE *)f))
return NULL;
buf = (char *) scm_must_malloc (limit * sizeof(char), "generic_fgets");
while (1) {
if (i >= limit-1)
{
buf = (char *) scm_must_realloc (buf,
sizeof(char) * limit,
sizeof(char) * limit * 2,
"generic_fgets");
limit *= 2;
}
c = (scm_ptobs[p].fgetc) (f);
if (c != EOF)
buf[i++] = c;
if (c == EOF || c == '\n')
{
if (i)
{
buf[i] = '\0';
return buf;
}
scm_must_free (buf);
return NULL;
}
}
}
SCM_PROC (s_unread_char, "unread-char", 2, 0, 0, scm_unread_char);
SCM
@ -590,8 +646,6 @@ scm_unread_char (cobj, port)
return cobj;
}
SCM_PROC (s_port_line, "port-line", 0, 1, 0, scm_port_line);
SCM
@ -807,6 +861,11 @@ getc_void_port (SCM strm)
return EOF;
}
static char *
fgets_void_port (SCM strm)
{
return NULL;
}
static int
close_void_port (SCM strm)
@ -834,6 +893,7 @@ static struct scm_ptobfuns void_port_ptob =
write_void_port,
flush_void_port,
getc_void_port,
fgets_void_port,
close_void_port,
};

View file

@ -147,6 +147,7 @@ typedef struct scm_ptobfuns
scm_sizet (*fwrite) SCM_P ((char *ptr, scm_sizet size, scm_sizet nitems, SCM stream));
int (*fflush) SCM_P ((SCM stream));
int (*fgetc) SCM_P ((SCM stream));
SCM (*fgets) SCM_P ((SCM stream));
int (*fclose) SCM_P ((SCM stream));
} scm_ptobfuns;
@ -189,6 +190,7 @@ extern SCM scm_flush_all_ports SCM_P ((void));
extern SCM scm_read_char SCM_P ((SCM port));
extern SCM scm_peek_char SCM_P ((SCM port));
extern SCM scm_unread_char SCM_P ((SCM cobj, SCM port));
extern char *scm_generic_fgets SCM_P ((SCM port));
extern SCM scm_port_line SCM_P ((SCM port));
extern SCM scm_port_column SCM_P ((SCM port));
extern SCM scm_port_filename SCM_P ((SCM port));

View file

@ -300,6 +300,7 @@ scm_ptobfuns scm_stptob =
stwrite,
noop0,
stgetc,
scm_generic_fgets,
0
};

View file

@ -214,6 +214,7 @@ scm_ptobfuns scm_sfptob =
sfwrite,
sfflush,
sfgetc,
scm_generic_fgets,
sfclose
};