blob: 7096ba35ab26ea37f9d758050a5ea904fb084440 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 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
4// met:
5//
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.
15//
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.
27
28#include <stdarg.h>
29
30#include "v8.h"
31
32#include "platform.h"
33
34#include "sys/stat.h"
35
36namespace v8 {
37namespace internal {
38
39
Steve Blocka7e24c12009-10-30 11:49:00 +000040void PrintF(const char* format, ...) {
41 va_list arguments;
42 va_start(arguments, format);
43 OS::VPrint(format, arguments);
44 va_end(arguments);
45}
46
47
48void Flush() {
49 fflush(stdout);
50}
51
52
53char* ReadLine(const char* prompt) {
54 char* result = NULL;
55 char line_buf[256];
56 int offset = 0;
57 bool keep_going = true;
58 fprintf(stdout, "%s", prompt);
59 fflush(stdout);
60 while (keep_going) {
61 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
62 // fgets got an error. Just give up.
63 if (result != NULL) {
64 DeleteArray(result);
65 }
66 return NULL;
67 }
Steve Blockd0582a62009-12-15 09:54:21 +000068 int len = StrLength(line_buf);
Steve Blocka7e24c12009-10-30 11:49:00 +000069 if (len > 1 &&
70 line_buf[len - 2] == '\\' &&
71 line_buf[len - 1] == '\n') {
72 // When we read a line that ends with a "\" we remove the escape and
73 // append the remainder.
74 line_buf[len - 2] = '\n';
75 line_buf[len - 1] = 0;
76 len -= 1;
77 } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
78 // Since we read a new line we are done reading the line. This
79 // will exit the loop after copying this buffer into the result.
80 keep_going = false;
81 }
82 if (result == NULL) {
83 // Allocate the initial result and make room for the terminating '\0'
84 result = NewArray<char>(len + 1);
85 } else {
86 // Allocate a new result with enough room for the new addition.
87 int new_len = offset + len + 1;
88 char* new_result = NewArray<char>(new_len);
89 // Copy the existing input into the new array and set the new
90 // array as the result.
91 memcpy(new_result, result, offset * kCharSize);
92 DeleteArray(result);
93 result = new_result;
94 }
95 // Copy the newly read line into the result.
96 memcpy(result + offset, line_buf, len * kCharSize);
97 offset += len;
98 }
99 ASSERT(result != NULL);
100 result[offset] = '\0';
101 return result;
102}
103
104
105char* ReadCharsFromFile(const char* filename,
106 int* size,
107 int extra_space,
108 bool verbose) {
109 FILE* file = OS::FOpen(filename, "rb");
110 if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
111 if (verbose) {
112 OS::PrintError("Cannot read from file %s.\n", filename);
113 }
114 return NULL;
115 }
116
117 // Get the size of the file and rewind it.
118 *size = ftell(file);
119 rewind(file);
120
121 char* result = NewArray<char>(*size + extra_space);
122 for (int i = 0; i < *size;) {
Steve Blockd0582a62009-12-15 09:54:21 +0000123 int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
Steve Blocka7e24c12009-10-30 11:49:00 +0000124 if (read <= 0) {
125 fclose(file);
126 DeleteArray(result);
127 return NULL;
128 }
129 i += read;
130 }
131 fclose(file);
132 return result;
133}
134
135
136byte* ReadBytes(const char* filename, int* size, bool verbose) {
137 char* chars = ReadCharsFromFile(filename, size, 0, verbose);
138 return reinterpret_cast<byte*>(chars);
139}
140
141
142Vector<const char> ReadFile(const char* filename,
143 bool* exists,
144 bool verbose) {
145 int size;
146 char* result = ReadCharsFromFile(filename, &size, 1, verbose);
147 if (!result) {
148 *exists = false;
149 return Vector<const char>::empty();
150 }
151 result[size] = '\0';
152 *exists = true;
153 return Vector<const char>(result, size);
154}
155
156
157int WriteCharsToFile(const char* str, int size, FILE* f) {
158 int total = 0;
159 while (total < size) {
Steve Blockd0582a62009-12-15 09:54:21 +0000160 int write = static_cast<int>(fwrite(str, 1, size - total, f));
Steve Blocka7e24c12009-10-30 11:49:00 +0000161 if (write == 0) {
162 return total;
163 }
164 total += write;
165 str += write;
166 }
167 return total;
168}
169
170
171int WriteChars(const char* filename,
172 const char* str,
173 int size,
174 bool verbose) {
175 FILE* f = OS::FOpen(filename, "wb");
176 if (f == NULL) {
177 if (verbose) {
178 OS::PrintError("Cannot open file %s for writing.\n", filename);
179 }
180 return 0;
181 }
182 int written = WriteCharsToFile(str, size, f);
183 fclose(f);
184 return written;
185}
186
187
188int WriteBytes(const char* filename,
189 const byte* bytes,
190 int size,
191 bool verbose) {
192 const char* str = reinterpret_cast<const char*>(bytes);
193 return WriteChars(filename, str, size, verbose);
194}
195
196
197StringBuilder::StringBuilder(int size) {
198 buffer_ = Vector<char>::New(size);
199 position_ = 0;
200}
201
202
203void StringBuilder::AddString(const char* s) {
Steve Blockd0582a62009-12-15 09:54:21 +0000204 AddSubstring(s, StrLength(s));
Steve Blocka7e24c12009-10-30 11:49:00 +0000205}
206
207
208void StringBuilder::AddSubstring(const char* s, int n) {
209 ASSERT(!is_finalized() && position_ + n < buffer_.length());
210 ASSERT(static_cast<size_t>(n) <= strlen(s));
211 memcpy(&buffer_[position_], s, n * kCharSize);
212 position_ += n;
213}
214
215
216void StringBuilder::AddFormatted(const char* format, ...) {
217 ASSERT(!is_finalized() && position_ < buffer_.length());
218 va_list args;
219 va_start(args, format);
220 int n = OS::VSNPrintF(buffer_ + position_, format, args);
221 va_end(args);
222 if (n < 0 || n >= (buffer_.length() - position_)) {
223 position_ = buffer_.length();
224 } else {
225 position_ += n;
226 }
227}
228
229
230void StringBuilder::AddPadding(char c, int count) {
231 for (int i = 0; i < count; i++) {
232 AddCharacter(c);
233 }
234}
235
236
237char* StringBuilder::Finalize() {
238 ASSERT(!is_finalized() && position_ < buffer_.length());
239 buffer_[position_] = '\0';
240 // Make sure nobody managed to add a 0-character to the
241 // buffer while building the string.
242 ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
243 position_ = -1;
244 ASSERT(is_finalized());
245 return buffer_.start();
246}
247
Steve Blockd0582a62009-12-15 09:54:21 +0000248
Steve Blocka7e24c12009-10-30 11:49:00 +0000249} } // namespace v8::internal