2
// Copyright ļæ½ 1997 - 2001, Paul C. Gregory
4
// Contact: pgregory@aqsis.com
6
// This library is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public
8
// License as published by the Free Software Foundation; either
9
// version 2 of the License, or (at your option) any later version.
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
// General Public License for more details.
16
// You should have received a copy of the GNU General Public
17
// License along with this library; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
\brief Implements a Renderman Shading Language compiler that generates Aqsis bytecode
23
\author Paul C. Gregory (pgregory@aqsis.com)
24
\author Timothy M. Shead (tshead@k-3d.com)
28
#include "logging_streambufs.h"
35
#ifdef AQSIS_SYSTEM_WIN32
39
#endif //AQSIS_SYSTEM_WIN32
41
#include "libslparse.h"
43
#include "codegenvm.h"
47
#if defined(AQSIS_SYSTEM_WIN32) || defined(AQSIS_SYSTEM_MACOSX)
51
using namespace Aqsis;
53
extern "C" void PreProcess(int argc, char** argv);
55
ArgParse::apstring g_stroutname = "";
58
ArgParse::apstringvec g_defines; // Filled in with strings to pass to the preprocessor
59
ArgParse::apstringvec g_includes; // Filled in with strings to pass to the preprocessor
60
ArgParse::apstringvec g_undefines; // Filled in with strings to pass to the preprocessor
62
bool g_cl_no_color = false;
63
bool g_cl_syslog = false;
65
void version( std::ostream& Stream )
67
#if defined(AQSIS_SYSTEM_WIN32) || defined(AQSIS_SYSTEM_MACOSX)
68
Stream << "aqsl version " << VERSION_STR << std::endl;
70
Stream << "aqsl version " << VERSION << std::endl;
75
char* g_slppDefArgs[] =
84
int g_cslppDefArgs = sizeof( g_slppDefArgs ) / sizeof( g_slppDefArgs[0] );
87
/** Process the sl file from stdin and produce an slx bytestream.
89
int main( int argc, const char** argv )
92
CqCodeGenVM codegen; // Should be a pointer determined by what we want to generate
93
bool error = false; ///! Couldn't compile shader
95
ap.usageHeader( ArgParse::apstring( "Usage: " ) + argv[ 0 ] + " [options] <filename>" );
96
ap.argString( "o", " %s \aspecify output filename", &g_stroutname );
97
ap.argStrings( "i", "%s \aSet path for #include files.", &g_includes );
98
ap.argStrings( "I", "%s \aSet path for #include files.", &g_includes );
99
ap.argStrings( "D", "Sym[=value] \adefine symbol <string> to have value <value> (default 1).", &g_defines );
100
ap.argStrings( "U", "Sym \aUndefine an initial symbol.", &g_undefines );
101
ap.argFlag( "help", "\aprint this help and exit", &g_help );
102
ap.argFlag( "version", "\aprint version information and exit", &g_version );
104
if ( argc > 1 && !ap.parse( argc - 1, argv + 1 ) )
106
std::cerr << ap.errmsg() << std::endl << ap.usagemsg();
112
version( std::cout );
118
std::cout << ap.usagemsg();
122
#ifdef AQSIS_SYSTEM_WIN32
123
std::auto_ptr<std::streambuf> ansi( new Aqsis::ansi_buf(std::cerr) );
125
std::auto_ptr<std::streambuf> reset_level( new Aqsis::reset_level_buf(std::cerr) );
126
std::auto_ptr<std::streambuf> show_timestamps( new Aqsis::timestamp_buf(std::cerr) );
127
std::auto_ptr<std::streambuf> fold_duplicates( new Aqsis::fold_duplicates_buf(std::cerr) );
128
std::auto_ptr<std::streambuf> color_level;
131
std::auto_ptr<std::streambuf> temp_color_level( new Aqsis::color_level_buf(std::cerr) );
132
color_level = temp_color_level;
134
std::auto_ptr<std::streambuf> show_level( new Aqsis::show_level_buf(std::cerr) );
135
std::auto_ptr<std::streambuf> filter_level( new Aqsis::filter_by_level_buf(Aqsis::DEBUG, std::cerr) );
136
#ifdef AQSIS_SYSTEM_POSIX
138
std::auto_ptr<std::streambuf> use_syslog( new Aqsis::syslog_buf(std::cerr) );
139
#endif // AQSIS_SYSTEM_POSIX
141
// Pass the shader file through the slpp preprocessor first to generate a temporary file.
142
if ( ap.leftovers().size() == 0 ) // If no files specified, take input from stdin.
144
//if ( Parse( std::cin, "stdin", std::cerr ) )
145
// codegen.OutputTree( GetParseTree(), g_stroutname );
146
std::cout << ap.usagemsg();
151
const char* _template = "slppXXXXXX";
153
for ( ArgParse::apstringvec::const_iterator e = ap.leftovers().begin(); e != ap.leftovers().end(); e++ )
155
FILE *file = fopen( e->c_str(), "rb" );
159
strcpy( ifile, _template );
161
#ifdef AQSIS_SYSTEM_WIN32
162
tempname = _mktemp( ifile );
164
tempname = mktemp( ifile );
165
#endif //AQSIS_SYSTEM_WIN32
166
if( NULL != tempname )
168
// Build the arguments array for slpp.
169
std::vector<char*> slppArgs;
170
for ( int defArg = 0; defArg != g_cslppDefArgs; defArg++ )
172
char* Arg = new char[strlen(g_slppDefArgs[ defArg ]) + 1];
173
sprintf( Arg, g_slppDefArgs[ defArg ] );
174
slppArgs.push_back(Arg);
177
// Append the -d arguments passed in to forward them to the preprocessor.
178
for ( ArgParse::apstringvec::const_iterator define = g_defines.begin(); define != g_defines.end(); define++ )
180
char* Arg = new char[strlen("-d") + 1];
182
slppArgs.push_back(Arg);
183
Arg = new char[define->size() + 1];
184
strcpy( Arg, define->c_str() );
185
slppArgs.push_back(Arg);
188
// Append the -i arguments passed in to forward them to the preprocessor.
189
for ( ArgParse::apstringvec::const_iterator include = g_includes.begin(); include != g_includes.end(); include++ )
191
char* Arg = new char[strlen("-i") + 1];
193
slppArgs.push_back(Arg);
194
Arg = new char[include->size() + 1];
195
strcpy( Arg, include->c_str() );
196
slppArgs.push_back(Arg);
199
// Append the -u arguments passed in to forward them to the preprocessor.
200
for ( ArgParse::apstringvec::const_iterator undefine = g_undefines.begin(); undefine != g_undefines.end(); undefine++ )
202
char* Arg = new char[strlen("-u") + 1];
204
slppArgs.push_back(Arg);
205
Arg = new char[undefine->size() + 1];
206
strcpy( Arg, undefine->c_str() );
207
slppArgs.push_back(Arg);
210
// Set the output filename.
211
char* Arg = new char[strlen("-o") + 1];
213
slppArgs.push_back(Arg);
214
Arg = new char[strlen(tempname) + 1];
215
strcpy( Arg, tempname );
216
slppArgs.push_back(Arg);
218
// Set the input filename.
219
char* fileArg = new char[e->size() + 1];
220
sprintf( fileArg, e->c_str() );
221
slppArgs.push_back(fileArg);
223
PreProcess(slppArgs.size(),&slppArgs[0]);
225
std::ifstream ppfile( tempname );
226
if ( Parse( ppfile, e->c_str(), std::cerr ) )
227
codegen.OutputTree( GetParseTree(), g_stroutname );
231
// Delete the temporary file.
237
std::cout << "Could not create temporary file for preprocessing." << std::endl;
243
std::cout << "Warning: Cannot open file \"" << *e << "\"" << std::endl;
248
return error ? -1 : 0;