]> git.saurik.com Git - cycript.git/blame_incremental - Library.cpp
Use -Wl,dead_strip to cut a little readline cruft.
[cycript.git] / Library.cpp
... / ...
CommitLineData
1/* Cycript - The Truly Universal Scripting Language
2 * Copyright (C) 2009-2016 Jay Freeman (saurik)
3*/
4
5/* GNU Affero General Public License, Version 3 {{{ */
6/*
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19**/
20/* }}} */
21
22#include "cycript.hpp"
23
24#include <iostream>
25#include <set>
26#include <map>
27#include <sstream>
28
29#include <dlfcn.h>
30
31#include <sys/mman.h>
32
33#include "Code.hpp"
34#include "ConvertUTF.h"
35#include "Driver.hpp"
36#include "Error.hpp"
37#include "Execute.hpp"
38#include "Pooling.hpp"
39#include "String.hpp"
40#include "Syntax.hpp"
41
42/* C Strings {{{ */
43CYUTF8String CYPoolUTF8String(CYPool &pool, CYUTF16String utf16) {
44 // XXX: this is wrong
45 size_t size(utf16.size * 5);
46 char *temp(new(pool) char[size + 1]);
47
48 const uint16_t *lhs(utf16.data);
49 uint8_t *rhs(reinterpret_cast<uint8_t *>(temp));
50 _assert(ConvertUTF16toUTF8(&lhs, lhs + utf16.size, &rhs, rhs + size, lenientConversion) == conversionOK);
51
52 *rhs = 0;
53 return CYUTF8String(temp, reinterpret_cast<char *>(rhs) - temp);
54}
55
56CYUTF16String CYPoolUTF16String(CYPool &pool, CYUTF8String utf8) {
57 // XXX: this is wrong
58 size_t size(utf8.size * 5);
59 uint16_t *temp(new (pool) uint16_t[size + 1]);
60
61 const uint8_t *lhs(reinterpret_cast<const uint8_t *>(utf8.data));
62 uint16_t *rhs(temp);
63 _assert(ConvertUTF8toUTF16(&lhs, lhs + utf8.size, &rhs, rhs + size, lenientConversion) == conversionOK);
64
65 *rhs = 0;
66 return CYUTF16String(temp, rhs - temp);
67}
68/* }}} */
69/* Index Offsets {{{ */
70size_t CYGetIndex(const CYUTF8String &value) {
71 if (value.data[0] != '0') {
72 size_t index(0);
73 for (size_t i(0); i != value.size; ++i) {
74 if (!DigitRange_[value.data[i]])
75 return _not(size_t);
76 index *= 10;
77 index += value.data[i] - '0';
78 }
79 return index;
80 } else if (value.size == 1)
81 return 0;
82 else
83 return _not(size_t);
84}
85
86// XXX: this isn't actually right
87bool CYGetOffset(const char *value, ssize_t &index) {
88 if (value[0] != '0') {
89 char *end;
90 index = strtol(value, &end, 10);
91 if (value + strlen(value) == end)
92 return true;
93 } else if (value[1] == '\0') {
94 index = 0;
95 return true;
96 }
97
98 return false;
99}
100/* }}} */
101
102bool CYIsKey(CYUTF8String value) {
103 const char *data(value.data);
104 size_t size(value.size);
105
106 if (size == 0)
107 return false;
108
109 if (DigitRange_[data[0]]) {
110 size_t index(CYGetIndex(value));
111 if (index == _not(size_t))
112 return false;
113 } else {
114 if (!WordStartRange_[data[0]])
115 return false;
116 for (size_t i(1); i != size; ++i)
117 if (!WordEndRange_[data[i]])
118 return false;
119 }
120
121 return true;
122}
123
124_visible bool CYStartsWith(const CYUTF8String &haystack, const CYUTF8String &needle) {
125 return haystack.size >= needle.size && strncmp(haystack.data, needle.data, needle.size) == 0;
126}
127
128CYUTF8String CYPoolCode(CYPool &pool, std::streambuf &stream) {
129 CYLocalPool local;
130 CYDriver driver(local, stream);
131
132 if (driver.Parse()) {
133 if (!driver.errors_.empty())
134 CYThrow("%s", driver.errors_.front().message_.c_str());
135 CYThrow("syntax error");
136 }
137
138 CYOptions options;
139 CYContext context(options);
140 driver.script_->Replace(context);
141
142 std::stringbuf str;
143 CYOutput out(str, options);
144 out << *driver.script_;
145 return pool.strdup(str.str().c_str());
146}
147
148CYUTF8String CYPoolCode(CYPool &pool, CYUTF8String code) {
149 CYStream stream(code.data, code.data + code.size);
150 return CYPoolCode(pool, stream);
151}
152
153CYPool &CYGetGlobalPool() {
154 static CYPool pool;
155 return pool;
156}