1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 void PrintF(const char* format, ...) {
42 va_start(arguments, format);
43 OS::VPrint(format, arguments);
48 void PrintF(FILE* out, const char* format, ...) {
50 va_start(arguments, format);
51 OS::VFPrint(out, format, arguments);
56 void Flush(FILE* out) {
61 char* ReadLine(const char* prompt) {
65 bool keep_going = true;
66 fprintf(stdout, "%s", prompt);
69 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
70 // fgets got an error. Just give up.
76 int len = StrLength(line_buf);
78 line_buf[len - 2] == '\\' &&
79 line_buf[len - 1] == '\n') {
80 // When we read a line that ends with a "\" we remove the escape and
81 // append the remainder.
82 line_buf[len - 2] = '\n';
83 line_buf[len - 1] = 0;
85 } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
86 // Since we read a new line we are done reading the line. This
87 // will exit the loop after copying this buffer into the result.
91 // Allocate the initial result and make room for the terminating '\0'
92 result = NewArray<char>(len + 1);
94 // Allocate a new result with enough room for the new addition.
95 int new_len = offset + len + 1;
96 char* new_result = NewArray<char>(new_len);
97 // Copy the existing input into the new array and set the new
98 // array as the result.
99 memcpy(new_result, result, offset * kCharSize);
103 // Copy the newly read line into the result.
104 memcpy(result + offset, line_buf, len * kCharSize);
107 ASSERT(result != NULL);
108 result[offset] = '\0';
113 char* ReadCharsFromFile(FILE* file,
117 const char* filename) {
118 if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
120 OS::PrintError("Cannot read from file %s.\n", filename);
125 // Get the size of the file and rewind it.
129 char* result = NewArray<char>(*size + extra_space);
130 for (int i = 0; i < *size && feof(file) == 0;) {
131 int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
132 if (read != (*size - i) && ferror(file) != 0) {
143 char* ReadCharsFromFile(const char* filename,
147 FILE* file = OS::FOpen(filename, "rb");
148 char* result = ReadCharsFromFile(file, size, extra_space, verbose, filename);
149 if (file != NULL) fclose(file);
154 byte* ReadBytes(const char* filename, int* size, bool verbose) {
155 char* chars = ReadCharsFromFile(filename, size, 0, verbose);
156 return reinterpret_cast<byte*>(chars);
160 static Vector<const char> SetVectorContents(char* chars,
165 return Vector<const char>::empty();
169 return Vector<const char>(chars, size);
173 Vector<const char> ReadFile(const char* filename,
177 char* result = ReadCharsFromFile(filename, &size, 1, verbose);
178 return SetVectorContents(result, size, exists);
182 Vector<const char> ReadFile(FILE* file,
186 char* result = ReadCharsFromFile(file, &size, 1, verbose, "");
187 return SetVectorContents(result, size, exists);
191 int WriteCharsToFile(const char* str, int size, FILE* f) {
193 while (total < size) {
194 int write = static_cast<int>(fwrite(str, 1, size - total, f));
205 int AppendChars(const char* filename,
209 FILE* f = OS::FOpen(filename, "ab");
212 OS::PrintError("Cannot open file %s for writing.\n", filename);
216 int written = WriteCharsToFile(str, size, f);
222 int WriteChars(const char* filename,
226 FILE* f = OS::FOpen(filename, "wb");
229 OS::PrintError("Cannot open file %s for writing.\n", filename);
233 int written = WriteCharsToFile(str, size, f);
239 int WriteBytes(const char* filename,
243 const char* str = reinterpret_cast<const char*>(bytes);
244 return WriteChars(filename, str, size, verbose);
249 void StringBuilder::AddFormatted(const char* format, ...) {
251 va_start(arguments, format);
252 AddFormattedList(format, arguments);
257 void StringBuilder::AddFormattedList(const char* format, va_list list) {
258 ASSERT(!is_finalized() && position_ < buffer_.length());
259 int n = OS::VSNPrintF(buffer_ + position_, format, list);
260 if (n < 0 || n >= (buffer_.length() - position_)) {
261 position_ = buffer_.length();
268 MemoryMappedExternalResource::MemoryMappedExternalResource(const char* filename)
272 remove_file_on_cleanup_(false) {
277 MemoryMappedExternalResource::
278 MemoryMappedExternalResource(const char* filename,
279 bool remove_file_on_cleanup)
283 remove_file_on_cleanup_(remove_file_on_cleanup) {
288 MemoryMappedExternalResource::~MemoryMappedExternalResource() {
289 // Release the resources if we had successfully acquired them:
292 if (remove_file_on_cleanup_) {
293 OS::Remove(filename_);
295 DeleteArray<char>(filename_);
300 void MemoryMappedExternalResource::Init(const char* filename) {
301 file_ = OS::MemoryMappedFile::open(filename);
303 filename_ = StrDup(filename);
304 data_ = reinterpret_cast<char*>(file_->memory());
305 length_ = file_->size();
310 bool MemoryMappedExternalResource::EnsureIsAscii(bool abort_if_failed) const {
311 bool is_ascii = true;
314 const char* start_of_line = data_;
315 const char* end = data_ + length_;
316 for (const char* p = data_; p < end; p++) {
318 if ((c & 0x80) != 0) {
319 // Non-ascii detected:
322 // Report the error and abort if appropriate:
323 if (abort_if_failed) {
324 int char_no = static_cast<int>(p - start_of_line) - 1;
326 ASSERT(filename_ != NULL);
328 "Abort: Non-Ascii character 0x%.2x in file %s line %d char %d",
329 c, filename_, line_no, char_no);
331 // Allow for some context up to kNumberOfLeadingContextChars chars
332 // before the offending non-ascii char to help the user see where
333 // the offending char is.
334 const int kNumberOfLeadingContextChars = 10;
335 const char* err_context = p - kNumberOfLeadingContextChars;
336 if (err_context < data_) {
339 // Compute the length of the error context and print it.
340 int err_context_length = static_cast<int>(p - err_context);
341 if (err_context_length != 0) {
342 PrintF(" after \"%.*s\"", err_context_length, err_context);
348 break; // Non-ascii detected. No need to continue scanning.
360 } } // namespace v8::internal