]>
git.saurik.com Git - cycript.git/blob - Library.cpp
   1 /* Cycript - Optimizing JavaScript Compiler/Runtime 
   2  * Copyright (C) 2009-2013  Jay Freeman (saurik) 
   5 /* GNU General Public License, Version 3 {{{ */ 
   7  * Cycript is free software: you can redistribute it and/or modify 
   8  * it under the terms of the GNU General Public License as published 
   9  * by the Free Software Foundation, either version 3 of the License, 
  10  * or (at your option) any later version. 
  12  * Cycript is distributed in the hope that it will be useful, but 
  13  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  * GNU General Public License for more details. 
  17  * You should have received a copy of the GNU General Public License 
  18  * along with Cycript.  If not, see <http://www.gnu.org/licenses/>. 
  24 #include "cycript.hpp" 
  26 #include "Pooling.hpp" 
  38 #include "Execute.hpp" 
  42 #include "Cycript.tab.hh" 
  45 #include "ConvertUTF.h" 
  48 CYUTF8String 
CYPoolUTF8String(CYPool 
&pool
, CYUTF16String utf16
) { 
  50     size_t size(utf16
.size 
* 5); 
  51     char *temp(new(pool
) char[size
]); 
  53     const uint16_t *lhs(utf16
.data
); 
  54     uint8_t *rhs(reinterpret_cast<uint8_t *>(temp
)); 
  55     _assert(ConvertUTF16toUTF8(&lhs
, lhs 
+ utf16
.size
, &rhs
, rhs 
+ size
, lenientConversion
) == conversionOK
); 
  58     return CYUTF8String(temp
, reinterpret_cast<char *>(rhs
) - temp
); 
  61 CYUTF16String 
CYPoolUTF16String(CYPool 
&pool
, CYUTF8String utf8
) { 
  63     size_t size(utf8
.size 
* 5); 
  64     uint16_t *temp(new (pool
) uint16_t[size
]); 
  66     const uint8_t *lhs(reinterpret_cast<const uint8_t *>(utf8
.data
)); 
  68     _assert(ConvertUTF8toUTF16(&lhs
, lhs 
+ utf8
.size
, &rhs
, rhs 
+ size
, lenientConversion
) == conversionOK
); 
  71     return CYUTF16String(temp
, rhs 
- temp
); 
  74 /* Index Offsets {{{ */ 
  75 size_t CYGetIndex(const CYUTF8String 
&value
) { 
  76     if (value
.data
[0] != '0') { 
  78         for (size_t i(0); i 
!= value
.size
; ++i
) { 
  79             if (!DigitRange_
[value
.data
[i
]]) 
  82             index 
+= value
.data
[i
] - '0'; 
  85     } else if (value
.size 
== 1) 
  91 // XXX: this isn't actually right 
  92 bool CYGetOffset(const char *value
, ssize_t 
&index
) { 
  93     if (value
[0] != '0') { 
  95         index 
= strtol(value
, &end
, 10); 
  96         if (value 
+ strlen(value
) == end
) 
  98     } else if (value
[1] == '\0') { 
 106 /* JavaScript *ify {{{ */ 
 107 void CYStringify(std::ostringstream 
&str
, const char *data
, size_t size
) { 
 108     unsigned quot(0), apos(0); 
 109     for (const char *value(data
), *end(data 
+ size
); value 
!= end
; ++value
) 
 112         else if (*value 
== '\'') 
 115     bool single(quot 
> apos
); 
 117     str 
<< (single 
? '\'' : '"'); 
 119     for (const char *value(data
), *end(data 
+ size
); value 
!= end
; ++value
) 
 121             case '\\': str 
<< "\\\\"; break; 
 122             case '\b': str 
<< "\\b"; break; 
 123             case '\f': str 
<< "\\f"; break; 
 124             case '\n': str 
<< "\\n"; break; 
 125             case '\r': str 
<< "\\r"; break; 
 126             case '\t': str 
<< "\\t"; break; 
 127             case '\v': str 
<< "\\v"; break; 
 142                 // this test is designed to be "awesome", generating neither warnings nor incorrect results 
 143                 if (*value 
< 0x20 || *value 
>= 0x7f) 
 144                     str 
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(uint8_t(*value
)); 
 149     str 
<< (single 
? '\'' : '"'); 
 152 void CYNumerify(std::ostringstream 
&str
, double value
) { 
 154     // XXX: I want this to print 1e3 rather than 1000 
 155     sprintf(string
, "%.17g", value
); 
 159 bool CYIsKey(CYUTF8String value
) { 
 160     const char *data(value
.data
); 
 161     size_t size(value
.size
); 
 166     if (DigitRange_
[data
[0]]) { 
 167         size_t index(CYGetIndex(value
)); 
 168         if (index 
== _not(size_t)) 
 171         if (!WordStartRange_
[data
[0]]) 
 173         for (size_t i(1); i 
!= size
; ++i
) 
 174             if (!WordEndRange_
[data
[i
]]) 
 182 double CYCastDouble(const char *value
, size_t size
) { 
 184     double number(strtod(value
, &end
)); 
 185     if (end 
!= value 
+ size
) 
 190 double CYCastDouble(const char *value
) { 
 191     return CYCastDouble(value
, strlen(value
)); 
 194 CYUTF8String 
CYPoolCode(CYPool 
&pool
, std::istream 
&stream
) { 
 196     CYDriver 
driver(stream
); 
 198     cy::parser 
parser(driver
); 
 199     _assert(parser
.parse() == 0); 
 200     _assert(driver
.errors_
.empty()); 
 203     CYContext 
context(options
); 
 204     driver
.program_
->Replace(context
); 
 206     std::ostringstream str
; 
 207     CYOutput 
out(str
, options
); 
 208     out 
<< *driver
.program_
; 
 209     return $pool
.strdup(str
.str().c_str()); 
 212 CYPool 
&CYGetGlobalPool() { 
 217 void CYThrow(const char *format
, ...) { 
 219     va_start(args
, format
); 
 220     throw CYPoolError(format
, args
); 
 221     // XXX: does this matter? :( 
 225 const char *CYPoolError::PoolCString(CYPool 
&pool
) const { 
 226     return pool
.strdup(message_
); 
 229 CYPoolError::CYPoolError(const CYPoolError 
&rhs
) : 
 230     message_(pool_
.strdup(rhs
.message_
)) 
 234 CYPoolError::CYPoolError(const char *format
, ...) { 
 236     va_start(args
, format
); 
 237     // XXX: there might be a beter way to think about this 
 238     message_ 
= pool_
.vsprintf(64, format
, args
); 
 242 CYPoolError::CYPoolError(const char *format
, va_list args
) { 
 243     // XXX: there might be a beter way to think about this 
 244     message_ 
= pool_
.vsprintf(64, format
, args
);