/[jscoverage]/trunk/highlight.cpp
ViewVC logotype

Diff of /trunk/highlight.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 215 by siliconforks, Fri Oct 3 02:26:18 2008 UTC revision 399 by siliconforks, Tue Dec 9 03:37:47 2008 UTC
# Line 91  Line 91 
91  static enum Class current_class;  static enum Class current_class;
92    
93  static void output_character(jschar c, enum Class class) {  static void output_character(jschar c, enum Class class) {
94      if (c == '\r' || c == '\n' || c == 0x2028 || c == 0x2029) {
95        class = CLASS_NONE;
96      }
97    
98    if (class != current_class) {    if (class != current_class) {
99      /* output the end tag */      /* output the end tag */
100      if (current_class != CLASS_NONE) {      if (current_class != CLASS_NONE) {
# Line 105  Line 109 
109      }      }
110    }    }
111    
112      if (column_num == UINT16_MAX) {
113        fatal("%s: script contains a line with more than 65,535 columns", g_id);
114      }
115      column_num++;
116    switch (c) {    switch (c) {
117    case '&':    case '&':
118      Stream_write_string(g_output, "&");      Stream_write_string(g_output, "&");
# Line 116  Line 124 
124      Stream_write_string(g_output, ">");      Stream_write_string(g_output, ">");
125      break;      break;
126    case '\t':    case '\t':
   case '\n':  
127      Stream_write_char(g_output, c);      Stream_write_char(g_output, c);
128      break;      break;
129      case '\r':
130      case '\n':
131      case 0x2028:
132      case 0x2029:
133        if (c == '\r' && character_offset + 1 < g_num_characters && g_characters[character_offset + 1] == '\n') {
134          break;
135        }
136        Stream_write_char(g_output, '\n');
137        column_num = 0;
138        if (line_num == UINT16_MAX) {
139          fatal("%s: script contains more than 65,535 lines", g_id);
140        }
141        line_num++;
142        break;
143    default:    default:
144      if (32 <= c && c <= 126) {      if (32 <= c && c <= 126) {
145        Stream_write_char(g_output, c);        Stream_write_char(g_output, c);
# Line 128  Line 149 
149      }      }
150      break;      break;
151    }    }
152      character_offset++;
153  }  }
154    
155  static void mark_nontoken_chars(uint16_t end_line, uint16_t end_column) {  static void mark_nontoken_chars(uint16_t end_line, uint16_t end_column) {
# Line 160  Line 182 
182          state = STATE_MULTILINE_COMMENT;          state = STATE_MULTILINE_COMMENT;
183          output_character('/', CLASS_COMMENT);          output_character('/', CLASS_COMMENT);
184          output_character('*', CLASS_COMMENT);          output_character('*', CLASS_COMMENT);
         character_offset += 2;  
         if (column_num >= UINT16_MAX - 1) {  
           fatal("%s: script contains line with more than 65,535 characters", g_id);  
         }  
         column_num += 2;  
185          continue;          continue;
186        }        }
187        break;        break;
# Line 178  Line 195 
195          output_character('*', CLASS_COMMENT);          output_character('*', CLASS_COMMENT);
196          output_character('/', CLASS_COMMENT);          output_character('/', CLASS_COMMENT);
197          state = STATE_NORMAL;          state = STATE_NORMAL;
         character_offset += 2;  
         if (column_num >= UINT16_MAX - 1) {  
           fatal("%s: script contains line with more than 65,535 characters", g_id);  
         }  
         column_num += 2;  
