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
45+int EM_tokPos = 0;
46+int EM_lineNum = 1;
47+int EM_extLineNum = 1;
48+t_CKBOOL anyErrors= FALSE;
49+
50+// local global
51+static const char * fileName = "";
52+static int lineNum = 1;
53+static char g_buffer[1024] = "";
54+static const size_t LASTERROR_SIZE = 1024;
55+static char g_lasterror[LASTERROR_SIZE] = "[chuck]: (no error)";
56+static size_t g_lasterrorIndex = strlen(g_lasterror);
57+// log globals
58+int g_loglevel = CK_LOG_CORE;
59+int g_logstack = 0;
60+XMutex g_logmutex;
61+
62+// more local globals
63+static const size_t g_buffer2_size = 1024;
64+static char g_buffer2[g_buffer2_size] = "";
65+std::stringstream g_stdout_stream;
66+std::stringstream g_stderr_stream;
67+
68+// local global callbacks
69+void (*g_stdout_callback)(const char *) = NULL;
70+void (*g_stderr_callback)(const char *) = NULL;
71+
72+void 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+
88+void 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+
104+void 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+
126+void 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+
149+void 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+
162+void 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+
176+void 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+
185+void 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
194+extern "C++" {
195+
196+ChuckOutStream::ChuckOutStream( bool isErr )
197+{
198+ m_callback = NULL;
199+ m_isErr = isErr;
200+}
201+
202+
203+ChuckOutStream::~ChuckOutStream()
204+{
205+}
206+
207+
208+ChuckOutStream& 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+
219+ChuckOutStream& ChuckOutStream::operator<<( const char * val )
220+{
221+ m_stream << val;
222+ return *this;
223+}
224+
225+
226+ChuckOutStream& ChuckOutStream::operator<<( const double val )
227+{
228+ m_stream << val;
229+ return *this;
230+}
231+
232+
233+ChuckOutStream& ChuckOutStream::operator<<( const float val )
234+{
235+ m_stream << val;
236+ return *this;
237+}
238+
239+
240+ChuckOutStream& ChuckOutStream::operator<<( const unsigned long long val )
241+{
242+ m_stream << val;
243+ return *this;
244+}
245+
246+
247+ChuckOutStream& ChuckOutStream::operator<<( const long long val )
248+{
249+ m_stream << val;
250+ return *this;
251+}
252+
253+
254+ChuckOutStream& ChuckOutStream::operator<<( const unsigned long val )
255+{
256+ m_stream << val;
257+ return *this;
258+}
259+
260+
261+ChuckOutStream& ChuckOutStream::operator<<( const long val )
262+{
263+ m_stream << val;
264+ return *this;
265+}
266+
267+
268+ChuckOutStream& ChuckOutStream::operator<<( const unsigned int val )
269+{
270+ m_stream << val;
271+ return *this;
272+}
273+
274+
275+ChuckOutStream& ChuckOutStream::operator<<( const int val )
276+{
277+ m_stream << val;
278+ return *this;
279+}
280+
281+
282+ChuckOutStream& ChuckOutStream::operator<<( const bool val )
283+{
284+ m_stream << val;
285+ return *this;
286+}
287+
288+
289+
290+
291+
292+void ChuckOutStream::set_callback( void (*callback)( const char * ) )
293+{
294+ m_callback = callback;
295+}
296+
297+
298+void 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+
326+ChuckOutStream g_ck_stdoutstream( FALSE );
327+ChuckOutStream g_ck_stderrstream( TRUE );
328+
329+}
330+#endif
331+
332+
333+
334+
335+// name
336+static 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
352+typedef struct intList {int i; struct intList *rest;} *IntList;
353+static IntList linePos=NULL;
354+
355+
356+static 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
372+static 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
381+void 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 '/'
391+const 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'
401+const 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+
409+void EM_reset_msg()
410+{
411+ g_lasterror[0] = '\0';
412+ g_lasterrorIndex = 0;
413+}
414+
415+// [%s]:line(%d).char(%d):
416+void 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):
459+void 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):
495+void 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+//
531+void 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
556+void 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
585+void 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
596+void EM_pushlog()
597+{
598+ g_logstack++;
599+}
600+
601+// pop log
602+void EM_poplog()
603+{
604+ g_logstack--;
605+ if( g_logstack < 0 ) g_logstack = 0;
606+}
607+
608+// prepare new file
609+t_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
635+void 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
647+const 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