notcurses 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,45 @@
1
+ #include <notcurses/notcurses.h>
2
+ #include <ruby.h>
3
+ #include <stdio.h>
4
+
5
+ int ruby_ncplane_vprintf_yx(struct ncplane* n, int y, int x, const char* format, VALUE rb_args) {
6
+ int argc = RARRAY_LEN(rb_args);
7
+ VALUE* argv = RARRAY_PTR(rb_args);
8
+
9
+ // Create a buffer to hold our formatted string
10
+ char* buffer = NULL;
11
+ size_t buffer_size = 0;
12
+ FILE* memstream = open_memstream(&buffer, &buffer_size);
13
+ if (!memstream) {
14
+ rb_raise(rb_eRuntimeError, "Failed to create memory stream");
15
+ return -1;
16
+ }
17
+
18
+ // Use vfprintf to format our string
19
+ for (int i = 0; i < argc; i++) {
20
+ VALUE arg = argv[i];
21
+ switch (TYPE(arg)) {
22
+ case T_FIXNUM:
23
+ fprintf(memstream, format, NUM2INT(arg));
24
+ break;
25
+ case T_FLOAT:
26
+ fprintf(memstream, format, NUM2DBL(arg));
27
+ break;
28
+ case T_STRING:
29
+ fprintf(memstream, format, StringValueCStr(arg));
30
+ break;
31
+ default:
32
+ fclose(memstream);
33
+ free(buffer);
34
+ rb_raise(rb_eTypeError, "Unsupported argument type");
35
+ return -1;
36
+ }
37
+ }
38
+
39
+ fclose(memstream);
40
+
41
+ int result = ncplane_putstr_yx(n, y, x, buffer);
42
+
43
+ free(buffer);
44
+ return result;
45
+ }
@@ -0,0 +1,282 @@
1
+ %module notcurses
2
+ %include <ruby/rubywstrings.swg>
3
+ %ignore ALLOC;
4
+ %ignore API;
5
+ %ignore __attribute__;
6
+ %ignore __attribute;
7
+ %ignore __declspec;
8
+ %ignore __nonnull;
9
+ %define __attribute__(x)
10
+ %enddef
11
+ %define __attribute(x)
12
+ %enddef
13
+ %define __declspec(x)
14
+ %enddef
15
+ %define __nonnull(x)
16
+ %enddef
17
+ %include <./modified_ruby_std_wstring.i>
18
+
19
+ %include <carrays.i>
20
+ %include <cdata.i>
21
+ %include <cmalloc.i>
22
+ %include <constraints.i>
23
+ %include <cpointer.i>
24
+ %include <cstring.i>
25
+ %include <inttypes.i>
26
+ %include <math.i>
27
+ %include <stdint.i>
28
+ %include <wchar.i>
29
+
30
+ %include <typemaps/attribute.swg>
31
+ %include <typemaps/carrays.swg>
32
+ %include <typemaps/cdata.swg>
33
+ %include <typemaps/cmalloc.swg>
34
+ %include <typemaps/cpointer.swg>
35
+ %include <typemaps/cstrings.swg>
36
+ %include <typemaps/cstring.swg>
37
+ %include <typemaps/cwstring.swg>
38
+ %include <typemaps/enumint.swg>
39
+ %include <typemaps/exception.swg>
40
+ %include <typemaps/factory.swg>
41
+ %include <typemaps/fragments.swg>
42
+ %include <typemaps/implicit.swg>
43
+ %include <typemaps/inoutlist.swg>
44
+ %include <typemaps/misctypes.swg>
45
+ %include <typemaps/primtypes.swg>
46
+ %include <typemaps/ptrtypes.swg>
47
+ %include <typemaps/strings.swg>
48
+ %include <typemaps/string.swg>
49
+ %include <typemaps/swigmacros.swg>
50
+ %include <typemaps/swigobject.swg>
51
+ %include <typemaps/swigtypemaps.swg>
52
+ %include <typemaps/swigtype.swg>
53
+ %include <typemaps/typemaps.swg>
54
+ %include <typemaps/valtypes.swg>
55
+ %include <typemaps/void.swg>
56
+ %include <typemaps/wstring.swg>
57
+
58
+ %include <ruby/argcargv.i>
59
+ %include <ruby/rubyautodoc.swg>
60
+ %include <ruby/file.i>
61
+ %include <ruby/progargcargv.i>
62
+ %include <ruby/rubycomplex.swg>
63
+ %include <ruby/rubykw.swg>
64
+ %include <ruby/rubymacros.swg>
65
+ %include <ruby/rubyprimtypes.swg>
66
+ %include <ruby/rubystrings.swg>
67
+ %include <ruby/timeval.i>
68
+ %include <ruby/typemaps.i>
69
+
70
+ // IO
71
+ %{
72
+ #include <fcntl.h>
73
+ #include <unistd.h>
74
+
75
+ // Helper function to determine file mode
76
+ static const char* get_file_mode(int fd) {
77
+ int flags = fcntl(fd, F_GETFL);
78
+ if (flags == -1) return "r"; // Default to read mode on error
79
+
80
+ int access_mode = flags & O_ACCMODE;
81
+ int append_flag = flags & O_APPEND;
82
+
83
+ if (access_mode == O_RDONLY) return "r";
84
+ if (access_mode == O_WRONLY) return append_flag ? "a" : "w";
85
+ if (access_mode == O_RDWR) return append_flag ? "a+" : "r+";
86
+
87
+ return "r";
88
+ }
89
+ %}
90
+
91
+ %typemap(in) FILE* {
92
+ if ($input == Qnil) {
93
+ $1 = NULL;
94
+ } else if (rb_respond_to($input, rb_intern("fileno"))) {
95
+ int fd = NUM2INT(rb_funcall($input, rb_intern("fileno"), 0));
96
+ const char* mode = get_file_mode(fd);
97
+ $1 = fdopen(dup(fd), mode);
98
+ if (!$1) {
99
+ rb_raise(rb_eIOError, "Unable to get FILE* from Ruby IO object");
100
+ }
101
+ } else {
102
+ SWIG_exception(SWIG_TypeError, "Expected IO object or nil");
103
+ }
104
+ }
105
+
106
+ %typemap(out) FILE* {
107
+ if ($1 == NULL) {
108
+ $result = Qnil;
109
+ } else {
110
+ int fd = fileno($1);
111
+ if (fd == -1) {
112
+ rb_raise(rb_eIOError, "Invalid file descriptor");
113
+ }
114
+ VALUE io_class = rb_const_get(rb_cObject, rb_intern("IO"));
115
+ $result = rb_funcall(io_class, rb_intern("for_fd"), 1, INT2NUM(fd));
116
+ rb_funcall($result, rb_intern("binmode"), 0);
117
+ }
118
+ }
119
+
120
+
121
+ %typemap(argout) FILE** {
122
+ if (*$1 != NULL) {
123
+ int fd = fileno(*$1);
124
+ if (fd == -1) {
125
+ rb_raise(rb_eIOError, "Invalid file descriptor");
126
+ }
127
+ VALUE io_class = rb_const_get(rb_cObject, rb_intern("IO"));
128
+ VALUE io_obj = rb_funcall(io_class, rb_intern("for_fd"), 1, INT2NUM(fd));
129
+
130
+ // Set the mode of the IO object
131
+ const char* mode = "r"; // Default to read mode
132
+ if ((*$1)->_flags & _IO_NO_READS) {
133
+ if ((*$1)->_flags & _IO_APPEND) {
134
+ mode = "a";
135
+ } else {
136
+ mode = "w";
137
+ }
138
+ }
139
+ if (!((*$1)->_flags & _IO_NO_WRITES)) {
140
+ mode = (strcmp(mode, "r") == 0) ? "r+" : "w+";
141
+ }
142
+
143
+ // Set the mode
144
+ rb_funcall(io_obj, rb_intern("set_encoding"), 1, rb_str_new2(mode));
145
+
146
+ // Preserve the original encoding if possible
147
+ VALUE enc = rb_funcall(io_obj, rb_intern("internal_encoding"), 0);
148
+ if (enc == Qnil) {
149
+ enc = rb_funcall(io_obj, rb_intern("external_encoding"), 0);
150
+ }
151
+ if (enc != Qnil) {
152
+ rb_funcall(io_obj, rb_intern("set_encoding"), 1, enc);
153
+ } else {
154
+ // Fallback to binary mode if no encoding is detected
155
+ rb_funcall(io_obj, rb_intern("binmode"), 0);
156
+ }
157
+
158
+ rb_io_taint_check(io_obj);
159
+
160
+ $result = io_obj;
161
+ } else {
162
+ $result = Qnil;
163
+ }
164
+ }
165
+
166
+ %typemap(in) FILE** (FILE* tempfile = NULL) {
167
+ if ($input == Qnil) {
168
+ $1 = &tempfile;
169
+ } else if (rb_obj_is_kind_of($input, rb_cIO)) {
170
+ VALUE fileno = rb_funcall($input, rb_intern("fileno"), 0);
171
+ int fd = NUM2INT(fileno);
172
+ const char* mode = StringValueCStr(rb_funcall($input, rb_intern("mode"), 0));
173
+ tempfile = fdopen(dup(fd), mode);
174
+ if (!tempfile) {
175
+ rb_raise(rb_eIOError, "Could not create FILE* from Ruby IO object");
176
+ }
177
+ $1 = &tempfile;
178
+ } else {
179
+ SWIG_exception(SWIG_TypeError, "Expected IO object or nil");
180
+ }
181
+ }
182
+
183
+ %typemap(freearg) FILE** {
184
+ if (tempfile$argnum != NULL) {
185
+ fclose(tempfile$argnum);
186
+ }
187
+ }
188
+
189
+ // Integer Pointers
190
+ %typemap(in) int* (int temp) {
191
+ temp = NUM2INT($input);
192
+ $1 = &temp;
193
+ }
194
+
195
+ %typemap(in) unsigned int* (unsigned int temp) {
196
+ temp = NUM2UINT($input);
197
+ $1 = &temp;
198
+ }
199
+
200
+ %typemap(in) long* (long temp) {
201
+ temp = NUM2LONG($input);
202
+ $1 = &temp;
203
+ }
204
+
205
+ %typemap(in) unsigned long* (unsigned long temp) {
206
+ temp = NUM2ULONG($input);
207
+ $1 = &temp;
208
+ }
209
+
210
+ %typemap(in) short* (short temp) {
211
+ temp = NUM2SHORT($input);
212
+ $1 = &temp;
213
+ }
214
+
215
+ %typemap(in) unsigned short* (unsigned short temp) {
216
+ temp = NUM2USHORT($input);
217
+ $1 = &temp;
218
+ }
219
+
220
+ //%typemap(in) char* (char temp) {
221
+ // temp = NUM2CHR($input);
222
+ // $1 = &temp;
223
+ //}
224
+
225
+ %typemap(in) unsigned char* (unsigned char temp) {
226
+ temp = NUM2CHR($input);
227
+ $1 = &temp;
228
+ }
229
+
230
+ %typemap(in) int64_t* (int64_t temp) {
231
+ temp = NUM2LL($input);
232
+ $1 = &temp;
233
+ }
234
+
235
+ %typemap(in) uint64_t* (uint64_t temp) {
236
+ temp = NUM2ULL($input);
237
+ $1 = &temp;
238
+ }
239
+
240
+ %typemap(argout) int*, unsigned int*, long*, unsigned long*, short*, unsigned short*, char*, unsigned char*, int64_t*, uint64_t* {
241
+ if ($1 != NULL) {
242
+ $result = INT2NUM(*$1);
243
+ }
244
+ }
245
+
246
+ %{
247
+ #include "version.h"
248
+ #include "nckeys.h"
249
+ #include "ncseqs.h"
250
+ #include "direct.h"
251
+ #include "notcurses.h"
252
+
253
+ int ruby_ncplane_vprintf_yx(struct ncplane* n, int y, int x, const char* format, VALUE rb_args);
254
+ int ruby_ncplane_vprintf_aligned(struct ncplane* n, int y, ncalign_e align, const char* format, VALUE rb_args);
255
+ int ruby_ncplane_vprintf_stained(struct ncplane* n, const char* format, VALUE rb_args);
256
+
257
+ int ruby_ncplane_vprintf(struct ncplane* n, const char* format, VALUE rb_args) {
258
+ return ruby_ncplane_vprintf_yx(n, -1, -1, format, rb_args);
259
+ }
260
+ %}
261
+
262
+ // Ignore problematic functions
263
+ %ignore ncplane_vprintf_yx;
264
+ %ignore ncplane_vprintf;
265
+ %ignore ncplane_vprintf_aligned;
266
+ %ignore ncplane_vprintf_stained;
267
+
268
+ %include "version.h"
269
+ %include "nckeys.h"
270
+ %include "ncseqs.h"
271
+ %include "direct.h"
272
+ %include "notcurses.h"
273
+
274
+ %rename("ncplane_vprintf_yx") ruby_ncplane_vprintf_yx;
275
+ %rename("ncplane_vprintf_aligned") ruby_ncplane_vprintf_aligned;
276
+ %rename("ncplane_vprintf_stained") ruby_ncplane_vprintf_stained;
277
+ %rename("ncplane_vprintf") ruby_ncplane_vprintf;
278
+
279
+ int ruby_ncplane_vprintf_yx(struct ncplane* n, int y, int x, const char* format, VALUE rb_args);
280
+ int ruby_ncplane_vprintf_aligned(struct ncplane* n, int y, ncalign_e align, const char* format, VALUE rb_args);
281
+ int ruby_ncplane_vprintf_stained(struct ncplane* n, const char* format, VALUE rb_args);
282
+ int ruby_ncplane_vprintf(struct ncplane* n, const char* format, VALUE rb_args);