]> git.saurik.com Git - cycript.git/blame - Display.cpp
Fix crash when trying to use specifier without int.
[cycript.git] / Display.cpp
CommitLineData
74296173 1/* Cycript - Optimizing JavaScript Compiler/Runtime
c15969fd 2 * Copyright (C) 2009-2013 Jay Freeman (saurik)
74296173
JF
3*/
4
c15969fd 5/* GNU General Public License, Version 3 {{{ */
74296173 6/*
c15969fd
JF
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.
74296173 11 *
c15969fd
JF
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.
74296173 16 *
c15969fd 17 * You should have received a copy of the GNU General Public License
74296173
JF
18 * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
19**/
20/* }}} */
21
22#include <complex>
23#include <sstream>
24
25#ifdef HAVE_READLINE_H
26#include <readline.h>
27#else
28#include <readline/readline.h>
29#endif
30
daf84f5e
JF
31#if RL_READLINE_VERSION >= 0x0600
32
74296173
JF
33#include <sys/ioctl.h>
34
35#include "Highlight.hpp"
36
37#include <term.h>
38
39typedef std::complex<int> CYCursor;
40
05f619c2 41extern "C" int rl_display_fixed;
daf84f5e
JF
42extern "C" int _rl_vis_botlin;
43extern "C" int _rl_last_c_pos;
44extern "C" int _rl_last_v_pos;
45
74296173
JF
46CYCursor current_;
47int width_;
48size_t point_;
49
74296173
JF
50unsigned CYDisplayWidth() {
51 struct winsize info;
52 if (ioctl(1, TIOCGWINSZ, &info) != -1)
53 return info.ws_col;
54 return tgetnum(const_cast<char *>("co"));
55}
56
57void CYDisplayOutput_(int (*put)(int), const char *&data) {
58 for (;; ++data) {
59 char next(*data);
60 if (next == '\0' || next == CYIgnoreEnd)
61 return;
62 if (put != NULL)
63 put(next);
64 }
65}
66
67CYCursor CYDisplayOutput(int (*put)(int), int width, const char *data, ssize_t offset = 0) {
68 CYCursor point(current_);
69
70 for (;;) {
71 if (offset-- == 0)
72 point = current_;
73
74 char next(*data++);
75 switch (next) {
76 case '\0':
77 return point;
78 break;
79
80 case CYIgnoreStart:
81 CYDisplayOutput_(put, data);
74296173
JF
82 case CYIgnoreEnd:
83 ++offset;
84 break;
85
86 default:
74296173
JF
87 current_ += CYCursor(0, 1);
88 if (current_.imag() == width)
dd059029 89 case '\n':
74296173 90 current_ = CYCursor(current_.real() + 1, 0);
dd059029
JF
91 if (put != NULL)
92 put(next);
74296173 93 break;
dd059029 94
74296173
JF
95 }
96 }
74296173
JF
97}
98
66abbf4d 99void CYDisplayMove_(char *negative, char *positive, int offset) {
74296173 100 if (offset < 0)
66abbf4d 101 putp(tparm(negative, -offset));
74296173 102 else if (offset > 0)
66abbf4d
JF
103 putp(tparm(positive, offset));
104}
105
106void CYDisplayMove(CYCursor target) {
107 CYCursor offset(target - current_);
108
109 CYDisplayMove_(parm_up_cursor, parm_down_cursor, offset.real());
110
111 if (char *parm = tparm(column_address, target.imag()))
112 putp(parm);
113 else
114 CYDisplayMove_(parm_left_cursor, parm_right_cursor, offset.imag());
74296173 115
74296173
JF
116 current_ = target;
117}
118
74296173 119void CYDisplayUpdate() {
05f619c2
JF
120 rl_display_fixed = 1;
121 rl_redisplay();
b68553a0 122 current_ = CYCursor(_rl_last_v_pos, _rl_last_c_pos);
05f619c2 123
7128e55c
JF
124#if RL_READLINE_VERSION >= 0x0600
125 const char *prompt(rl_display_prompt);
126#else
127 const char *prompt(rl_prompt);
128#endif
129
74296173
JF
130 std::ostringstream stream;
131 CYLexerHighlight(rl_line_buffer, rl_end, stream, true);
132 std::string string(stream.str());
133 const char *buffer(string.c_str());
134
135 int width(CYDisplayWidth());
136 if (width_ != width) {
137 current_ = CYCursor();
7128e55c 138 CYDisplayOutput(NULL, width, prompt);
c584b893 139 current_ = CYDisplayOutput(NULL, width, buffer, point_);
74296173
JF
140 }
141
142 CYDisplayMove(CYCursor());
7128e55c 143 CYDisplayOutput(putchar, width, prompt);
74296173 144 CYCursor target(CYDisplayOutput(putchar, width, stream.str().c_str(), rl_point));
74296173 145
daf84f5e 146 _rl_vis_botlin = current_.real();
daf84f5e 147
c6874782
JF
148 if (current_.imag() == 0)
149 CYDisplayOutput(putchar, width, " ");
74296173 150 putp(clr_eos);
74296173 151
c6874782 152 CYDisplayMove(target);
74296173
JF
153 fflush(stdout);
154
b68553a0
JF
155 _rl_last_v_pos = current_.real();
156 _rl_last_c_pos = current_.imag();
157
74296173
JF
158 width_ = width;
159 point_ = rl_point;
160}
161
daf84f5e 162#endif