1
0
mirror of https://git.savannah.gnu.org/git/gperf.git synced 2025-12-02 21:19:24 +00:00

Don't assume a huge stack.

This commit is contained in:
Bruno Haible
2002-10-18 11:47:02 +00:00
parent a6fd7cc006
commit 74672acb3e
8 changed files with 177 additions and 72 deletions

View File

@@ -142,11 +142,6 @@ extern Options option;
#endif
#endif
/* Set to 1 if the stack is large enough for holding a text line. */
#ifndef LARGE_STACK
#define LARGE_STACK 1
#endif
#ifdef __OPTIMIZE__
#define INLINE inline

View File

@@ -23,68 +23,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include <stdlib.h>
#include <string.h> /* declares memcpy() */
#include "options.h"
/* Recursively fills up the buffer. */
#define CHUNK_SIZE 4096
/* CHUNKS is the number of chunks (each of size CHUNK_SIZE) which have
already been read and which are temporarily stored on the stack.
This function reads the remainder of the line, allocates a buffer
for the entire line, fills the part beyond &buffer[chunks*CHUNK_SIZE],
and returns &buffer[chunks*CHUNK_SIZE]. */
char *
Read_Line::readln_aux (int chunks)
{
#if LARGE_STACK
char buf[CHUNK_SIZE];
#else
// Note: we don't use new, because that invokes a custom operator new.
char *buf = (char*)malloc(CHUNK_SIZE);
if (buf == NULL)
abort ();
#endif
char *bufptr = buf;
char *ptr;
int c;
while (c = getc (fp), c != EOF && c != '\n') /* fill the current buffer */
{
*bufptr++ = c;
if (bufptr - buf == CHUNK_SIZE)
{
if ((ptr = readln_aux (chunks + 1)) != NULL)
/* prepend remainder to ptr buffer */
{
ptr -= CHUNK_SIZE;
memcpy (ptr, buf, CHUNK_SIZE);
}
goto done;
}
}
if (c == EOF && bufptr == buf && chunks == 0)
ptr = NULL;
else
{
size_t s1 = chunks * CHUNK_SIZE;
size_t s2 = bufptr - buf;
ptr = new char[s1+s2+1];
ptr += s1;
ptr[s2] = '\0';
memcpy (ptr, buf, s2);
}
done:
#if !LARGE_STACK
free (buf);
#endif
return ptr;
}
#ifndef __OPTIMIZE__

View File

@@ -29,11 +29,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#define read_line_h 1
#include <stdio.h>
#include "getline.h"
class Read_Line
{
private:
char *readln_aux (int chunks);
FILE *fp; /* FILE pointer to the input stream. */
public:

View File

@@ -21,8 +21,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
// This needs:
//#include <stdio.h>
//#include "getline.h"
/* Returns the ``next'' line, ignoring comments beginning with '#'. */
/* Returns the "next" line, ignoring comments beginning with '#'. */
INLINE char *
Read_Line::get_line (void)
{
@@ -41,5 +42,16 @@ Read_Line::get_line (void)
return (char *)0;
ungetc (c, stdin);
return readln_aux (0);
char *line = (char *)0;
size_t linesize = 0;
int length = ::get_line (&line, &linesize, fp);
if (length < 0)
{
delete[] line;
return (char *)0;
}
if (length > 0 && line[length - 1] == '\n')
line[length - 1] = '\0';
return line;
}