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:
@@ -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
|
||||
|
||||
@@ -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__
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user