1271440Sjkim/******************************************************************************
2271440Sjkim *
3271440Sjkim * Module Name: aslascii - ASCII detection and support routines
4271440Sjkim *
5271440Sjkim *****************************************************************************/
6271440Sjkim
7271440Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9271440Sjkim * All rights reserved.
10271440Sjkim *
11271440Sjkim * Redistribution and use in source and binary forms, with or without
12271440Sjkim * modification, are permitted provided that the following conditions
13271440Sjkim * are met:
14271440Sjkim * 1. Redistributions of source code must retain the above copyright
15271440Sjkim *    notice, this list of conditions, and the following disclaimer,
16271440Sjkim *    without modification.
17271440Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18271440Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19271440Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20271440Sjkim *    including a substantially similar Disclaimer requirement for further
21271440Sjkim *    binary redistribution.
22271440Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23271440Sjkim *    of any contributors may be used to endorse or promote products derived
24271440Sjkim *    from this software without specific prior written permission.
25271440Sjkim *
26271440Sjkim * Alternatively, this software may be distributed under the terms of the
27271440Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28271440Sjkim * Software Foundation.
29271440Sjkim *
30271440Sjkim * NO WARRANTY
31271440Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32271440Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33271440Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34271440Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35271440Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36271440Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37271440Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38271440Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39271440Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40271440Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41271440Sjkim * POSSIBILITY OF SUCH DAMAGES.
42271440Sjkim */
43271440Sjkim
44272444Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45306536Sjkim#include <contrib/dev/acpica/include/actables.h>
46272444Sjkim#include <contrib/dev/acpica/include/acapps.h>
47271440Sjkim
48271440Sjkim#define _COMPONENT          ACPI_COMPILER
49271440Sjkim        ACPI_MODULE_NAME    ("aslascii")
50271440Sjkim
51271440Sjkim
52271440Sjkim/* Local prototypes */
53271440Sjkim
54271440Sjkimstatic void
55271440SjkimFlConsumeAnsiComment (
56271440Sjkim    FILE                    *Handle,
57271440Sjkim    ASL_FILE_STATUS         *Status);
58271440Sjkim
59271440Sjkimstatic void
60271440SjkimFlConsumeNewComment (
61271440Sjkim    FILE                    *Handle,
62271440Sjkim    ASL_FILE_STATUS         *Status);
63271440Sjkim
64271440Sjkim
65271440Sjkim/*******************************************************************************
66271440Sjkim *
67306536Sjkim * FUNCTION:    FlIsFileAsciiSource
68271440Sjkim *
69284460Sjkim * PARAMETERS:  Filename            - Full input filename
70271440Sjkim *              DisplayErrors       - TRUE if error messages desired
71271440Sjkim *
72271440Sjkim * RETURN:      Status
73271440Sjkim *
74271440Sjkim * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
75271440Sjkim *              within comments. Note: does not handle nested comments and does
76271440Sjkim *              not handle comment delimiters within string literals. However,
77271440Sjkim *              on the rare chance this happens and an invalid character is
78271440Sjkim *              missed, the parser will catch the error by failing in some
79271440Sjkim *              spectactular manner.
80271440Sjkim *
81271440Sjkim ******************************************************************************/
82271440Sjkim
83271440SjkimACPI_STATUS
84306536SjkimFlIsFileAsciiSource (
85271440Sjkim    char                    *Filename,
86271440Sjkim    BOOLEAN                 DisplayErrors)
87271440Sjkim{
88271440Sjkim    UINT8                   Byte;
89271440Sjkim    ACPI_SIZE               BadBytes = 0;
90271440Sjkim    BOOLEAN                 OpeningComment = FALSE;
91271440Sjkim    ASL_FILE_STATUS         Status;
92284460Sjkim    FILE                    *Handle;
93271440Sjkim
94271440Sjkim
95284460Sjkim    /* Open file in text mode so file offset is always accurate */
96284460Sjkim
97284460Sjkim    Handle = fopen (Filename, "rb");
98306536Sjkim    if (!Handle)
99306536Sjkim    {
100306536Sjkim        perror ("Could not open input file");
101306536Sjkim        return (AE_ERROR);
102306536Sjkim    }
103284460Sjkim
104271440Sjkim    Status.Line = 1;
105271440Sjkim    Status.Offset = 0;
106271440Sjkim
107271440Sjkim    /* Read the entire file */
108271440Sjkim
109271440Sjkim    while (fread (&Byte, 1, 1, Handle) == 1)
110271440Sjkim    {
111271440Sjkim        /* Ignore comment fields (allow non-ascii within) */
112271440Sjkim
113271440Sjkim        if (OpeningComment)
114271440Sjkim        {
115271440Sjkim            /* Check for second comment open delimiter */
116271440Sjkim
117271440Sjkim            if (Byte == '*')
118271440Sjkim            {
119271440Sjkim                FlConsumeAnsiComment (Handle, &Status);
120271440Sjkim            }
121271440Sjkim
122271440Sjkim            if (Byte == '/')
123271440Sjkim            {
124271440Sjkim                FlConsumeNewComment (Handle, &Status);
125271440Sjkim            }
126271440Sjkim
127271440Sjkim            /* Reset */
128271440Sjkim
129271440Sjkim            OpeningComment = FALSE;
130271440Sjkim        }
131271440Sjkim        else if (Byte == '/')
132271440Sjkim        {
133271440Sjkim            OpeningComment = TRUE;
134271440Sjkim        }
135271440Sjkim
136271440Sjkim        /* Check for an ASCII character */
137271440Sjkim
138271440Sjkim        if (!ACPI_IS_ASCII (Byte))
139271440Sjkim        {
140271440Sjkim            if ((BadBytes < 10) && (DisplayErrors))
141271440Sjkim            {
142271440Sjkim                AcpiOsPrintf (
143284460Sjkim                    "Found non-ASCII character in source text: "
144284460Sjkim                    "0x%2.2X in line %u, file offset 0x%2.2X\n",
145271440Sjkim                    Byte, Status.Line, Status.Offset);
146271440Sjkim            }
147284460Sjkim            BadBytes++;
148284460Sjkim        }
149271440Sjkim
150284460Sjkim        /* Ensure character is either printable or a "space" char */
151284460Sjkim
152306536Sjkim        else if (!isprint (Byte) && !isspace (Byte))
153284460Sjkim        {
154284460Sjkim            if ((BadBytes < 10) && (DisplayErrors))
155284460Sjkim            {
156284460Sjkim                AcpiOsPrintf (
157284460Sjkim                    "Found invalid character in source text: "
158284460Sjkim                    "0x%2.2X in line %u, file offset 0x%2.2X\n",
159284460Sjkim                    Byte, Status.Line, Status.Offset);
160284460Sjkim            }
161271440Sjkim            BadBytes++;
162271440Sjkim        }
163271440Sjkim
164284460Sjkim        /* Update line counter as necessary */
165271440Sjkim
166284460Sjkim        if (Byte == 0x0A)
167271440Sjkim        {
168271440Sjkim            Status.Line++;
169271440Sjkim        }
170271440Sjkim
171271440Sjkim        Status.Offset++;
172271440Sjkim    }
173271440Sjkim
174284460Sjkim    fclose (Handle);
175271440Sjkim
176271440Sjkim    /* Were there any non-ASCII characters in the file? */
177271440Sjkim
178271440Sjkim    if (BadBytes)
179271440Sjkim    {
180271440Sjkim        if (DisplayErrors)
181271440Sjkim        {
182271440Sjkim            AcpiOsPrintf (
183284460Sjkim                "Total %u invalid characters found in input source text, "
184284460Sjkim                "could be a binary file\n", BadBytes);
185271440Sjkim            AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
186271440Sjkim        }
187271440Sjkim
188271440Sjkim        return (AE_BAD_CHARACTER);
189271440Sjkim    }
190271440Sjkim
191271440Sjkim    /* File is OK (100% ASCII) */
192271440Sjkim
193271440Sjkim    return (AE_OK);
194271440Sjkim}
195271440Sjkim
196271440Sjkim
197271440Sjkim/*******************************************************************************
198271440Sjkim *
199271440Sjkim * FUNCTION:    FlConsumeAnsiComment
200271440Sjkim *
201271440Sjkim * PARAMETERS:  Handle              - Open input file
202271440Sjkim *              Status              - File current status struct
203271440Sjkim *
204271440Sjkim * RETURN:      Number of lines consumed
205271440Sjkim *
206271440Sjkim * DESCRIPTION: Step over a normal slash-star type comment
207271440Sjkim *
208271440Sjkim ******************************************************************************/
209271440Sjkim
210271440Sjkimstatic void
211271440SjkimFlConsumeAnsiComment (
212271440Sjkim    FILE                    *Handle,
213271440Sjkim    ASL_FILE_STATUS         *Status)
214271440Sjkim{
215271440Sjkim    UINT8                   Byte;
216271440Sjkim    BOOLEAN                 ClosingComment = FALSE;
217271440Sjkim
218271440Sjkim
219271440Sjkim    while (fread (&Byte, 1, 1, Handle) == 1)
220271440Sjkim    {
221271440Sjkim        /* Scan until comment close is found */
222271440Sjkim
223271440Sjkim        if (ClosingComment)
224271440Sjkim        {
225271440Sjkim            if (Byte == '/')
226271440Sjkim            {
227284460Sjkim                Status->Offset++;
228271440Sjkim                return;
229271440Sjkim            }
230271440Sjkim
231271440Sjkim            if (Byte != '*')
232271440Sjkim            {
233271440Sjkim                /* Reset */
234271440Sjkim
235271440Sjkim                ClosingComment = FALSE;
236271440Sjkim            }
237271440Sjkim        }
238271440Sjkim        else if (Byte == '*')
239271440Sjkim        {
240271440Sjkim            ClosingComment = TRUE;
241271440Sjkim        }
242271440Sjkim
243271440Sjkim        /* Maintain line count */
244271440Sjkim
245271440Sjkim        if (Byte == 0x0A)
246271440Sjkim        {
247271440Sjkim            Status->Line++;
248271440Sjkim        }
249271440Sjkim
250271440Sjkim        Status->Offset++;
251271440Sjkim    }
252271440Sjkim}
253271440Sjkim
254271440Sjkim
255271440Sjkim/*******************************************************************************
256271440Sjkim *
257271440Sjkim * FUNCTION:    FlConsumeNewComment
258271440Sjkim *
259271440Sjkim * PARAMETERS:  Handle              - Open input file
260271440Sjkim *              Status              - File current status struct
261271440Sjkim *
262271440Sjkim * RETURN:      Number of lines consumed
263271440Sjkim *
264271440Sjkim * DESCRIPTION: Step over a slash-slash type of comment
265271440Sjkim *
266271440Sjkim ******************************************************************************/
267271440Sjkim
268271440Sjkimstatic void
269271440SjkimFlConsumeNewComment (
270271440Sjkim    FILE                    *Handle,
271271440Sjkim    ASL_FILE_STATUS         *Status)
272271440Sjkim{
273271440Sjkim    UINT8                   Byte;
274271440Sjkim
275271440Sjkim
276271440Sjkim    while (fread (&Byte, 1, 1, Handle) == 1)
277271440Sjkim    {
278271440Sjkim        Status->Offset++;
279271440Sjkim
280271440Sjkim        /* Comment ends at newline */
281271440Sjkim
282271440Sjkim        if (Byte == 0x0A)
283271440Sjkim        {
284271440Sjkim            Status->Line++;
285271440Sjkim            return;
286271440Sjkim        }
287271440Sjkim    }
288271440Sjkim}
289