198          continue;          continue;
199        }        }
200        break;        break;
201      }      }
202    
203      character_offset++;      if (state == STATE_NORMAL) {
204      if (c == '\r' || c == '\n' || c == 0x2028 || c == 0x2029) {        output_character(c, CLASS_NONE);
       if (line_num == UINT16_MAX) {  
         fatal("%s: script contains more than 65,535 lines", g_id);  
       }  
       line_num++;  
       column_num = 0;  
       if (c == '\r' && character_offset < g_num_characters && g_characters[character_offset] == '\n') {  
         character_offset++;  
       }  
       output_character('\n', CLASS_NONE);  
205      }      }
206      else {      else {
207        if (column_num == UINT16_MAX) {        output_character(c, CLASS_COMMENT);
         fatal("%s: script contains line with more than 65,535 characters", g_id);  
       }  
       column_num++;  
       if (state == STATE_NORMAL) {  
         output_character(c, CLASS_NONE);  
       }  
       else {  
         output_character(c, CLASS_COMMENT);  
       }  
208      }      }
209    }    }
210  }  }
# Line 227  Line 221 
221    current_class = CLASS_NONE;    current_class = CLASS_NONE;
222    
223    /* tokenize the JavaScript */    /* tokenize the JavaScript */
224    JSTokenStream * token_stream = js_NewTokenStream(context, characters, num_characters, NULL, 1, NULL);    JSTokenStream token_stream;
225    if (token_stream == NULL) {    if (! js_InitTokenStream(context, &token_stream, characters, num_characters, NULL, NULL, 1)) {
226      fatal("cannot create token stream from JavaScript file %s", id);      fatal("cannot create token stream from JavaScript file %s", id);
227    }    }
228    
     /* see js_ParseTokenStream in jsparse.c */  
     JSObject * chain = NULL;  
     JSContext * cx = context;  
     JSStackFrame *fp, frame;  
   
     /*  
      * Push a compiler frame if we have no frames, or if the top frame is a  
      * lightweight function activation, or if its scope chain doesn't match  
      * the one passed to us.  
      */  
     fp = cx->fp;  
     if (!fp || !fp->varobj || fp->scopeChain != chain) {  
         memset(&frame, 0, sizeof frame);  
         frame.varobj = frame.scopeChain = chain;  
         if (cx->options & JSOPTION_VAROBJFIX) {  
             while ((chain = JS_GetParent(cx, chain)) != NULL)  
                 frame.varobj = chain;  
         }  
         frame.down = fp;  
         if (fp)  
             frame.flags = fp->flags & (JSFRAME_SPECIAL | JSFRAME_COMPILE_N_GO);  
         cx->fp = &frame;  
     }  
   
     /*  
      * Protect atoms from being collected by a GC activation, which might  
      * - nest on this thread due to out of memory (the so-called "last ditch"  
      *   GC attempted within js_NewGCThing), or  
      * - run for any reason on another thread if this thread is suspended on  
      *   an object lock before it finishes generating bytecode into a script  
      *   protected from the GC by a root or a stack frame reference.  
      */  
     JS_KEEP_ATOMS(cx->runtime);  
   
229    for (;;) {    for (;;) {
230      JSTokenType tt = js_GetToken(context, token_stream);      JSTokenType tt = js_GetToken(context, &token_stream);
231    
232      if (tt == TOK_ERROR) {      if (tt == TOK_ERROR) {
233        fatal("JavaScript parse error: %s: line = %d, col = %d\n", id, line_num, column_num);        fatal("JavaScript parse error: %s: line = %d, col = %d\n", id, line_num, column_num);
# Line 279  Line 239 
239      }      }
240    
241      /* mark the chars before the token */      /* mark the chars before the token */
242      JSToken t = CURRENT_TOKEN(token_stream);      JSToken t = CURRENT_TOKEN(&token_stream);
243      mark_nontoken_chars(t.pos.begin.lineno, t.pos.begin.index);      mark_nontoken_chars(t.pos.begin.lineno, t.pos.begin.index);
244    
245      /* mark the token */      /* mark the token */
# Line 290  Line 250 
250        abort();        abort();
251      case TOK_EOL:      case TOK_EOL:
252        class = CLASS_NONE;        class = CLASS_NONE;
253        token_stream->flags |= TSF_OPERAND;        token_stream.flags |= TSF_OPERAND;
254        break;        break;
255      case TOK_SEMI:      case TOK_SEMI:
256      case TOK_COMMA:      case TOK_COMMA:
# Line 310  Line 270 
270      case TOK_STAR:      case TOK_STAR:
271      case TOK_DIVOP:      case TOK_DIVOP:
272        class = CLASS_SYMBOL;        class = CLASS_SYMBOL;
273        token_stream->flags |= TSF_OPERAND;        token_stream.flags |= TSF_OPERAND;
274        break;        break;
275      case TOK_UNARYOP:      case TOK_UNARYOP:
276        switch (t.t_op) {        switch (t.t_op) {
# Line 319  Line 279 
279        case JSOP_NOT:        case JSOP_NOT:
280        case JSOP_BITNOT:        case JSOP_BITNOT:
281          class = CLASS_SYMBOL;          class = CLASS_SYMBOL;
282          token_stream->flags |= TSF_OPERAND;          token_stream.flags |= TSF_OPERAND;
283          break;          break;
284        case JSOP_TYPEOF:        case JSOP_TYPEOF:
285          class = CLASS_KEYWORD;          class = CLASS_KEYWORD;
286          token_stream->flags |= TSF_OPERAND;          token_stream.flags |= TSF_OPERAND;
287          break;          break;
288        case JSOP_VOID:        case JSOP_VOID:
289          class = CLASS_TYPE;          class = CLASS_TYPE;
290          token_stream->flags |= TSF_OPERAND;          token_stream.flags |= TSF_OPERAND;
291          break;          break;
292        default:        default:
293          abort();          abort();
# Line 335  Line 295 
295        break;        break;
296      case TOK_INC:      case TOK_INC:
297      case TOK_DEC:      case TOK_DEC:
298          class = CLASS_SYMBOL;
299          /* token_stream.flags does not change w.r.t. TSF_OPERAND */
300          break;
301      case TOK_DOT:      case TOK_DOT:
302      case TOK_LB:      case TOK_LB:
303        class = CLASS_SYMBOL;        class = CLASS_SYMBOL;
304        token_stream->flags |= TSF_OPERAND;        token_stream.flags |= TSF_OPERAND;
305        break;        break;
306      case TOK_RB:      case TOK_RB:
307        class = CLASS_SYMBOL;        class = CLASS_SYMBOL;
308        token_stream->flags &= ~TSF_OPERAND;        token_stream.flags &= ~TSF_OPERAND;
309        break;        break;
310      case TOK_LC:      case TOK_LC:
311        class = CLASS_CBRACKET;        class = CLASS_CBRACKET;
312        token_stream->flags |= TSF_OPERAND;        token_stream.flags |= TSF_OPERAND;
313        break;        break;
314      case TOK_RC:      case TOK_RC:
315        class = CLASS_CBRACKET;        class = CLASS_CBRACKET;
316        token_stream->flags &= ~TSF_OPERAND;        token_stream.flags &= ~TSF_OPERAND;
317        break;        break;
318      case TOK_LP:      case TOK_LP:
319        class = CLASS_SYMBOL;        class = CLASS_SYMBOL;
320        token_stream->flags |= TSF_OPERAND;        token_stream.flags |= TSF_OPERAND;
321        break;        break;
322      case TOK_RP:      case TOK_RP:
323        class = CLASS_SYMBOL;        class = CLASS_SYMBOL;
324        token_stream->flags &= ~TSF_OPERAND;        token_stream.flags &= ~TSF_OPERAND;
325        break;        break;
326      case TOK_NAME:      case TOK_NAME:
327        class = CLASS_NONE;        class = CLASS_NONE;
328        token_stream->flags &= ~TSF_OPERAND;        token_stream.flags &= ~TSF_OPERAND;
329        if (js_PeekToken(context, token_stream) == TOK_LP) {        if (js_PeekToken(context, &token_stream) == TOK_LP) {
330          /* function */          /* function */
331          class = CLASS_NONE;          class = CLASS_NONE;
332        }        }
333        break;        break;
334      case TOK_NUMBER:      case TOK_NUMBER:
335        class = CLASS_NUMBER;        class = CLASS_NUMBER;
336        token_stream->flags &= ~TSF_OPERAND;        token_stream.flags &= ~TSF_OPERAND;
337        break;        break;
338      case TOK_STRING:      case TOK_STRING:
339        class = CLASS_STRING;        class = CLASS_STRING;
340        token_stream->flags &= ~TSF_OPERAND;        token_stream.flags &= ~TSF_OPERAND;
341        break;        break;
342      case TOK_OBJECT:      case TOK_REGEXP:
343        class = CLASS_REGEXP;        class = CLASS_REGEXP;
344        token_stream->flags &= ~TSF_OPERAND;        token_stream.flags &= ~TSF_OPERAND;
345        break;        break;
346      case TOK_PRIMARY:      case TOK_PRIMARY:
347        switch (t.t_op) {        switch (t.t_op) {
# Line 387  Line 350 
350        case JSOP_NULL:        case JSOP_NULL:
351        case JSOP_THIS:        case JSOP_THIS:
352          class = CLASS_KEYWORD;          class = CLASS_KEYWORD;
353          token_stream->flags &= ~TSF_OPERAND;          token_stream.flags &= ~TSF_OPERAND;
354          break;          break;
355        default:        default:
356          abort();          abort();
# Line 395  Line 358 
358        break;        break;
359      case TOK_FUNCTION:      case TOK_FUNCTION:
360        class = CLASS_KEYWORD;        class = CLASS_KEYWORD;
361        token_stream->flags |= TSF_OPERAND;        token_stream.flags |= TSF_OPERAND;
       break;  
     case TOK_EXPORT:  
     case TOK_IMPORT:  
       abort();  
362        break;        break;
363      case TOK_IF:      case TOK_IF:
364      case TOK_ELSE:      case TOK_ELSE:
# Line 417  Line 376 
376      case TOK_RETURN:      case TOK_RETURN:
377      case TOK_NEW:      case TOK_NEW:
378      case TOK_DELETE:      case TOK_DELETE:
379        token_stream->flags |= TSF_OPERAND;        token_stream.flags |= TSF_OPERAND;
380        class = CLASS_KEYWORD;        class = CLASS_KEYWORD;
381        break;        break;
382      case TOK_DEFSHARP:      case TOK_DEFSHARP:
# Line 430  Line 389 
389      case TOK_THROW:      case TOK_THROW:
390      case TOK_INSTANCEOF:      case TOK_INSTANCEOF:
391      case TOK_DEBUGGER:      case TOK_DEBUGGER:
392        token_stream->flags |= TSF_OPERAND;        token_stream.flags |= TSF_OPERAND;
393        class = CLASS_KEYWORD;        class = CLASS_KEYWORD;
394        break;        break;
395      case TOK_XMLSTAGO:      case TOK_XMLSTAGO:
# Line 451  Line 410 
410      case TOK_FILTER:      case TOK_FILTER:
411      case TOK_XMLELEM:      case TOK_XMLELEM:
412      case TOK_XMLLIST:      case TOK_XMLLIST:
413          abort();
414          break;
415        case TOK_YIELD:
416          token_stream.flags |= TSF_OPERAND;
417          class = CLASS_KEYWORD;
418          break;
419        case TOK_ARRAYCOMP:
420        case TOK_ARRAYPUSH:
421        case TOK_LEXICALSCOPE:
422          abort();
423          break;
424        case TOK_LET:
425          token_stream.flags |= TSF_OPERAND;
426          class = CLASS_KEYWORD;
427          break;
428        case TOK_SEQ:
429        case TOK_FORHEAD:
430      case TOK_RESERVED:      case TOK_RESERVED:
431      case TOK_LIMIT:      case TOK_LIMIT:
432        abort();        abort();
# Line 460  Line 436 
436        break;        break;
437      }      }
438    
439      assert(t.pos.begin.lineno == t.pos.end.lineno);      uint16_t start_line = t.pos.begin.lineno;
440      if (t.pos.begin.index > t.pos.end.index) {      uint16_t end_line = t.pos.end.lineno;
441        uint16_t start_column = t.pos.begin.index;
442        uint16_t end_column = t.pos.end.index;
443        assert(line_num == start_line);
444        assert(column_num == start_column);
445        if (start_line == end_line && start_column >= end_column) {
446        fatal("%s: script contains line with more than 65,535 characters", id);        fatal("%s: script contains line with more than 65,535 characters", id);
447      }      }
448      for (uint16_t i = t.pos.begin.index; i < t.pos.end.index; i++) {      for (;;) {
449        assert(character_offset < num_characters);        assert(character_offset < num_characters);
450        jschar c = characters[character_offset];        jschar c = characters[character_offset];
451        if (tt == TOK_STRING && c == '\\') {        if (tt == TOK_STRING && c == '\\') {
452          output_character(c, CLASS_SPECIALCHAR);          output_character(c, CLASS_SPECIALCHAR);
         character_offset++;  
         i++;  
453          assert(character_offset < num_characters);          assert(character_offset < num_characters);
454          c = characters[character_offset];          c = characters[character_offset];
455          output_character(c, CLASS_SPECIALCHAR);          output_character(c, CLASS_SPECIALCHAR);
         character_offset++;  
456        }        }
457        else {        else {
458          output_character(c, class);          output_character(c, class);
459          character_offset++;        }
460    
461          if (line_num > end_line) {
462            break;
463          }
464          else if (line_num == end_line && column_num >= end_column) {
465            break;
466        }        }
467      }      }
468    
469      line_num = t.pos.end.lineno;      assert(line_num == end_line);
470      column_num = t.pos.end.index;      assert(column_num = end_column);
471    }    }
472    
473    if (current_class != CLASS_NONE) {    if (current_class != CLASS_NONE) {
474      output_character('\n', CLASS_NONE);      output_character('\n', CLASS_NONE);
475    }    }
476    
477    /* cleanup */    js_CloseTokenStream(context, &token_stream);
   JS_UNKEEP_ATOMS(cx->runtime);  
   context->fp = fp;  
478  }  }

Legend:
Removed from v.215  
changed lines
  Added in v.399

  ViewVC Help
Powered by ViewVC 1.1.24