Home | History | Annotate | Download | only in src
      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
      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 
     36 namespace v8 {
     37 namespace internal {
     38 
     39 
     40 void 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 
     48 void PrintF(FILE* out, const char* format, ...) {
     49   va_list arguments;
     50   va_start(arguments, format);
     51   OS::VFPrint(out, format, arguments);
     52   va_end(arguments);
     53 }
     54 
     55 
     56 void PrintPID(const char* format, ...) {
     57   OS::Print("[%d] ", OS::GetCurrentProcessId());
     58   va_list arguments;
     59   va_start(arguments, format);
     60   OS::VPrint(format, arguments);
     61   va_end(arguments);
     62 }
     63 
     64 
     65 void Flush(FILE* out) {
     66   fflush(out);
     67 }
     68 
     69 
     70 char* ReadLine(const char* prompt) {
     71   char* result = NULL;
     72   char line_buf[256];
     73   int offset = 0;
     74   bool keep_going = true;
     75   fprintf(stdout, "%s", prompt);
     76   fflush(stdout);
     77   while (keep_going) {
     78     if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
     79       // fgets got an error. Just give up.
     80       if (result != NULL) {
     81         DeleteArray(result);
     82       }
     83       return NULL;
     84     }
     85     int len = StrLength(line_buf);
     86     if (len > 1 &&
     87         line_buf[len - 2] == '\\' &&
     88         line_buf[len - 1] == '\n') {
     89       // When we read a line that ends with a "\" we remove the escape and
     90       // append the remainder.
     91       line_buf[len - 2] = '\n';
     92       line_buf[len - 1] = 0;
     93       len -= 1;
     94     } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
     95       // Since we read a new line we are done reading the line. This
     96       // will exit the loop after copying this buffer into the result.
     97       keep_going = false;
     98     }
     99     if (result == NULL) {
    100       // Allocate the initial result and make room for the terminating '\0'
    101       result = NewArray<char>(len + 1);
    102     } else {
    103       // Allocate a new result with enough room for the new addition.
    104       int new_len = offset + len + 1;
    105       char* new_result = NewArray<char>(new_len);
    106       // Copy the existing input into the new array and set the new
    107       // array as the result.
    108       OS::MemCopy(new_result, result, offset * kCharSize);
    109       DeleteArray(result);
    110       result = new_result;
    111     }
    112     // Copy the newly read line into the result.
    113     OS::MemCopy(result + offset, line_buf, len * kCharSize);
    114     offset += len;
    115   }
    116   ASSERT(result != NULL);
    117   result[offset] = '\0';
    118   return result;
    119 }
    120 
    121 
    122 char* ReadCharsFromFile(FILE* file,
    123                         int* size,
    124                         int extra_space,
    125                         bool verbose,
    126                         const char* filename) {
    127   if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
    128     if (verbose) {
    129       OS::PrintError("Cannot read from file %s.\n", filename);
    130     }
    131     return NULL;
    132   }
    133 
    134   // Get the size of the file and rewind it.
    135   *size = ftell(file);
    136   rewind(file);
    137 
    138   char* result = NewArray<char>(*size + extra_space);
    139   for (int i = 0; i < *size && feof(file) == 0;) {
    140     int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
    141     if (read != (*size - i) && ferror(file) != 0) {
    142       fclose(file);
    143       DeleteArray(result);
    144       return NULL;
    145     }
    146     i += read;
    147   }
    148   return result;
    149 }
    150 
    151 
    152 char* ReadCharsFromFile(const char* filename,
    153                         int* size,
    154                         int extra_space,
    155                         bool verbose) {
    156   FILE* file = OS::FOpen(filename, "rb");
    157   char* result = ReadCharsFromFile(file, size, extra_space, verbose, filename);
    158   if (file != NULL) fclose(file);
    159   return result;
    160 }
    161 
    162 
    163 byte* ReadBytes(const char* filename, int* size, bool verbose) {
    164   char* chars = ReadCharsFromFile(filename, size, 0, verbose);
    165   return reinterpret_cast<byte*>(chars);
    166 }
    167 
    168 
    169 static Vector<const char> SetVectorContents(char* chars,
    170                                             int size,
    171                                             bool* exists) {
    172   if (!chars) {
    173     *exists = false;
    174     return Vector<const char>::empty();
    175   }
    176   chars[size] = '\0';
    177   *exists = true;
    178   return Vector<const char>(chars, size);
    179 }
    180 
    181 
    182 Vector<const char> ReadFile(const char* filename,
    183                             bool* exists,
    184                             bool verbose) {
    185   int size;
    186   char* result = ReadCharsFromFile(filename, &size, 1, verbose);
    187   return SetVectorContents(result, size, exists);
    188 }
    189 
    190 
    191 Vector<const char> ReadFile(FILE* file,
    192                             bool* exists,
    193                             bool verbose) {
    194   int size;
    195   char* result = ReadCharsFromFile(file, &size, 1, verbose, "");
    196   return SetVectorContents(result, size, exists);
    197 }
    198 
    199 
    200 int WriteCharsToFile(const char* str, int size, FILE* f) {
    201   int total = 0;
    202   while (total < size) {
    203     int write = static_cast<int>(fwrite(str, 1, size - total, f));
    204     if (write == 0) {
    205       return total;
    206     }
    207     total += write;
    208     str += write;
    209   }
    210   return total;
    211 }
    212 
    213 
    214 int AppendChars(const char* filename,
    215                 const char* str,
    216                 int size,
    217                 bool verbose) {
    218   FILE* f = OS::FOpen(filename, "ab");
    219   if (f == NULL) {
    220     if (verbose) {
    221       OS::PrintError("Cannot open file %s for writing.\n", filename);
    222     }
    223     return 0;
    224   }
    225   int written = WriteCharsToFile(str, size, f);
    226   fclose(f);
    227   return written;
    228 }
    229 
    230 
    231 int WriteChars(const char* filename,
    232                const char* str,
    233                int size,
    234                bool verbose) {
    235   FILE* f = OS::FOpen(filename, "wb");
    236   if (f == NULL) {
    237     if (verbose) {
    238       OS::PrintError("Cannot open file %s for writing.\n", filename);
    239     }
    240     return 0;
    241   }
    242   int written = WriteCharsToFile(str, size, f);
    243   fclose(f);
    244   return written;
    245 }
    246 
    247 
    248 int WriteBytes(const char* filename,
    249                const byte* bytes,
    250                int size,
    251                bool verbose) {
    252   const char* str = reinterpret_cast<const char*>(bytes);
    253   return WriteChars(filename, str, size, verbose);
    254 }
    255 
    256 
    257 
    258 void StringBuilder::AddFormatted(const char* format, ...) {
    259   va_list arguments;
    260   va_start(arguments, format);
    261   AddFormattedList(format, arguments);
    262   va_end(arguments);
    263 }
    264 
    265 
    266 void StringBuilder::AddFormattedList(const char* format, va_list list) {
    267   ASSERT(!is_finalized() && position_ <= buffer_.length());
    268   int n = OS::VSNPrintF(buffer_ + position_, format, list);
    269   if (n < 0 || n >= (buffer_.length() - position_)) {
    270     position_ = buffer_.length();
    271   } else {
    272     position_ += n;
    273   }
    274 }
    275 
    276 } }  // namespace v8::internal
    277