1/** \file
2 * \brief The ANTLR3 C filestream is used when the source character stream
3 * is a filesystem based input set and all the characters in the filestream
4 * can be loaded at once into memory and away the lexer goes.
5 *
6 * A number of initializers are provided in order that various character
7 * sets can be supported from input files. The ANTLR3 C runtime expects
8 * to deal with UTF32 characters only (the reasons for this are to
9 * do with the simplification of C code when using this form of Unicode
10 * encoding, though this is not a panacea. More information can be
11 * found on this by consulting:
12 *   - http://www.unicode.org/versions/Unicode4.0.0/ch02.pdf#G11178
13 * Where a well grounded discussion of the encoding formats available
14 * may be found.
15 *
16 */
17
18// [The "BSD licence"]
19// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
20// http://www.temporal-wave.com
21// http://www.linkedin.com/in/jimidle
22//
23// All rights reserved.
24//
25// Redistribution and use in source and binary forms, with or without
26// modification, are permitted provided that the following conditions
27// are met:
28// 1. Redistributions of source code must retain the above copyright
29//    notice, this list of conditions and the following disclaimer.
30// 2. Redistributions in binary form must reproduce the above copyright
31//    notice, this list of conditions and the following disclaimer in the
32//    documentation and/or other materials provided with the distribution.
33// 3. The name of the author may not be used to endorse or promote products
34//    derived from this software without specific prior written permission.
35//
36// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
37// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
39// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
40// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
45// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46
47#include    <antlr3.h>
48
49
50/** \brief Use the contents of an operating system file as the input
51 *         for an input stream.
52 *
53 * \param fileName Name of operating system file to read.
54 * \return
55 *	- Pointer to new input stream context upon success
56 *	- One of the ANTLR3_ERR_ defines on error.
57 */
58ANTLR3_API pANTLR3_INPUT_STREAM
59antlr3AsciiFileStreamNew(pANTLR3_UINT8 fileName)
60{
61	// Pointer to the input stream we are going to create
62	//
63	pANTLR3_INPUT_STREAM    input;
64	ANTLR3_UINT32	    status;
65
66	if	(fileName == NULL)
67	{
68		return NULL;
69	}
70
71	// Allocate memory for the input stream structure
72	//
73	input   = (pANTLR3_INPUT_STREAM)
74		ANTLR3_CALLOC(1, sizeof(ANTLR3_INPUT_STREAM));
75
76	if	(input == NULL)
77	{
78		return	NULL;
79	}
80
81	// Structure was allocated correctly, now we can read the file.
82	//
83	status  = antlr3readAscii(input, fileName);
84
85	// Call the common 8 bit ASCII input stream handler
86	// Initializer type thingy doobry function.
87	//
88	antlr3AsciiSetupStream(input, ANTLR3_CHARSTREAM);
89
90	// Now we can set up the file name
91	//
92	input->istream->streamName	= input->strFactory->newStr(input->strFactory, fileName);
93	input->fileName				= input->istream->streamName;
94
95	if	(status != ANTLR3_SUCCESS)
96	{
97		input->close(input);
98		return	NULL;
99	}
100
101	return  input;
102}
103
104ANTLR3_API ANTLR3_UINT32
105antlr3readAscii(pANTLR3_INPUT_STREAM    input, pANTLR3_UINT8 fileName)
106{
107	ANTLR3_FDSC		    infile;
108	ANTLR3_UINT32	    fSize;
109
110	/* Open the OS file in read binary mode
111	*/
112	infile  = antlr3Fopen(fileName, "rb");
113
114	/* Check that it was there
115	*/
116	if	(infile == NULL)
117	{
118		return	(ANTLR3_UINT32)ANTLR3_ERR_NOFILE;
119	}
120
121	/* It was there, so we can read the bytes now
122	*/
123	fSize   = antlr3Fsize(fileName);	/* Size of input file	*/
124
125	/* Allocate buffer for this input set
126	*/
127	input->data	    = ANTLR3_MALLOC((size_t)fSize);
128	input->sizeBuf  = fSize;
129
130	if	(input->data == NULL)
131	{
132		return	(ANTLR3_UINT32)ANTLR3_ERR_NOMEM;
133	}
134
135	input->isAllocated	= ANTLR3_TRUE;
136
137	/* Now we read the file. Characters are not converted to
138	* the internal ANTLR encoding until they are read from the buffer
139	*/
140	antlr3Fread(infile, fSize, input->data);
141
142	/* And close the file handle
143	*/
144	antlr3Fclose(infile);
145
146	return  ANTLR3_SUCCESS;
147}
148
149/** \brief Open an operating system file and return the descriptor
150 * We just use the common open() and related functions here.
151 * Later we might find better ways on systems
152 * such as Windows and OpenVMS for instance. But the idea is to read the
153 * while file at once anyway, so it may be irrelevant.
154 */
155ANTLR3_API ANTLR3_FDSC
156antlr3Fopen(pANTLR3_UINT8 filename, const char * mode)
157{
158    return  (ANTLR3_FDSC)fopen((const char *)filename, mode);
159}
160
161/** \brief Close an operating system file and free any handles
162 *  etc.
163 */
164ANTLR3_API void
165antlr3Fclose(ANTLR3_FDSC fd)
166{
167    fclose(fd);
168}
169ANTLR3_API ANTLR3_UINT32
170antlr3Fsize(pANTLR3_UINT8 fileName)
171{
172    struct _stat	statbuf;
173
174    _stat((const char *)fileName, &statbuf);
175
176    return (ANTLR3_UINT32)statbuf.st_size;
177}
178
179ANTLR3_API ANTLR3_UINT32
180antlr3Fread(ANTLR3_FDSC fdsc, ANTLR3_UINT32 count,  void * data)
181{
182    return  (ANTLR3_UINT32)fread(data, (size_t)count, 1, fdsc);
183}
184