*** empty log message ***
[chuck-blob.git] / v2 / chuck_errmsg.cpp
blob83c493bbb66f167b6a8aa6deaf237d01ec7bb24d
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
22 U.S.A.
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: errmsg.cpp
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)
33 // date: Autumn 2002
34 //-----------------------------------------------------------------------------
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <string.h>
38 #include "chuck_utils.h"
39 #include "chuck_errmsg.h"
40 #include "util_thread.h"
43 // global
44 int EM_tokPos = 0;
45 int EM_lineNum = 1;
46 int EM_extLineNum = 1;
47 t_CKBOOL anyErrors= FALSE;
49 // local global
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)";
54 // log globals
55 int g_loglevel = CK_LOG_CORE;
56 int g_logstack = 0;
57 XMutex g_logmutex;
59 // name
60 static const char * g_str[] = {
61 "NONE", // 0
62 "CKCORE", // 1
63 "SYSTEM", // 2
64 "SEVERE", // 3
65 "WARN!!", // 4
66 "INFORM", // 5
67 "CONFIG", // 6
68 "FINE!!", // 7
69 "FINER!", // 8
70 "FINEST", // 9
71 "ALL!!" // 10
75 // intList
76 typedef struct intList {int i; struct intList *rest;} *IntList;
77 static IntList linePos=NULL;
80 // constructor
81 static IntList intList( int i, IntList rest )
83 IntList l = (IntList)checked_malloc(sizeof *l);
84 l->i=i; l->rest=rest;
85 return l;
89 // new line in lexer
90 void EM_newline(void)
92 lineNum++;
93 EM_lineNum++;
94 EM_extLineNum++;
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++;
115 return p;
119 // [%s]:line(%d).char(%d):
120 void EM_error( int pos, const char * message, ... )
122 va_list ap;
123 IntList lines = linePos;
124 int num = lineNum;
126 anyErrors = TRUE;
127 while( lines && lines->i >= pos )
129 lines = lines->rest;
130 num--;
133 fprintf( stderr, "[%s]:", *fileName ? mini(fileName) : "chuck" );
134 sprintf( g_lasterror, "[%s]:", *fileName ? mini(fileName) : "chuck" );
135 if(lines)
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 );
146 va_end(ap);
147 fprintf(stderr, "\n");
148 fflush( stderr );
149 strcat( g_lasterror, g_buffer );
153 // [%s]:line(%d):
154 void EM_error2( int line, const char * message, ... )
156 va_list ap;
158 EM_extLineNum = line;
160 fprintf( stderr, "[%s]:", *fileName ? mini(fileName) : "chuck" );
161 sprintf( g_lasterror, "[%s]:", *fileName ? mini(fileName) : "chuck" );
162 if(line)
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 );
174 va_end( ap );
176 strcat( g_lasterror, g_buffer );
177 fprintf( stderr, "\n" );
178 fflush( stderr );
182 // [%s]:line(%d):
183 void EM_error2b( int line, const char * message, ... )
185 va_list ap;
187 EM_extLineNum = line;
189 fprintf( stderr, "[%s]:", *fileName ? mini(fileName) : "chuck" );
190 sprintf( g_lasterror, "[%s]:", *fileName ? mini(fileName) : "chuck" );
191 if(line)
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 );
203 va_end( ap );
205 strcat( g_lasterror, g_buffer );
206 fprintf( stdout, "\n" );
207 fflush( stdout );
212 void EM_error3( const char * message, ... )
214 va_list ap;
216 g_lasterror[0] = '\0';
217 g_buffer[0] = '\0';
219 va_start( ap, message );
220 vfprintf( stderr, message, ap );
221 vsprintf( g_buffer, message, ap );
222 va_end( ap );
224 strcat( g_lasterror, g_buffer );
225 fprintf( stderr, "\n" );
226 fflush( stderr );
230 // log
231 void EM_log( int level, const char * message, ... )
233 va_list ap;
235 if( level > CK_LOG_CRAZY ) level = CK_LOG_CRAZY;
236 else if( level <= CK_LOG_NONE ) level = CK_LOG_NONE + 1;
238 // check level
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 );
251 va_end( ap );
253 fprintf( stderr, "\n" );
254 fflush( stderr );
255 g_logmutex.release();
259 // set log level
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;
264 g_loglevel = level;
266 // log this
267 EM_log( CK_LOG_SYSTEM, "setting log level to: %i (%s)...", level, g_str[level] );
270 // push log
271 void EM_pushlog()
273 g_logstack++;
276 // pop log
277 void EM_poplog()
279 g_logstack--;
280 if( g_logstack < 0 ) g_logstack = 0;
283 // prepare new file
284 t_CKBOOL EM_reset( const char * fname, FILE * fd )
286 anyErrors = FALSE;
287 fileName = fname ? fname : (c_str)"";
288 lineNum = 1;
289 EM_lineNum = 1;
290 EM_extLineNum = 1;
292 // free the intList
293 IntList curr = NULL;
294 while( linePos )
296 curr = linePos;
297 linePos = linePos->rest;
298 // free
299 free( curr );
302 // make new intList
303 linePos = intList( 0, NULL );
305 return TRUE;
309 // change file
310 void EM_change_file( const char * fname )
312 // set
313 fileName = fname ? fname : (c_str)"";
314 // more set
315 lineNum = 0;
316 EM_lineNum = 0;
317 EM_extLineNum = 0;
321 // return last error
322 const char * EM_lasterror()
324 return g_lasterror;