diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-08-25 11:23:24 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-08-26 10:03:55 +0200 |
commit | 7421802276e737c2da297599121480833db92de9 (patch) | |
tree | cd6cbc5a311c559679c6d3743940a6fb4a6ffc9e /gcc/d/d-lang.cc | |
parent | 1db88844a22f75b13ced224415f645680784d354 (diff) | |
download | gcc-7421802276e737c2da297599121480833db92de9.zip gcc-7421802276e737c2da297599121480833db92de9.tar.gz gcc-7421802276e737c2da297599121480833db92de9.tar.bz2 |
d: Use read() to load contents of stdin into memory.
This would be an improvement over reading one character at a time.
An ICE was discovered when mixing reading from stdin with `-v', this has been
fixed in upstream DMD and backported as well.
Reviewed-on: https://github.com/dlang/dmd/pull/11620
gcc/d/ChangeLog:
* d-lang.cc (d_parse_file): Use read() to load contents from stdin,
allow the front-end to free the memory after parsing.
* dmd/MERGE: Merge upstream dmd 2cc25c219.
Diffstat (limited to 'gcc/d/d-lang.cc')
-rw-r--r-- | gcc/d/d-lang.cc | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index 6183389..c5254a0 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -906,32 +906,43 @@ d_parse_file (void) { if (strcmp (in_fnames[i], "-") == 0) { - /* Handling stdin, generate a unique name for the module. */ - obstack buffer; - gcc_obstack_init (&buffer); - int c; + /* Load the entire contents of stdin into memory. 8 kilobytes should + be a good enough initial size, but double on each iteration. + 16 bytes are added for the final '\n' and 15 bytes of padding. */ + ssize_t size = 8 * 1024; + uchar *buffer = XNEWVEC (uchar, size + 16); + ssize_t len = 0; + ssize_t count; + + while ((count = read (STDIN_FILENO, buffer + len, size - len)) > 0) + { + len += count; + if (len == size) + { + size *= 2; + buffer = XRESIZEVEC (uchar, buffer, size + 16); + } + } + if (count < 0) + { + error (Loc ("stdin", 0, 0), "%s", xstrerror (errno)); + free (buffer); + continue; + } + + /* Handling stdin, generate a unique name for the module. */ Module *m = Module::create (in_fnames[i], Identifier::generateId ("__stdin"), global.params.doDocComments, global.params.doHdrGeneration); modules.push (m); - /* Load the entire contents of stdin into memory. */ - while ((c = getc (stdin)) != EOF) - obstack_1grow (&buffer, c); - - if (!obstack_object_size (&buffer)) - obstack_1grow (&buffer, '\0'); - /* Overwrite the source file for the module, the one created by Module::create would have a forced a `.d' suffix. */ m->srcfile = File::create ("<stdin>"); - m->srcfile->len = obstack_object_size (&buffer); - m->srcfile->buffer = (unsigned char *) obstack_finish (&buffer); - - /* Tell the front-end not to free the buffer after parsing. */ - m->srcfile->ref = 1; + m->srcfile->len = len; + m->srcfile->buffer = buffer; } else { |