34 |
#include <jsscope.h> |
#include <jsscope.h> |
35 |
#include <jsstr.h> |
#include <jsstr.h> |
36 |
|
|
37 |
|
#include "encoding.h" |
38 |
#include "resource-manager.h" |
#include "resource-manager.h" |
39 |
#include "util.h" |
#include "util.h" |
40 |
|
|
76 |
} |
} |
77 |
|
|
78 |
static void print_string(JSString * s, Stream * f) { |
static void print_string(JSString * s, Stream * f) { |
79 |
for (size_t i = 0; i < s->length; i++) { |
size_t length = JSSTRING_LENGTH(s); |
80 |
char c = s->chars[i]; |
jschar * characters = JSSTRING_CHARS(s); |
81 |
Stream_write_char(f, c); |
for (size_t i = 0; i < length; i++) { |
82 |
|
jschar c = characters[i]; |
83 |
|
if (32 <= c && c <= 126) { |
84 |
|
switch (c) { |
85 |
|
case '"': |
86 |
|
Stream_write_string(f, "\\\""); |
87 |
|
break; |
88 |
|
/* |
89 |
|
case '\'': |
90 |
|
Stream_write_string(f, "\\'"); |
91 |
|
break; |
92 |
|
*/ |
93 |
|
case '\\': |
94 |
|
Stream_write_string(f, "\\\\"); |
95 |
|
break; |
96 |
|
default: |
97 |
|
Stream_write_char(f, c); |
98 |
|
break; |
99 |
|
} |
100 |
|
} |
101 |
|
else { |
102 |
|
switch (c) { |
103 |
|
case 0x8: |
104 |
|
Stream_write_string(f, "\\b"); |
105 |
|
break; |
106 |
|
case 0x9: |
107 |
|
Stream_write_string(f, "\\t"); |
108 |
|
break; |
109 |
|
case 0xa: |
110 |
|
Stream_write_string(f, "\\n"); |
111 |
|
break; |
112 |
|
case 0xb: |
113 |
|
Stream_write_string(f, "\\v"); |
114 |
|
break; |
115 |
|
case 0xc: |
116 |
|
Stream_write_string(f, "\\f"); |
117 |
|
break; |
118 |
|
case 0xd: |
119 |
|
Stream_write_string(f, "\\r"); |
120 |
|
break; |
121 |
|
default: |
122 |
|
Stream_printf(f, "\\u%04x", c); |
123 |
|
break; |
124 |
|
} |
125 |
|
} |
126 |
} |
} |
127 |
} |
} |
128 |
|
|
132 |
print_string(s, f); |
print_string(s, f); |
133 |
} |
} |
134 |
|
|
135 |
static void print_string_jsval(jsval value, Stream * f) { |
static void print_regex(jsval value, Stream * f) { |
136 |
assert(JSVAL_IS_STRING(value)); |
assert(JSVAL_IS_STRING(value)); |
137 |
JSString * s = JSVAL_TO_STRING(value); |
JSString * s = JSVAL_TO_STRING(value); |
138 |
print_string(s, f); |
size_t length = JSSTRING_LENGTH(s); |
139 |
|
jschar * characters = JSSTRING_CHARS(s); |
140 |
|
for (size_t i = 0; i < length; i++) { |
141 |
|
jschar c = characters[i]; |
142 |
|
if (32 <= c && c <= 126) { |
143 |
|
Stream_write_char(f, c); |
144 |
|
} |
145 |
|
else { |
146 |
|
Stream_printf(f, "\\u%04x", c); |
147 |
|
} |
148 |
|
} |
149 |
} |
} |
150 |
|
|
151 |
static void print_quoted_string_atom(JSAtom * atom, Stream * f) { |
static void print_quoted_string_atom(JSAtom * atom, Stream * f) { |
152 |
assert(ATOM_IS_STRING(atom)); |
assert(ATOM_IS_STRING(atom)); |
153 |
JSString * s = ATOM_TO_STRING(atom); |
JSString * s = ATOM_TO_STRING(atom); |
154 |
JSString * quoted = js_QuoteString(context, s, '"'); |
Stream_write_char(f, '"'); |
155 |
print_string(quoted, f); |
print_string(s, f); |
156 |
|
Stream_write_char(f, '"'); |
157 |
} |
} |
158 |
|
|
159 |
static const char * get_op(uint8 op) { |
static const char * get_op(uint8 op) { |
543 |
JSObject * object = ATOM_TO_OBJECT(node->pn_atom); |
JSObject * object = ATOM_TO_OBJECT(node->pn_atom); |
544 |
jsval result; |
jsval result; |
545 |
js_regexp_toString(context, object, 0, NULL, &result); |
js_regexp_toString(context, object, 0, NULL, &result); |
546 |
print_string_jsval(result, f); |
print_regex(result, f); |
547 |
} |
} |
548 |
break; |
break; |
549 |
default: |
default: |
883 |
output_statement(node, f, indent); |
output_statement(node, f, indent); |
884 |
} |
} |
885 |
|
|
886 |
void jscoverage_instrument_js(const char * id, Stream * input, Stream * output) { |
void jscoverage_instrument_js(const char * id, const char * encoding, Stream * input, Stream * output) { |
887 |
file_id = id; |
file_id = id; |
888 |
|
|
889 |
/* scan the javascript */ |
/* scan the javascript */ |
890 |
size_t input_length = input->length; |
size_t input_length = input->length; |
891 |
jschar * base = js_InflateString(context, (char *) input->data, &input_length); |
jschar * base = NULL; |
892 |
if (base == NULL) { |
int result = jscoverage_bytes_to_characters(encoding, input->data, input->length, &base, &input_length); |
893 |
fatal("out of memory"); |
if (result == JSCOVERAGE_ERROR_ENCODING_NOT_SUPPORTED) { |
894 |
|
fatal("encoding %s not supported in file %s", encoding, id); |
895 |
|
} |
896 |
|
else if (result == JSCOVERAGE_ERROR_INVALID_BYTE_SEQUENCE) { |
897 |
|
fatal("error decoding %s in file %s", encoding, id); |
898 |
} |
} |
899 |
JSTokenStream * token_stream = js_NewTokenStream(context, base, input_length, NULL, 1, NULL); |
JSTokenStream * token_stream = js_NewTokenStream(context, base, input_length, NULL, 1, NULL); |
900 |
if (token_stream == NULL) { |
if (token_stream == NULL) { |