Line-oriented i/o:
scm_gen_read_line scm_read_line scm_fgets scm_generic_fgets
This commit is contained in:
parent
757cfb94f4
commit
3cb988bd00
9 changed files with 166 additions and 2 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ scm_ptobfuns scm_stptob =
|
|||
stwrite,
|
||||
noop0,
|
||||
stgetc,
|
||||
scm_generic_fgets,
|
||||
0
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@ scm_ptobfuns scm_sfptob =
|
|||
sfwrite,
|
||||
sfflush,
|
||||
sfgetc,
|
||||
scm_generic_fgets,
|
||||
sfclose
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue