1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
27 // desc: functions used in all phases of the compiler to give error messages
28 // about the Tiger program. (now ChucK)
30 // author: Andrew Appel (appel@cs.princeton.edu)
31 // modified: Ge Wang (gewang@cs.princeton.edu)
32 // Perry R. Cook (prc@cs.princeton.edu)
34 //-----------------------------------------------------------------------------
38 #include "chuck_utils.h"
39 #include "chuck_errmsg.h"
40 #include "util_thread.h"
46 int EM_extLineNum
= 1;
47 t_CKBOOL anyErrors
= FALSE
;
50 static const char * fileName
= "";
51 static int lineNum
= 1;
52 static char g_buffer
[1024] = "";
53 static char g_lasterror
[1024] = "[chuck]: (no error)";
55 int g_loglevel
= CK_LOG_CORE
;
60 static const char * g_str
[] = {
76 typedef struct intList
{int i
; struct intList
*rest
;} *IntList
;
77 static IntList linePos
=NULL
;
81 static IntList
intList( int i
, IntList rest
)
83 IntList l
= (IntList
)checked_malloc(sizeof *l
);
95 linePos
= intList(EM_tokPos
, linePos
);
99 // content after rightmost '/'
100 const char * mini( const char * str
)
102 int len
= strlen( str
);
103 const char * p
= str
+ len
;
104 while( p
!= str
&& *p
!= '/' && *p
!= '\\' ) p
--;
105 return ( p
== str
|| strlen(p
+1) == 0 ? p
: p
+1 );
109 // content after 'struct'
110 const char * mini_type( const char * str
)
112 if( !strncmp( str
, "struct ", 7 ) ) str
+= 7;
113 const char * p
= str
;
114 while( *p
&& *p
>= '0' && *p
<= '9' ) p
++;
119 // [%s]:line(%d).char(%d):
120 void EM_error( int pos
, const char * message
, ... )
123 IntList lines
= linePos
;
127 while( lines
&& lines
->i
>= pos
)
133 fprintf( stderr
, "[%s]:", *fileName
? mini(fileName
) : "chuck" );
134 sprintf( g_lasterror
, "[%s]:", *fileName
? mini(fileName
) : "chuck" );
137 fprintf(stderr
, "line(%d).char(%d):", num
, pos
-lines
->i
);
138 sprintf( g_buffer
, "line(%d).char(%d):", num
, pos
-lines
->i
);
139 strcat( g_lasterror
, g_buffer
);
141 fprintf(stderr
, " " );
142 strcat( g_lasterror
, " " );
143 va_start(ap
, message
);
144 vfprintf(stderr
, message
, ap
);
145 vsprintf( g_buffer
, message
, ap
);
147 fprintf(stderr
, "\n");
149 strcat( g_lasterror
, g_buffer
);
154 void EM_error2( int line
, const char * message
, ... )
158 EM_extLineNum
= line
;
160 fprintf( stderr
, "[%s]:", *fileName
? mini(fileName
) : "chuck" );
161 sprintf( g_lasterror
, "[%s]:", *fileName
? mini(fileName
) : "chuck" );
164 fprintf( stderr
, "line(%d):", line
);
165 sprintf( g_buffer
, "line(%d):", line
);
166 strcat( g_lasterror
, g_buffer
);
168 fprintf( stderr
, " " );
169 strcat( g_lasterror
, " " );
171 va_start( ap
, message
);
172 vfprintf( stderr
, message
, ap
);
173 vsprintf( g_buffer
, message
, ap
);
176 strcat( g_lasterror
, g_buffer
);
177 fprintf( stderr
, "\n" );
183 void EM_error2b( int line
, const char * message
, ... )
187 EM_extLineNum
= line
;
189 fprintf( stderr
, "[%s]:", *fileName
? mini(fileName
) : "chuck" );
190 sprintf( g_lasterror
, "[%s]:", *fileName
? mini(fileName
) : "chuck" );
193 fprintf( stderr
, "line(%d):", line
);
194 sprintf( g_buffer
, "line(%d):", line
);
195 strcat( g_lasterror
, g_buffer
);
197 fprintf( stderr
, " " );
198 strcat( g_lasterror
, " " );
200 va_start( ap
, message
);
201 vfprintf( stderr
, message
, ap
);
202 vsprintf( g_buffer
, message
, ap
);
205 strcat( g_lasterror
, g_buffer
);
206 fprintf( stdout
, "\n" );
212 void EM_error3( const char * message
, ... )
216 g_lasterror
[0] = '\0';
219 va_start( ap
, message
);
220 vfprintf( stderr
, message
, ap
);
221 vsprintf( g_buffer
, message
, ap
);
224 strcat( g_lasterror
, g_buffer
);
225 fprintf( stderr
, "\n" );
231 void EM_log( int level
, const char * message
, ... )
235 if( level
> CK_LOG_CRAZY
) level
= CK_LOG_CRAZY
;
236 else if( level
<= CK_LOG_NONE
) level
= CK_LOG_NONE
+ 1;
239 if( level
> g_loglevel
) return;
241 g_logmutex
.acquire();
242 fprintf( stderr
, "[chuck]:" );
243 fprintf( stderr
, "(%i:%s): ", level
, g_str
[level
] );
245 // if( g_logstack ) fprintf( stderr, " " );
246 for( int i
= 0; i
< g_logstack
; i
++ )
247 fprintf( stderr
, " | " );
249 va_start( ap
, message
);
250 vfprintf( stderr
, message
, ap
);
253 fprintf( stderr
, "\n" );
255 g_logmutex
.release();
260 void EM_setlog( int level
)
262 if( level
> CK_LOG_CRAZY
) level
= CK_LOG_CRAZY
;
263 else if( level
< CK_LOG_NONE
) level
= CK_LOG_NONE
;
267 EM_log( CK_LOG_SYSTEM
, "setting log level to: %i (%s)...", level
, g_str
[level
] );
280 if( g_logstack
< 0 ) g_logstack
= 0;
284 t_CKBOOL
EM_reset( const char * fname
, FILE * fd
)
287 fileName
= fname
? fname
: (c_str
)"";
297 linePos
= linePos
->rest
;
303 linePos
= intList( 0, NULL
);
310 void EM_change_file( const char * fname
)
313 fileName
= fname
? fname
: (c_str
)"";
322 const char * EM_lasterror()