From 13c9383b10872525688ef2b4daab090037ea3576 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Tue, 24 Apr 2018 09:25:10 +0200 Subject: Support input files with CR/LF line terminators. --- ChangeLog | 6 ++++++ NEWS | 6 ++++++ src/input.cc | 26 +++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 75a3957..21218d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2018-04-24 Bruno Haible + + Support input files with CR/LF line terminators. + Reported at . + * src/input.cc (Input::read_input): Convert CR/LF sequences to LF. + 2018-01-27 Bruno Haible Rename some files. diff --git a/NEWS b/NEWS index f3abd0e..14deb90 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +New in 3.2: +* The input file may now use Windows line terminators (CR/LF) instead of + Unix line terminators (LF). + Note: This is an incompatible change. If you want to use a keyword that + ends in a CR byte, such as xyz, write it as "xyz\r". + New in 3.1: * The generated C code is now in ANSI-C by default. If you want to support pre-ANSI-C compilers, you need to provide the option --language=C on the diff --git a/src/input.cc b/src/input.cc index 67c93b5..fca04e0 100644 --- a/src/input.cc +++ b/src/input.cc @@ -1,5 +1,5 @@ /* Input routines. - Copyright (C) 1989-1998, 2002-2004, 2011 Free Software Foundation, Inc. + Copyright (C) 1989-1998, 2002-2004, 2011, 2017-2018 Free Software Foundation, Inc. Written by Douglas C. Schmidt and Bruno Haible . @@ -263,6 +263,30 @@ Input::read_input () exit (1); } + /* Convert CR/LF line terminators (Windows) to LF line terminators (Unix). + GCC 3.3 and newer support CR/LF line terminators in C sources on Unix, + so we do the same. + The so-called "text mode" in stdio on Windows translates CR/LF to \n + automatically, but here we also need this conversion on Unix. As a side + effect, on Windows we also parse CR/CR/LF into a single \n, but this + is not a problem. */ + { + char *p = input; + char *p_end = input + input_length; + /* Converting the initial segment without CRs is a no-op. */ + while (p < p_end && *p != '\r') + p++; + /* Then start the conversion for real. */ + char *q = p; + while (p < p_end) + { + if (p[0] == '\r' && p + 1 < p_end && p[1] == '\n') + p++; + *q++ = *p++; + } + input_length = q - input; + } + /* We use input_end as a limit, in order to cope with NUL bytes in the input. But note that one trailing NUL byte has been added after input_end, for convenience. */ -- cgit v1.2.1