History

the only constant is change.

Ge Wang committed 9 years ago

Commit 009ac191 parent b1e2669181 files · +0 −3911Browse files

Showing the changes to src/core/chuck_errmsg.cpp (1 of 181 files). Show all

Unified · Split

src/core/chuck_errmsg.cpp+650−0
@@ -0,0 +1,650 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: errmsg.cpp
27// desc: functions used in all phases of the compiler to give error messages
28// based on Andrew Appel's Tiger code
29//
30// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
31// based on code by: Andrew Appel (appel@cs.princeton.edu)
32// date: Summer 2002
33//-----------------------------------------------------------------------------
34#include <stdlib.h>
35#include <stdarg.h>
36#include <string.h>
37#include <sstream>
38#include <iostream>
39#include "chuck_utils.h"
40#include "chuck_errmsg.h"
41#include "util_thread.h"
42
43
44// global
45int EM_tokPos = 0;
46int EM_lineNum = 1;
47int EM_extLineNum = 1;
48t_CKBOOL anyErrors= FALSE;
49
50// local global
51static const char * fileName = "";
52static int lineNum = 1;
53static char g_buffer[1024] = "";
54static const size_t LASTERROR_SIZE = 1024;
55static char g_lasterror[LASTERROR_SIZE] = "[chuck]: (no error)";
56static size_t g_lasterrorIndex = strlen(g_lasterror);
57// log globals
58int g_loglevel = CK_LOG_CORE;
59int g_logstack = 0;
60XMutex g_logmutex;
61
62// more local globals
63static const size_t g_buffer2_size = 1024;
64static char g_buffer2[g_buffer2_size] = "";
65std::stringstream g_stdout_stream;
66std::stringstream g_stderr_stream;
67
68// local global callbacks
69void (*g_stdout_callback)(const char *) = NULL;
70void (*g_stderr_callback)(const char *) = NULL;
71
72void ck_fprintf_stdout( const char * format, ... )
73{
74 // evaluate the format string
75 va_list args;
76 va_start( args, format );
77 vsnprintf( g_buffer2, g_buffer2_size, format, args );
78 va_end( args );
79
80 // send the formatted string to the buffer
81 g_stdout_stream << g_buffer2;
82
83 // try flushing
84 ck_fflush_stdout();
85}
86
87
88void ck_fprintf_stderr( const char * format, ... )
89{
90 // evaluate the format string
91 va_list args;
92 va_start( args, format );
93 vsnprintf( g_buffer2, g_buffer2_size, format, args );
94 va_end( args );
95
96 // send the formatted string to the buffer
97 g_stderr_stream << g_buffer2;
98
99 // try flushing
100 ck_fflush_stderr();
101}
102
103
104void ck_fflush_stdout()
105{
106 // check if stream contains a newline
107 if( g_stdout_stream.str().find( '\n' ) != std::string::npos )
108 {
109 // if so, print it
110 if( g_stdout_callback == NULL ) {
111 // send to stdout
112 fprintf( stdout, "%s", g_stdout_stream.str().c_str() );
113 }
114 else
115 {
116 // emit to callback
117 g_stdout_callback( g_stdout_stream.str().c_str() );
118 }
119 // and clear buffer
120 g_stdout_stream.str( std::string() );
121
122 }
123}
124
125
126void ck_fflush_stderr()
127{
128 // check if stream contains a newline
129 if( g_stderr_stream.str().find( '\n' ) != std::string::npos )
130 {
131 // if so, print it
132 if( g_stderr_callback == NULL )
133 {
134 // send to stderr
135 fprintf( stderr, "%s", g_stderr_stream.str().c_str() );
136 }
137 else
138 {
139 // emit to callback
140 g_stderr_callback( g_stderr_stream.str().c_str() );
141 }
142
143 // and clear buffer
144 g_stderr_stream.str( std::string() );
145 }
146}
147
148
149void ck_vfprintf_stdout( const char * format, va_list args )
150{
151 // evaluate the format string
152 vsnprintf( g_buffer2, g_buffer2_size, format, args );
153
154 // send the formatted string to the buffer
155 g_stdout_stream << g_buffer2;
156
157 // try flushing
158 ck_fflush_stdout();
159}
160
161
162void ck_vfprintf_stderr( const char * format, va_list args )
163{
164 // evaluate the format string
165 vsnprintf( g_buffer2, g_buffer2_size, format, args );
166
167 // send the formatted string to the buffer
168 g_stderr_stream << g_buffer2;
169
170 // try flushing
171 ck_fflush_stderr();
172}
173
174
175
176void ck_set_stdout_callback( void (*callback)(const char *) )
177{
178 g_stdout_callback = callback;
179#ifdef __cplusplus
180 g_ck_stdoutstream.set_callback( callback );
181#endif
182}
183
184
185void ck_set_stderr_callback( void (*callback)(const char *) )
186{
187 g_stderr_callback = callback;
188#ifdef __cplusplus
189 g_ck_stderrstream.set_callback( callback );
190#endif
191}
192
193#ifdef __cplusplus
194extern "C++" {
195
196ChuckOutStream::ChuckOutStream( bool isErr )
197{
198 m_callback = NULL;
199 m_isErr = isErr;
200}
201
202
203ChuckOutStream::~ChuckOutStream()
204{
205}
206
207
208ChuckOutStream& ChuckOutStream::operator<<( const std::string val )
209{
210 m_stream << val;
211 if( val == CK_STDENDL )
212 {
213 this->flush();
214 }
215 return *this;
216}
217
218
219ChuckOutStream& ChuckOutStream::operator<<( const char * val )
220{
221 m_stream << val;
222 return *this;
223}
224
225
226ChuckOutStream& ChuckOutStream::operator<<( const double val )
227{
228 m_stream << val;
229 return *this;
230}
231
232
233ChuckOutStream& ChuckOutStream::operator<<( const float val )
234{
235 m_stream << val;
236 return *this;
237}
238
239
240ChuckOutStream& ChuckOutStream::operator<<( const unsigned long long val )
241{
242 m_stream << val;
243 return *this;
244}
245
246
247ChuckOutStream& ChuckOutStream::operator<<( const long long val )
248{
249 m_stream << val;
250 return *this;
251}
252
253
254ChuckOutStream& ChuckOutStream::operator<<( const unsigned long val )
255{
256 m_stream << val;
257 return *this;
258}
259
260
261ChuckOutStream& ChuckOutStream::operator<<( const long val )
262{
263 m_stream << val;
264 return *this;
265}
266
267
268ChuckOutStream& ChuckOutStream::operator<<( const unsigned int val )
269{
270 m_stream << val;
271 return *this;
272}
273
274
275ChuckOutStream& ChuckOutStream::operator<<( const int val )
276{
277 m_stream << val;
278 return *this;
279}
280
281
282ChuckOutStream& ChuckOutStream::operator<<( const bool val )
283{
284 m_stream << val;
285 return *this;
286}
287
288
289
290
291
292void ChuckOutStream::set_callback( void (*callback)( const char * ) )
293{
294 m_callback = callback;
295}
296
297
298void ChuckOutStream::flush()
299{
300 if( m_callback != NULL )
301 {
302 // send to callback
303 m_callback( m_stream.str().c_str() );
304 }
305 else
306 {
307 // print it
308 if( m_isErr )
309 {
310 // to cerr
311 std::cerr << m_stream.str().c_str();
312 std::cerr.flush();
313 }
314 else
315 {
316 // to cout
317 std::cout << m_stream.str().c_str();
318 std::cout.flush();
319 }
320 }
321 // clear buffer
322 m_stream.str( std::string() );
323}
324
325
326ChuckOutStream g_ck_stdoutstream( FALSE );
327ChuckOutStream g_ck_stderrstream( TRUE );
328
329}
330#endif
331
332
333
334
335// name
336static const char * g_str[] = {
337 "NONE", // 0
338 "CKCORE", // 1
339 "SYSTEM", // 2
340 "SEVERE", // 3
341 "WARN!!", // 4
342 "INFORM", // 5
343 "CONFIG", // 6
344 "FINE!!", // 7
345 "FINER!", // 8
346 "FINEST", // 9
347 "ALL!!" // 10
348};
349
350
351// intList
352typedef struct intList {int i; struct intList *rest;} *IntList;
353static IntList linePos=NULL;
354
355
356static int lastErrorCat(const char * str)
357{
358 assert(g_lasterrorIndex <= LASTERROR_SIZE-1);
359
360 size_t len = strlen(str);
361
362 strncat(g_lasterror, str, LASTERROR_SIZE-g_lasterrorIndex-1);
363
364 size_t appendCount = ck_min(LASTERROR_SIZE-g_lasterrorIndex-1, len);
365 g_lasterrorIndex += appendCount;
366
367 return appendCount > 0;
368}
369
370
371// constructor
372static IntList intList( int i, IntList rest )
373{
374 IntList l = (IntList)checked_malloc(sizeof *l);
375 l->i=i; l->rest=rest;
376 return l;
377}
378
379
380// new line in lexer
381void EM_newline(void)
382{
383 lineNum++;
384 EM_lineNum++;
385 EM_extLineNum++;
386 linePos = intList(EM_tokPos, linePos);
387}
388
389
390// content after rightmost '/'
391const char * mini( const char * str )
392{
393 int len = strlen( str );
394 const char * p = str + len;
395 while( p != str && *p != '/' && *p != '\\' ) p--;
396 return ( p == str || strlen(p+1) == 0 ? p : p+1 );
397}
398
399
400// content after 'struct'
401const char * mini_type( const char * str )
402{
403 if( !strncmp( str, "struct ", 7 ) ) str += 7;
404 const char * p = str;
405 while( *p && *p >= '0' && *p <= '9' ) p++;
406 return p;
407}
408
409void EM_reset_msg()
410{
411 g_lasterror[0] = '\0';
412 g_lasterrorIndex = 0;
413}
414
415// [%s]:line(%d).char(%d):
416void EM_error( int pos, const char * message, ... )
417{
418 va_list ap;
419 IntList lines = linePos;
420 int num = lineNum;
421
422 anyErrors = TRUE;
423 while( lines && lines->i >= pos )
424 {
425 lines = lines->rest;
426 num--;
427 }
428
429 // separate errmsgs with newlines
430 if( g_lasterror[0] != '\0' ) lastErrorCat( "\n" );
431
432 CK_FPRINTF_STDERR( "[%s]:", *fileName ? mini(fileName) : "chuck" );
433 sprintf( g_buffer, "[%s]:", *fileName ? mini(fileName) : "chuck" );
434 lastErrorCat( g_buffer );
435 if(lines)
436 {
437 CK_FPRINTF_STDERR( "line(%d).char(%d):", num, pos-lines->i );
438 sprintf( g_buffer, "line(%d).char(%d):", num, pos-lines->i );
439 lastErrorCat( g_buffer );
440 }
441 CK_FPRINTF_STDERR( " " );
442 lastErrorCat( " " );
443
444 va_start(ap, message);
445 CK_VFPRINTF_STDERR( message, ap);
446 va_end(ap);
447
448 va_start(ap, message);
449 vsprintf( g_buffer, message, ap );
450 va_end(ap);
451
452 CK_FPRINTF_STDERR( "\n");
453 CK_FFLUSH_STDERR();
454 lastErrorCat( g_buffer );
455}
456
457
458// [%s]:line(%d):
459void EM_error2( int line, const char * message, ... )
460{
461 va_list ap;
462
463 EM_extLineNum = line;
464
465 // separate errmsgs with newlines
466 if( g_lasterror[0] != '\0' ) lastErrorCat( "\n" );
467
468 CK_FPRINTF_STDERR( "[%s]:", *fileName ? mini(fileName) : "chuck" );
469 sprintf( g_buffer, "[%s]:", *fileName ? mini(fileName) : "chuck" );
470 lastErrorCat( g_buffer );
471 if(line)
472 {
473 CK_FPRINTF_STDERR( "line(%d):", line );
474 sprintf( g_buffer, "line(%d):", line );
475 lastErrorCat( g_buffer );
476 }
477 CK_FPRINTF_STDERR( " " );
478 lastErrorCat( " " );
479
480 va_start( ap, message );
481 CK_VFPRINTF_STDERR( message, ap );
482 va_end( ap );
483
484 va_start( ap, message );
485 vsprintf( g_buffer, message, ap );
486 va_end( ap );
487
488 lastErrorCat( g_buffer );
489 CK_FPRINTF_STDERR( "\n" );
490 CK_FFLUSH_STDERR();
491}
492
493
494// [%s]:line(%d):
495void EM_error2b( int line, const char * message, ... )
496{
497 va_list ap;
498
499 EM_extLineNum = line;
500
501 // separate errmsgs with newlines
502 if( g_lasterror[0] != '\0' ) lastErrorCat( "\n" );
503
504 CK_FPRINTF_STDERR( "[%s]:", *fileName ? mini(fileName) : "chuck" );
505 sprintf( g_buffer, "[%s]:", *fileName ? mini(fileName) : "chuck" );
506 lastErrorCat( g_buffer );
507 if(line)
508 {
509 CK_FPRINTF_STDERR( "line(%d):", line );
510 sprintf( g_buffer, "line(%d):", line );
511 lastErrorCat( g_buffer );
512 }
513 CK_FPRINTF_STDERR( " " );
514 lastErrorCat( " " );
515
516 va_start( ap, message );
517 CK_VFPRINTF_STDERR( message, ap );
518 va_end( ap );
519
520 va_start( ap, message );
521 vsprintf( g_buffer, message, ap );
522 va_end( ap );
523
524 lastErrorCat( g_buffer );
525 CK_FPRINTF_STDOUT( "\n" );
526 CK_FFLUSH_STDOUT();
527}
528
529
530//
531void EM_error3( const char * message, ... )
532{
533 va_list ap;
534
535 // separate errmsgs with newlines
536 if( g_lasterror[0] != '\0' ) lastErrorCat( "\n" );
537
538// g_lasterror[0] = '\0';
539 g_buffer[0] = '\0';
540
541 va_start( ap, message );
542 CK_VFPRINTF_STDERR( message, ap );
543 va_end( ap );
544
545 va_start( ap, message );
546 vsprintf( g_buffer, message, ap );
547 va_end( ap );
548
549 lastErrorCat( g_buffer );
550 CK_FPRINTF_STDERR( "\n" );
551 CK_FFLUSH_STDERR();
552}
553
554
555// log
556void EM_log( int level, const char * message, ... )
557{
558 va_list ap;
559
560 if( level > CK_LOG_CRAZY ) level = CK_LOG_CRAZY;
561 else if( level <= CK_LOG_NONE ) level = CK_LOG_NONE + 1;
562
563 // check level
564 if( level > g_loglevel ) return;
565
566 g_logmutex.acquire();
567 CK_FPRINTF_STDERR( "[chuck]:" );
568 CK_FPRINTF_STDERR( "(%i:%s): ", level, g_str[level] );
569
570 // if( g_logstack ) CK_FPRINTF_STDERR( " " );
571 for( int i = 0; i < g_logstack; i++ )
572 CK_FPRINTF_STDERR( " | " );
573
574 va_start( ap, message );
575 CK_VFPRINTF_STDERR( message, ap );
576 va_end( ap );
577
578 CK_FPRINTF_STDERR( "\n" );
579 CK_FFLUSH_STDERR();
580 g_logmutex.release();
581}
582
583
584// set log level
585void EM_setlog( int level )
586{
587 if( level > CK_LOG_CRAZY ) level = CK_LOG_CRAZY;
588 else if( level < CK_LOG_NONE ) level = CK_LOG_NONE;
589 g_loglevel = level;
590
591 // log this
592 EM_log( CK_LOG_SYSTEM, "setting log level to: %i (%s)...", level, g_str[level] );
593}
594
595// push log
596void EM_pushlog()
597{
598 g_logstack++;
599}
600
601// pop log
602void EM_poplog()
603{
604 g_logstack--;
605 if( g_logstack < 0 ) g_logstack = 0;
606}
607
608// prepare new file
609t_CKBOOL EM_reset( const char * fname, FILE * fd )
610{
611 anyErrors = FALSE;
612 fileName = fname ? fname : (c_str)"";
613 lineNum = 1;
614 EM_lineNum = 1;
615 EM_extLineNum = 1;
616
617 // free the intList
618 IntList curr = NULL;
619 while( linePos )
620 {
621 curr = linePos;
622 linePos = linePos->rest;
623 // free
624 free( curr );
625 }
626
627 // make new intList
628 linePos = intList( 0, NULL );
629
630 return TRUE;
631}
632
633
634// change file
635void EM_change_file( const char * fname )
636{
637 // set
638 fileName = fname ? fname : (c_str)"";
639 // more set
640 lineNum = 0;
641 EM_lineNum = 0;
642 EM_extLineNum = 0;
643}
644
645
646// return last error
647const char * EM_lasterror()
648{
649 return g_lasterror;
650}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t