cgen 0.16.0 → 0.16.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/README.txt +58 -17
- data/examples/complex.rb +0 -2
- data/examples/complex2.rb +0 -2
- data/examples/matrix.rb +0 -2
- data/examples/sample.rb +0 -24
- data/examples/test.rb +0 -0
- data/lib/cgen/attribute.rb +1 -1
- data/lib/cgen/cgen.rb +341 -369
- data/lib/cgen/cshadow.rb +4 -6
- metadata +1 -1
data/.gitignore
CHANGED
data/README.txt
CHANGED
@@ -1,34 +1,75 @@
|
|
1
|
+
= Overview
|
1
2
|
|
2
|
-
|
3
|
+
Ruby has a C interface for defining extensions to the language. Using this interface, you define functions in C and add them as methods that are callable from ruby code. You may also define classes, modules, globals, and so on.
|
3
4
|
|
4
|
-
|
5
|
+
CGen is a library that makes it relatively easy to code, build, and load extensions from within a ruby program, rather than using a typical C development process. In this way, the construction of the extension is driven by the ruby program. The extension is also available for execution from the program. CGen is a kind of "inline" tool.
|
5
6
|
|
6
|
-
|
7
|
+
The CShadow module is for the special case of T_DATA objects, particularly those whose data is defined by a C struct. A class of such objects can be defined only through the ruby C API. Unlike normal ruby objects such as arrays and strings, a T_DATA object contains a "blob" of data that can only be accessed through methods defined in a C extension.
|
7
8
|
|
8
|
-
|
9
|
+
Including the CShadow module in a class lets you define the structure of the data blob by using simple attribute declarations (no C code needed). CShadow uses these declarations to generate the essential functions: accessors with type conversion and checking, mark/free, marshal, yaml, and initialization. Additional methods can be defined in ruby or using CGenerator. CShadow also manages inheritance of the structure from parent class to child class; the child class may define further attributes.
|
9
10
|
|
10
|
-
|
11
|
+
See the CGenerator, CShadow, and CShadow::Attribute pages for details.
|
11
12
|
|
12
|
-
|
13
|
+
= Purpose and history
|
13
14
|
|
14
|
-
|
15
|
+
The intended use of cgen is managing a complex library that may change from one run of the program to the next. The reason for the change might be that the program is written in a DSL (domain-specific language), and that the library functions are generated based on the statements of the DSL.
|
15
16
|
|
16
|
-
|
17
|
+
In fact, the original use of cgen was to support a DSL for designing and simulating dynamic networks of hybrid automata.[RedShift, formerly hosted at redshift.sourceforge.net, now at http://rubyforge.org/projects/redshift]
|
17
18
|
|
19
|
+
Cgen was introduced in 2001 with this post:
|
18
20
|
|
19
|
-
|
21
|
+
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/24443
|
20
22
|
|
21
|
-
|
23
|
+
= Getting started
|
22
24
|
|
25
|
+
== Installing
|
23
26
|
|
24
|
-
|
27
|
+
Cgen is available from http://rubyforge.org/projects/cgen.
|
25
28
|
|
26
|
-
|
29
|
+
Install either as gem:
|
27
30
|
|
28
|
-
|
29
|
-
Copyright 2001-2009
|
30
|
-
Joel VanderWerf,
|
31
|
-
mailto:vjoel@users.sourceforge.net
|
31
|
+
gem install cgen
|
32
32
|
|
33
|
-
|
33
|
+
or from tarball, by unpacking and then:
|
34
|
+
|
35
|
+
ruby install.rb config
|
36
|
+
ruby install.rb setup
|
37
|
+
ruby install.rb install
|
38
|
+
|
39
|
+
=== System Requirements
|
40
|
+
|
41
|
+
Cgen is pure ruby, so you don't need a compiler to install it. However, you do need a C compiler to do anything useful with it.
|
42
|
+
|
43
|
+
On Unix and GNU/Linux, the gcc compiler works fine. The Sun C compiler has also been tested.
|
44
|
+
|
45
|
+
On Windows, you should use a compiler that is compatible with your ruby interpreter. The following compilers have been tested:
|
46
|
+
|
47
|
+
* MSVC 6.0 (with the traditional one-click ruby installer--the OCI)
|
48
|
+
* MSVC 2003
|
49
|
+
* Mingw32 (gcc; the foundation of the new OCI by Luis Lavena)
|
50
|
+
|
51
|
+
= Examples
|
52
|
+
|
53
|
+
The cgen package comes with a substantial examples directory, but it is not yet very well organized. Here are the best ones to start with:
|
54
|
+
|
55
|
+
sample.rb::
|
56
|
+
introduction to CGenerator
|
57
|
+
|
58
|
+
complex.rb::
|
59
|
+
introduction to CShadow
|
60
|
+
|
61
|
+
matrix.rb::
|
62
|
+
second example of CShadow
|
63
|
+
|
64
|
+
= Web site
|
65
|
+
|
66
|
+
http://rubyforge.org/projects/cgen
|
67
|
+
http://cgen.rubyforge.org/
|
68
|
+
|
69
|
+
= License
|
70
|
+
|
71
|
+
Ruby license.
|
72
|
+
|
73
|
+
= Author
|
34
74
|
|
75
|
+
Copyright 2001-2009, Joel VanderWerf, mailto:vjoel@users.sourceforge.net.
|
data/examples/complex.rb
CHANGED
data/examples/complex2.rb
CHANGED
data/examples/matrix.rb
CHANGED
data/examples/sample.rb
CHANGED
@@ -1,27 +1,3 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
=begin
|
4
|
-
|
5
|
-
Sample for CGenerator.
|
6
|
-
|
7
|
-
==version
|
8
|
-
|
9
|
-
CGenerator 0.14
|
10
|
-
|
11
|
-
The current version of this software can be found at
|
12
|
-
((<"http://redshift.sourceforge.net/cgen
|
13
|
-
"|URL:http://redshift.sourceforge.net/cgen>)).
|
14
|
-
|
15
|
-
==license
|
16
|
-
This software is distributed under the Ruby license.
|
17
|
-
See ((<"http://www.ruby-lang.org"|URL:http://www.ruby-lang.org>)).
|
18
|
-
|
19
|
-
==author
|
20
|
-
Joel VanderWerf,
|
21
|
-
((<vjoel@users.sourceforge.net|URL:mailto:vjoel@users.sourceforge.net>))
|
22
|
-
|
23
|
-
=end
|
24
|
-
|
25
1
|
require 'cgen/cgen'
|
26
2
|
require 'fileutils'
|
27
3
|
|
data/examples/test.rb
CHANGED
File without changes
|
data/lib/cgen/attribute.rb
CHANGED
@@ -27,7 +27,7 @@ module CShadow
|
|
27
27
|
#
|
28
28
|
# The subclass hierarchy has two branches: ObjectAttribute and
|
29
29
|
# CNativeAttribute. The former is a reference to a Ruby object (in other
|
30
|
-
# words, a struct member of type +VALUE
|
30
|
+
# words, a struct member of type +VALUE+). The latter has subclasses for
|
31
31
|
# various C data types, such as +double+ and <tt>char *</tt>.
|
32
32
|
#
|
33
33
|
# ==Adding new attribute classes
|
data/lib/cgen/cgen.rb
CHANGED
@@ -178,366 +178,6 @@ require 'cgen/inherit'
|
|
178
178
|
# It is useful to keep a reference to +lib+ around to send define and declare
|
179
179
|
# messages to.
|
180
180
|
#
|
181
|
-
# ===Templates
|
182
|
-
#
|
183
|
-
# All templates respond to #library and #file methods, which return the library
|
184
|
-
# or file object which contains the template. (The library itself does not
|
185
|
-
# respond to #file.) They also respond to #name and #parent.
|
186
|
-
#
|
187
|
-
# ===Library
|
188
|
-
#
|
189
|
-
# ---Library#use_work_dir dir_name
|
190
|
-
#
|
191
|
-
# Changes into +dir_name+, creating it first if necessary. Does nothing if
|
192
|
-
# alread in a diredctory of that name. Often used with +"tmp"+.
|
193
|
-
#
|
194
|
-
# ---Library#commit
|
195
|
-
#
|
196
|
-
# Writes the files to disk, and makes and loads the library.
|
197
|
-
#
|
198
|
-
# Note that #commit must be called after all C code definitions for the library,
|
199
|
-
# but before instantiation of any objects that use those definitions. If a
|
200
|
-
# definition occurs after commit, or if instantiation occurs before commit, then
|
201
|
-
# a CGenerator::Library::CommitError is raised, with an appropriate message.
|
202
|
-
# Sometimes, this forces you to use many small libraries, each committed just in
|
203
|
-
# time for use. See examples/fixed-array.rb.
|
204
|
-
#
|
205
|
-
# ---Library#committed?
|
206
|
-
#
|
207
|
-
# True if the library has been committed.
|
208
|
-
#
|
209
|
-
# ---Library#before_commit(&block)
|
210
|
-
# ---Library#after_commit(&block)
|
211
|
-
#
|
212
|
-
# Schedules block to run before or after Library#commit. The before blocks are
|
213
|
-
# run in the same order in which they were scheduled; the after blocks run in
|
214
|
-
# the reverse order (analogously with +BEGIN+/+END+). Each block is evaluated in
|
215
|
-
# the context in which it was created (instance_eval is *not* used), and it is
|
216
|
-
# passed the library as an argument.
|
217
|
-
#
|
218
|
-
# ---Library#empty?
|
219
|
-
#
|
220
|
-
# True if no content has been added to the library.
|
221
|
-
#
|
222
|
-
# ---Library#add_file name
|
223
|
-
#
|
224
|
-
# Creates templates for two files, a source (.c) file and an include (.h) file
|
225
|
-
# that will be generated in the same dir as the library. The base file name is
|
226
|
-
# taken from the argument. Returns an array containing the include file template
|
227
|
-
# and the source file template, in that order.
|
228
|
-
#
|
229
|
-
# Functions can be added to the source file by calling #define_method and
|
230
|
-
# similar methods on the source file template. Their +rb_init+ calls are done in
|
231
|
-
# #init_library_function in the main library source file. The new source file
|
232
|
-
# automatically #includes the library's main header file, as well as its own
|
233
|
-
# header file, and the library's main source file also #includes the new header
|
234
|
-
# file. Declarations can be added to the header file by calling #declare on it,
|
235
|
-
# but in many cases this is taken care of automatically.
|
236
|
-
#
|
237
|
-
# ---Library#extconf
|
238
|
-
#
|
239
|
-
# Override #extconf if you want to do more than just #create_makefile. Note that
|
240
|
-
# #create_makefile recognizes all .c files in the library directory, and
|
241
|
-
# generates a makefile that compiles them and links them into the dynamic
|
242
|
-
# library.
|
243
|
-
#
|
244
|
-
# ---Library#write
|
245
|
-
# ---Library#makedepend
|
246
|
-
# ---Library#mkmf
|
247
|
-
# ---Library#make arg = nil
|
248
|
-
#
|
249
|
-
# Internal methods called, in sequence, by #commit:
|
250
|
-
#
|
251
|
-
# * #write dumps each file template to disk, if needed
|
252
|
-
# * #makedepend executes +makedepend+
|
253
|
-
# * #mkmf calls Library#extconf
|
254
|
-
# * #make executes the system's +make+ program.
|
255
|
-
#
|
256
|
-
# These methods can be overridden, but are more typically called directly. The
|
257
|
-
# argument to #make is interpolated into the system call as a command line
|
258
|
-
# argument to the +make+ program. If the argument is 'clean' or 'distclean' then
|
259
|
-
# the make log is deleted; if the argument is 'distclean' then all .c and .h
|
260
|
-
# files generated by #write are deleted (additional user-supplied .c and .h
|
261
|
-
# files in the library dir are not affected).
|
262
|
-
#
|
263
|
-
# ---Library#update_file f, template
|
264
|
-
#
|
265
|
-
# Called by write on each .c and .h file to actually write +template+ to the
|
266
|
-
# open file +f+. The default behavior is to compare the existing data with the
|
267
|
-
# generated data, and leave the file untouched if nothing changed. Subclasses
|
268
|
-
# may have more efficient ways of doing this. (For instance, check a version
|
269
|
-
# indicator in the file on disk, perhaps stored using the file's preamble
|
270
|
-
# accumulator. It is even possible to defer some entries in the template until
|
271
|
-
# after this check has been made: code that only needs to be regenerated if some
|
272
|
-
# specification has changed)
|
273
|
-
#
|
274
|
-
# ---Library#purge_source_dir
|
275
|
-
# ---Library#purge_source_dir= flag
|
276
|
-
#
|
277
|
-
# Access the #purge_source_dir attribute of a library, which controls what
|
278
|
-
# happens to .c, .h, and .o files in the source dir of the library that are not
|
279
|
-
# among those generated as part of the library. If this is set to +:delete+,
|
280
|
-
# then those files are deleted. Other true values cause the .c, .h, and .o files
|
281
|
-
# to be renamed with the .hide extension. (Note that this makes it difficult to
|
282
|
-
# keep manually written C files in the same dir.) False +flag+ values (the
|
283
|
-
# default) cause CGen to leave the files untouched.
|
284
|
-
#
|
285
|
-
# Note that, regardless of this setting, #mkmf will construct a Makefile which
|
286
|
-
# lists all .c files that are in the source dir. If you do not delete obsolete
|
287
|
-
# files, they will be compiled into your library!
|
288
|
-
#
|
289
|
-
# ---Library#init_library_function
|
290
|
-
#
|
291
|
-
# Returns a Function template object; see below. This function is called when
|
292
|
-
# the library is loaded. Method definitions put stuff here to register methods
|
293
|
-
# with Ruby. Usually, there is no need to bother this guy directly. Use
|
294
|
-
# Library#setup instead.
|
295
|
-
#
|
296
|
-
# ---Library#setup key => "statements", ...
|
297
|
-
#
|
298
|
-
# Inserts code in the #init_library_function, which is called when the library
|
299
|
-
# is loaded. The +key+ is used for redundancy checking, as in the #declare
|
300
|
-
# accumulators. Note that hashes are unordered, so constructs like
|
301
|
-
#
|
302
|
-
# setup :x => "...", :y => "..."
|
303
|
-
#
|
304
|
-
# can result in unpredictable order. To avoid this, use several #setup calls.
|
305
|
-
#
|
306
|
-
# ---Library#source_file ---Library#include_file
|
307
|
-
#
|
308
|
-
# Returns the template for the main source or include file of the library.
|
309
|
-
# Usually, there is no need to access these directly.
|
310
|
-
#
|
311
|
-
# ---Library#define_c_function name, type
|
312
|
-
#
|
313
|
-
# Defines a plain ol' C function. Returns a Function template (see below), or a
|
314
|
-
# template of the specified +type+, if given.
|
315
|
-
#
|
316
|
-
# ---Library#define_c_method mod, name, subclass
|
317
|
-
# ---Library#define_c_module_function mod, name, subclass
|
318
|
-
# ---Library#define_c_global_function name, subclass
|
319
|
-
# ---Library#define_c_singleton_method mod, name, subclass
|
320
|
-
# ---Library#define_c_class_method mod, name, subclass
|
321
|
-
#
|
322
|
-
# Defines a function of the specified name and type in the given class/module
|
323
|
-
# (or in the global scope), and returns the function template (often used with
|
324
|
-
# #instance_eval to add arguments, code, etc.). The +subclass+ argument is
|
325
|
-
# optional and allows the template to belong to a subclass of the function
|
326
|
-
# template it would normally belong to.
|
327
|
-
#
|
328
|
-
# For example,
|
329
|
-
#
|
330
|
-
# define_c_method String, "reverse"
|
331
|
-
#
|
332
|
-
# The arguments accepted by the method automatically include +self+. By default,
|
333
|
-
# arguments are passed as individual C arguments, but the can be passed in a
|
334
|
-
# Ruby or C array. The latter has the advantage of argument parsing (based on
|
335
|
-
# rb_scan_args), defaults, and typechecking. See Method#c_array_args.
|
336
|
-
# #define_c_class_method is just an alias for #define_c_singleton_method.
|
337
|
-
#
|
338
|
-
# ---Library#include "file1.h", "<file2.h>", ...
|
339
|
-
#
|
340
|
-
# Insert the include statement(s) at the top of the library's main .c file. For
|
341
|
-
# convenience, <ruby.h> is included automatically, as is the header file of the
|
342
|
-
# library itself.
|
343
|
-
#
|
344
|
-
# ---Library#declare :x => "int x", ... ---Library#declare_extern :x => "int x",
|
345
|
-
# ...
|
346
|
-
#
|
347
|
-
# Puts the string in the declaration area of the .c or .h file, respectively.
|
348
|
-
# The declaration area is before the function definitions, and after the
|
349
|
-
# structure declarations.
|
350
|
-
#
|
351
|
-
# ---Library#declare_struct name, attributes=nil
|
352
|
-
# ---Library#declare_extern_struct name, attributes=nil
|
353
|
-
#
|
354
|
-
# Returns a Structure template, which generates to a typedefed C struct in the
|
355
|
-
# .c or .h file. The #declare method of this template is used to add members.
|
356
|
-
#
|
357
|
-
# ---Library#declare_class cl ---Library#declare_module mod
|
358
|
-
# ---Library#declare_symbol sym
|
359
|
-
#
|
360
|
-
# Define a C variable which will be initialized to refer to the class, module,
|
361
|
-
# or symbol. These accumulators return the name of the C variable which will be
|
362
|
-
# generated and initialized to the ID of the symbol, and this return value can
|
363
|
-
# be interpolated into C calls to the Ruby API. (The arguments are the actual
|
364
|
-
# Ruby objects.) This is very useful in #rb_ivar_get/#rb_ivar_set calls, and it
|
365
|
-
# avoids doing the lookup more than once:
|
366
|
-
#
|
367
|
-
# ...
|
368
|
-
# declare :my_ivar => "VALUE my_ivar"
|
369
|
-
# body %{
|
370
|
-
# my_ivar = rb_ivar_get(shadow->self, #{declare_symbol :@my_ivar});
|
371
|
-
# rb_ivar_set(shadow->self, #{declare_symbol :@my_ivar}, Qnil);
|
372
|
-
# }
|
373
|
-
#
|
374
|
-
# The second declaration notices that the library already has a variable that
|
375
|
-
# will be initialized to the ID of the symbol, and uses it.
|
376
|
-
#
|
377
|
-
# ---Library#literal_symbol sym
|
378
|
-
#
|
379
|
-
# Like Library#declare_symbol, but converts the ID to a VALUE at library
|
380
|
-
# initialization time. Useful for looking up hash values keyed by symbol
|
381
|
-
# objects, for example. +sym+ is a string or symbol.
|
382
|
-
#
|
383
|
-
# ---Library#show_times message
|
384
|
-
#
|
385
|
-
# If the attribute #show_times_flag is set to true, print the user and system
|
386
|
-
# times (and child user and child system on some platforms) and real time for
|
387
|
-
# each major step of the commit process. Display +message+.
|
388
|
-
#
|
389
|
-
# ===File
|
390
|
-
#
|
391
|
-
# File templates are managed by the Library, and most users do not need to
|
392
|
-
# interact with them directly. They are structured into four sections: includes,
|
393
|
-
# structure declarations, variable and function declarations, and function
|
394
|
-
# definitions. Each source file automatically includes its corresponding header
|
395
|
-
# file and the main header file for the library (which includes ruby.h). The
|
396
|
-
# main source file for the library includes each additional header file.
|
397
|
-
#
|
398
|
-
# ---File#define_c_method
|
399
|
-
# ---File#define_c_module_function
|
400
|
-
# ---File#define_c_global_function
|
401
|
-
# ---File#define_c_singleton_method
|
402
|
-
#
|
403
|
-
# As for the Library, but can be used on any source file within the library.
|
404
|
-
# Used to break large projects up into many files.
|
405
|
-
#
|
406
|
-
# ---File#preamble
|
407
|
-
#
|
408
|
-
# An accumulator that wraps its input in C comments and places it at the head of
|
409
|
-
# the source file.
|
410
|
-
#
|
411
|
-
# ===Function
|
412
|
-
#
|
413
|
-
# ---Funtion#scope :static ---Funtion#scope :extern ---Funtion#arguments 'int
|
414
|
-
# x', 'double y', 'VALUE obj', ... ---Funtion#return_type 'void'
|
415
|
-
#
|
416
|
-
# These accumulators affect the prototype of the function, which will be placed
|
417
|
-
# in the declaration section of either the .h or the .c file, depending on the
|
418
|
-
# scope setting. The default scope is static. The default return type is 'void'.
|
419
|
-
#
|
420
|
-
# For the Method subclasses of Function, argument and return types can be
|
421
|
-
# omitted, in which case they default to 'VALUE'.
|
422
|
-
#
|
423
|
-
# ---Funtion#declare :x => "static double x", ... ---Funtion#init "x = 0", ...
|
424
|
-
# ---Funtion#setup 'x' => "x += 1", ... ---Funtion#body 'y = sin(x);
|
425
|
-
# printf("%d\n", y)', ...
|
426
|
-
#
|
427
|
-
# These four accumulators determine the contents of the function between the
|
428
|
-
# opening and closing braces. The #init code is executed once when the function
|
429
|
-
# first runs; it's useful for initializing static data. The #setup code runs
|
430
|
-
# each time the function is called, as does the #body. Distinguishing #setup
|
431
|
-
# from #body is useful for two reasons: first, #setup is guaranteed to execute
|
432
|
-
# before #body, and, second, one can avoid setting up the same variable twice,
|
433
|
-
# because of the key.
|
434
|
-
#
|
435
|
-
# ---Funtion#returns "2*x"
|
436
|
-
#
|
437
|
-
# Specifies the string used in the final return statement of the function.
|
438
|
-
# Subsequent uses of this method clobber the previous value. Alternately, one
|
439
|
-
# can simply insert a "return" manually in the body.
|
440
|
-
#
|
441
|
-
# ===Method ===ModuleFunction ===GlobalFunction ===SingletonMethod
|
442
|
-
#
|
443
|
-
# These subclasses of the Function template are designed for coding Ruby
|
444
|
-
# methods. The necessary registration (+rb_define_method+, etc.) is handled
|
445
|
-
# automatically. Defaults are different from Function: +'VALUE self'+ is
|
446
|
-
# automatically an argument, and argument and return types are assumed to be
|
447
|
-
# +'VALUE'+ and can be omitted by the caller. The return value is +nil+ by
|
448
|
-
# default.
|
449
|
-
#
|
450
|
-
# ---Method#arguments :arg1, :arg2, ...
|
451
|
-
#
|
452
|
-
# The default way of specifying arguments. Allows a fixed number of VALUE
|
453
|
-
# arguments.
|
454
|
-
#
|
455
|
-
# ---Method#c_array_args argc_name = 'argc', argv_name = 'argv', &block
|
456
|
-
# ---Method#rb_array_args args_name = 'args'
|
457
|
-
#
|
458
|
-
# Specifies that arguments are to be collected and passed in a C or Ruby array,
|
459
|
-
# instead of individually (which is the default). In each case, the array of
|
460
|
-
# actual arguments will be bound to a C parameter with the name specified. See
|
461
|
-
# the Ruby API documentation for details.
|
462
|
-
#
|
463
|
-
# If a block is given to Method#c_array_args, it will be used to specify a call
|
464
|
-
# to the API function +rb_scan_args+ and to declare the associated variables.
|
465
|
-
# For example:
|
466
|
-
#
|
467
|
-
# c_array_args('argc', 'argv') {
|
468
|
-
# required :arg0, :arg1
|
469
|
-
# optional :arg2, :arg3, :arg4
|
470
|
-
# rest :rest
|
471
|
-
# block :block
|
472
|
-
# }
|
473
|
-
#
|
474
|
-
# declares all the listed symbols as variables of type +VALUE+ in function
|
475
|
-
# scope, and arranges for the following to be called in the #setup clause (i.e.,
|
476
|
-
# before the #body):
|
477
|
-
#
|
478
|
-
# rb_scan_args(argc, argv, "23*&", &arg0, &arg1, &arg2, &arg3, &arg4, &rest, &block);
|
479
|
-
#
|
480
|
-
# The <tt>'argc', 'argv'</tt> are the default values and are usually omitted.
|
481
|
-
#
|
482
|
-
# The lines in the block can occur in any order, and any line can be omitted.
|
483
|
-
# However, only one line of each kind should be used. In addition, each optional
|
484
|
-
# argument can be associated with a fragment of C code that will be executed to
|
485
|
-
# assign it a default value, if needed. For example, one can add the following
|
486
|
-
# lines to the above block:
|
487
|
-
#
|
488
|
-
# default :arg3 => "INT2NUM(7)",
|
489
|
-
# :arg4 => "INT2NUM(NUM2INT(arg2) + NUM2INT(arg3))"
|
490
|
-
#
|
491
|
-
# Otherwise, optional arguments are assigned nil.
|
492
|
-
#
|
493
|
-
# In this case, if +arg4+ is not provided by +argv+, then it is initialized
|
494
|
-
# using the code given. If, in addition, +arg3+ is not provided, then it too is
|
495
|
-
# initialized. These initializations happen in the #setup clause of the Function
|
496
|
-
# template and are executed in the same order as the arguments are given in the
|
497
|
-
# +optional+ line.
|
498
|
-
#
|
499
|
-
# Finally, argument types can be checked automatically:
|
500
|
-
#
|
501
|
-
# typecheck :arg2 => Numeric, :arg3 => Numeric
|
502
|
-
#
|
503
|
-
# The value passed to the function must either be +nil+ or match the type. Note
|
504
|
-
# that type checking happens *before* default assignment, so that default
|
505
|
-
# calculation code can assume types are correct. No typechecking code is
|
506
|
-
# generated if the type is Object.
|
507
|
-
#
|
508
|
-
# ===Structure
|
509
|
-
#
|
510
|
-
# ---Structure#declare :x => "int x"
|
511
|
-
#
|
512
|
-
# Adds the specified string to define a structure member.
|
513
|
-
#
|
514
|
-
# ===Utility functions
|
515
|
-
#
|
516
|
-
# ---CGenerator.make_c_name s
|
517
|
-
#
|
518
|
-
# Geenrates a unique C itentifier from the given Ruby identifier, which may
|
519
|
-
# include +/[@$?!]/+, +'::'+, and even +'.'+. (Some special globals are not yet
|
520
|
-
# supported: +$:+ and +$-I+, for example.)
|
521
|
-
#
|
522
|
-
# It is unique in the sense that distinct Ruby identifiers map to distinct C
|
523
|
-
# identifiers. (Not completely checked. Might fail for some really obscure
|
524
|
-
# cases.)
|
525
|
-
#
|
526
|
-
# ---String.tab n
|
527
|
-
#
|
528
|
-
# Tabs left or right by n chars, using spaces.
|
529
|
-
#
|
530
|
-
# ---String.tabto n
|
531
|
-
#
|
532
|
-
# The first non-empty line is adjusted to have n spaces before the first
|
533
|
-
# nonspace. Additional lines are changed to preserve relative tabbing.
|
534
|
-
#
|
535
|
-
# ---String.taballto n
|
536
|
-
#
|
537
|
-
# Aligns each line to have n spaces before the first non-space.
|
538
|
-
#
|
539
|
-
# (These routines probably don't work well, if at all, with "hard" tabs.)
|
540
|
-
#
|
541
181
|
# ==Example
|
542
182
|
#
|
543
183
|
# require 'cgen'
|
@@ -778,7 +418,7 @@ require 'cgen/inherit'
|
|
778
418
|
# way that makes clear that the problem is really with commit.
|
779
419
|
module CGenerator
|
780
420
|
|
781
|
-
VERSION = '0.16.
|
421
|
+
VERSION = '0.16.1'
|
782
422
|
|
783
423
|
class Accumulator ## should be a mixin? "Cumulative"?
|
784
424
|
|
@@ -889,6 +529,9 @@ module KeyAccumulator
|
|
889
529
|
end
|
890
530
|
end
|
891
531
|
|
532
|
+
# All templates respond to #library and #file methods, which return the library
|
533
|
+
# or file object which contains the template. (The library itself does not
|
534
|
+
# respond to #file.) They also respond to #name and #parent.
|
892
535
|
class Template < Accumulator
|
893
536
|
|
894
537
|
def initialize name = "", parent = nil, &block
|
@@ -926,9 +569,35 @@ class Library < Template
|
|
926
569
|
|
927
570
|
class CommitError < RuntimeError; end
|
928
571
|
|
929
|
-
|
930
|
-
|
572
|
+
# Returns a Function template object. This function is called when the library
|
573
|
+
# is loaded. Method definitions put stuff here to register methods with Ruby.
|
574
|
+
# Usually, there is no need to bother this guy directly. Use Library#setup
|
575
|
+
# instead.
|
576
|
+
attr_reader :init_library_function
|
931
577
|
|
578
|
+
# Returns the template for the main include file of the library.
|
579
|
+
# Usually, there is no need to access this directly.
|
580
|
+
attr_reader :include_file
|
581
|
+
|
582
|
+
# Returns the template for the main source file of the library.
|
583
|
+
# Usually, there is no need to access this directly.
|
584
|
+
attr_reader :source_file
|
585
|
+
|
586
|
+
attr_accessor :show_times_flag
|
587
|
+
|
588
|
+
# The #purge_source_dir attribute controls what happens to .c, .h, and .o
|
589
|
+
# files in the source dir of the library that are not among those generated as
|
590
|
+
# part of the library. If this is set to +:delete+, then those files are
|
591
|
+
# deleted. Other true values cause the .c, .h, and .o files to be renamed with
|
592
|
+
# the .hide extension. (Note that this makes it difficult to keep manually
|
593
|
+
# written C files in the same dir.) False +flag+ values (the default) cause
|
594
|
+
# CGen to leave the files untouched.
|
595
|
+
#
|
596
|
+
# Note that, regardless of this setting, #mkmf will construct a Makefile which
|
597
|
+
# lists all .c files that are in the source dir. If you do not delete obsolete
|
598
|
+
# files, they will be compiled into your library!
|
599
|
+
attr_accessor :purge_source_dir
|
600
|
+
|
932
601
|
def initialize name
|
933
602
|
super name
|
934
603
|
|
@@ -960,6 +629,8 @@ class Library < Template
|
|
960
629
|
## a template which is not the parent
|
961
630
|
end
|
962
631
|
|
632
|
+
# Changes into +dir_name+, creating it first if necessary. Does nothing if
|
633
|
+
# already in a directory of that name. Often used with +"tmp"+.
|
963
634
|
def use_work_dir dir_name
|
964
635
|
if File.basename(Dir.pwd) == dir_name
|
965
636
|
yield
|
@@ -972,6 +643,19 @@ class Library < Template
|
|
972
643
|
end
|
973
644
|
end
|
974
645
|
|
646
|
+
# Creates templates for two files, a source (.c) file and an include (.h) file
|
647
|
+
# that will be generated in the same dir as the library. The base file name is
|
648
|
+
# taken from the argument. Returns an array containing the include file
|
649
|
+
# template and the source file template, in that order.
|
650
|
+
#
|
651
|
+
# Functions can be added to the source file by calling #define_method and
|
652
|
+
# similar methods on the source file template. Their +rb_init+ calls are done
|
653
|
+
# in
|
654
|
+
# #init_library_function in the main library source file. The new source file
|
655
|
+
# automatically #includes the library's main header file, as well as its own
|
656
|
+
# header file, and the library's main source file also #includes the new
|
657
|
+
# header file. Declarations can be added to the header file by calling
|
658
|
+
# #declare on it, but in many cases this is taken care of automatically.
|
975
659
|
def add_file name, opts = {}
|
976
660
|
pair = @pile.detect {|p| p[0].name == name + ".h"}
|
977
661
|
|
@@ -998,22 +682,42 @@ class Library < Template
|
|
998
682
|
end
|
999
683
|
end
|
1000
684
|
|
685
|
+
# True if the library has been committed.
|
1001
686
|
def committed?
|
1002
687
|
@committed
|
1003
688
|
end
|
1004
689
|
|
690
|
+
# True if no content has been added to the library.
|
1005
691
|
def empty?
|
1006
692
|
@init_library_function.empty? ## is this enough?
|
1007
693
|
end
|
1008
694
|
|
695
|
+
# Schedules block to run before Library#commit. The before blocks are run in
|
696
|
+
# the same order in which they were scheduled; the after blocks run in the
|
697
|
+
# reverse order (analogously with +BEGIN+/+END+). Each block is evaluated in
|
698
|
+
# the context in which it was created (instance_eval is *not* used), and it is
|
699
|
+
# passed the library as an argument.
|
1009
700
|
def before_commit(&block)
|
1010
701
|
(@before_commit ||= []) << block
|
1011
702
|
end
|
1012
703
|
|
704
|
+
# Schedules block to run after Library#commit. The before blocks are run in
|
705
|
+
# the same order in which they were scheduled; the after blocks run in the
|
706
|
+
# reverse order (analogously with +BEGIN+/+END+). Each block is evaluated in
|
707
|
+
# the context in which it was created (instance_eval is *not* used), and it is
|
708
|
+
# passed the library as an argument.
|
1013
709
|
def after_commit(&block)
|
1014
710
|
(@after_commit ||= []) << block
|
1015
711
|
end
|
1016
712
|
|
713
|
+
# Writes the files to disk, and makes and loads the library.
|
714
|
+
#
|
715
|
+
# Note that #commit must be called after all C code definitions for the
|
716
|
+
# library, but before instantiation of any objects that use those definitions.
|
717
|
+
# If a definition occurs after commit, or if instantiation occurs before
|
718
|
+
# commit, then a CGenerator::Library::CommitError is raised, with an
|
719
|
+
# appropriate message. Sometimes, this forces you to use many small libraries,
|
720
|
+
# each committed just in time for use. See examples/fixed-array.rb.
|
1017
721
|
def commit(build = true)
|
1018
722
|
assert_uncommitted
|
1019
723
|
|
@@ -1042,10 +746,34 @@ class Library < Template
|
|
1042
746
|
end
|
1043
747
|
end
|
1044
748
|
|
749
|
+
#----------------
|
750
|
+
# :section: Build methods
|
751
|
+
#
|
752
|
+
# Methods used during commit to control the build chain.
|
753
|
+
# In sequence, #commit calls these methods:
|
754
|
+
#
|
755
|
+
# * #write dumps each file template to disk, if needed
|
756
|
+
# * #makedepend executes +makedepend+
|
757
|
+
# * #mkmf calls Library#extconf
|
758
|
+
# * #make executes the system's +make+ program
|
759
|
+
# * #loadlib load the library that has been built
|
760
|
+
#
|
761
|
+
# These methods can be overridden, but are more typically called via commit or
|
762
|
+
# sometimes directly. The argument to #make is interpolated into the system
|
763
|
+
# call as a command line argument to the +make+ program. If the argument is
|
764
|
+
# 'clean' or 'distclean' then the make log is deleted; if the argument is
|
765
|
+
# 'distclean' then all .c and .h files generated by #write are deleted
|
766
|
+
# (additional user-supplied .c and .h files in the library dir are not
|
767
|
+
# affected).
|
768
|
+
#----------------
|
769
|
+
|
1045
770
|
def process_times
|
1046
771
|
RUBY_VERSION.to_f >= 1.7 ? Process.times : Time.times
|
1047
772
|
end
|
1048
773
|
|
774
|
+
# If the attribute #show_times_flag is set to true, print the user and system
|
775
|
+
# times (and child user and child system on some platforms) and real time for
|
776
|
+
# each major step of the commit process. Display +message+.
|
1049
777
|
def show_times message
|
1050
778
|
yield if block_given?
|
1051
779
|
if @show_times_flag
|
@@ -1094,6 +822,14 @@ class Library < Template
|
|
1094
822
|
end
|
1095
823
|
end
|
1096
824
|
|
825
|
+
# Called by write on each .c and .h file to actually write +template+ to the
|
826
|
+
# open file +f+. The default behavior is to compare the existing data with the
|
827
|
+
# generated data, and leave the file untouched if nothing changed. Subclasses
|
828
|
+
# may have more efficient ways of doing this. (For instance, check a version
|
829
|
+
# indicator in the file on disk, perhaps stored using the file's preamble
|
830
|
+
# accumulator. It is even possible to defer some entries in the template until
|
831
|
+
# after this check has been made: code that only needs to be regenerated if
|
832
|
+
# some specification has changed)
|
1097
833
|
def update_file f, template
|
1098
834
|
template_str = template.to_s
|
1099
835
|
file_data = f.gets(nil) ## sysread is faster?
|
@@ -1256,6 +992,11 @@ class Library < Template
|
|
1256
992
|
### this is fragile--should record abs path when Lib is created
|
1257
993
|
end
|
1258
994
|
|
995
|
+
# Override #extconf if you want to do more than just #create_makefile. Note
|
996
|
+
# that #create_makefile recognizes all .c files in the library directory, and
|
997
|
+
# generates a makefile that compiles them and links them into the dynamic
|
998
|
+
# library.
|
999
|
+
#
|
1259
1000
|
# Yields the array of lines being constructed so that additional configuration
|
1260
1001
|
# can be added. See the ruby documentation on mkmf.
|
1261
1002
|
def extconf # :yields: lines_array
|
@@ -1332,27 +1073,67 @@ class Library < Template
|
|
1332
1073
|
:rb_define_global_function,
|
1333
1074
|
:rb_define_singleton_method) {RbDefineAccumulator}
|
1334
1075
|
|
1076
|
+
# call-seq:
|
1077
|
+
# define_c_method mod, name, subclass
|
1078
|
+
# define_c_module_function mod, name, subclass
|
1079
|
+
# define_c_global_function name, subclass
|
1080
|
+
# define_c_singleton_method mod, name, subclass
|
1081
|
+
# define_c_class_method mod, name, subclass
|
1082
|
+
#
|
1083
|
+
# Defines a function of the specified name and type in the given class/module
|
1084
|
+
# (or in the global scope), and returns the function template (often used with
|
1085
|
+
# #instance_eval to add arguments, code, etc.). The +subclass+ argument is
|
1086
|
+
# optional and allows the template to belong to a subclass of the function
|
1087
|
+
# template it would normally belong to.
|
1088
|
+
#
|
1089
|
+
# For example,
|
1090
|
+
#
|
1091
|
+
# define_c_method String, "reverse"
|
1092
|
+
#
|
1093
|
+
# The arguments accepted by the method automatically include +self+. By
|
1094
|
+
# default, arguments are passed as individual C arguments, but the can be
|
1095
|
+
# passed in a Ruby or C array. The latter has the advantage of argument
|
1096
|
+
# parsing (based on rb_scan_args), defaults, and typechecking. See
|
1097
|
+
# Method#c_array_args. #define_c_class_method is just an alias for
|
1098
|
+
# #define_c_singleton_method.
|
1099
|
+
#
|
1335
1100
|
def define_c_method(*args)
|
1336
1101
|
@source_file.define_c_method(*args)
|
1337
1102
|
end
|
1338
1103
|
|
1104
|
+
# See #define_c_method.
|
1339
1105
|
def define_c_module_function(*args)
|
1340
1106
|
@source_file.define_c_module_function(*args)
|
1341
1107
|
end
|
1342
1108
|
|
1109
|
+
# See #define_c_method.
|
1343
1110
|
def define_c_global_function(*args)
|
1344
1111
|
@source_file.define_c_global_function(*args)
|
1345
1112
|
end
|
1346
1113
|
|
1114
|
+
# See #define_c_method.
|
1347
1115
|
def define_c_singleton_method(*args)
|
1348
1116
|
@source_file.define_c_singleton_method(*args)
|
1349
1117
|
end
|
1350
1118
|
alias define_c_class_method define_c_singleton_method
|
1351
1119
|
|
1120
|
+
# call-seq:
|
1121
|
+
# include "file1.h", "<file2.h>", ...
|
1122
|
+
#
|
1123
|
+
# Insert the include statement(s) at the top of the library's main .c file.
|
1124
|
+
# For convenience, <ruby.h> is included automatically, as is the header file
|
1125
|
+
# of the library itself.
|
1352
1126
|
def include(*args)
|
1353
1127
|
@source_file.include(*args)
|
1354
1128
|
end
|
1355
1129
|
|
1130
|
+
# call-seq:
|
1131
|
+
# declare :x => "int x", ...
|
1132
|
+
# declare_extern :x => "int x", ...
|
1133
|
+
#
|
1134
|
+
# Puts the string in the declaration area of the .c or .h file, respectively.
|
1135
|
+
# The declaration area is before the function definitions, and after the
|
1136
|
+
# structure declarations.
|
1356
1137
|
def declare(*args)
|
1357
1138
|
@source_file.declare(*args)
|
1358
1139
|
end
|
@@ -1362,20 +1143,53 @@ class Library < Template
|
|
1362
1143
|
@include_file.declare(*args)
|
1363
1144
|
end
|
1364
1145
|
|
1146
|
+
# call-seq:
|
1147
|
+
# declare_struct name, attributes=nil
|
1148
|
+
# declare_extern_struct name, attributes=nil
|
1149
|
+
#
|
1150
|
+
# Returns a Structure template, which generates to a typedefed C struct in the
|
1151
|
+
# .c or .h file. The #declare method of this template is used to add members.
|
1365
1152
|
def declare_struct struct_name, *rest
|
1366
1153
|
@source_file.declare_struct struct_name, *rest
|
1367
1154
|
end
|
1368
1155
|
alias declare_static_struct declare_struct
|
1369
1156
|
|
1157
|
+
# See #declare_struct.
|
1370
1158
|
def declare_extern_struct struct_name, *rest
|
1371
1159
|
@include_file.declare_struct struct_name, *rest
|
1372
1160
|
end
|
1373
1161
|
|
1162
|
+
# call-seq:
|
1163
|
+
# define_c_function
|
1164
|
+
#
|
1165
|
+
# Defines a plain ol' C function. Returns a Function template (see below), or
|
1166
|
+
# a template of the specified +type+, if given.
|
1374
1167
|
def define(*args)
|
1375
1168
|
@source_file.define(*args)
|
1376
1169
|
end
|
1377
1170
|
alias define_c_function define
|
1378
1171
|
|
1172
|
+
# call-seq:
|
1173
|
+
# declare_class cl
|
1174
|
+
# declare_module mod
|
1175
|
+
# declare_symbol sym
|
1176
|
+
#
|
1177
|
+
# Define a C variable which will be initialized to refer to the class, module,
|
1178
|
+
# or symbol. These accumulators return the name of the C variable which will
|
1179
|
+
# be generated and initialized to the ID of the symbol, and this return value
|
1180
|
+
# can be interpolated into C calls to the Ruby API. (The arguments are the
|
1181
|
+
# actual Ruby objects.) This is very useful in #rb_ivar_get/#rb_ivar_set
|
1182
|
+
# calls, and it avoids doing the lookup more than once:
|
1183
|
+
#
|
1184
|
+
# ...
|
1185
|
+
# declare :my_ivar => "VALUE my_ivar"
|
1186
|
+
# body %{
|
1187
|
+
# my_ivar = rb_ivar_get(shadow->self, #{declare_symbol :@my_ivar});
|
1188
|
+
# rb_ivar_set(shadow->self, #{declare_symbol :@my_ivar}, Qnil);
|
1189
|
+
# }
|
1190
|
+
#
|
1191
|
+
# The second declaration notices that the library already has a variable that
|
1192
|
+
# will be initialized to the ID of the symbol, and uses it.
|
1379
1193
|
def declare_module mod
|
1380
1194
|
c_name = "module_#{CGenerator::make_c_name mod.to_s}"
|
1381
1195
|
declare mod => "VALUE #{c_name}"
|
@@ -1385,6 +1199,7 @@ class Library < Template
|
|
1385
1199
|
end
|
1386
1200
|
alias declare_class declare_module
|
1387
1201
|
|
1202
|
+
# See #declare_module.
|
1388
1203
|
def declare_symbol sym
|
1389
1204
|
c_name = "ID_#{CGenerator::make_c_name sym}"
|
1390
1205
|
declare sym => "ID #{c_name}"
|
@@ -1393,6 +1208,9 @@ class Library < Template
|
|
1393
1208
|
c_name.intern
|
1394
1209
|
end
|
1395
1210
|
|
1211
|
+
# Like Library#declare_symbol, but converts the ID to a VALUE at library
|
1212
|
+
# initialization time. Useful for looking up hash values keyed by symbol
|
1213
|
+
# objects, for example. +sym+ is a string or symbol.
|
1396
1214
|
def literal_symbol sym
|
1397
1215
|
c_name = "SYM_#{CGenerator::make_c_name sym}"
|
1398
1216
|
declare sym => "VALUE #{c_name}"
|
@@ -1401,6 +1219,16 @@ class Library < Template
|
|
1401
1219
|
c_name.intern
|
1402
1220
|
end
|
1403
1221
|
|
1222
|
+
# call-seq:
|
1223
|
+
# setup key => "statements", ...
|
1224
|
+
#
|
1225
|
+
# Inserts code in the #init_library_function, which is called when the library
|
1226
|
+
# is loaded. The +key+ is used for redundancy checking, as in the #declare
|
1227
|
+
# accumulators. Note that hashes are unordered, so constructs like
|
1228
|
+
#
|
1229
|
+
# setup :x => "...", :y => "..."
|
1230
|
+
#
|
1231
|
+
# can result in unpredictable order. To avoid this, use several #setup calls.
|
1404
1232
|
def setup(*args)
|
1405
1233
|
@init_library_function.setup(*args)
|
1406
1234
|
end
|
@@ -1472,6 +1300,15 @@ class CFragment < Template
|
|
1472
1300
|
end # class CFragment
|
1473
1301
|
|
1474
1302
|
|
1303
|
+
# File templates are managed by the Library, and most users do not need to
|
1304
|
+
# interact with them directly. They are structured into four sections: includes,
|
1305
|
+
# structure declarations, variable and function declarations, and function
|
1306
|
+
# definitions. Each source file automatically includes its corresponding header
|
1307
|
+
# file and the main header file for the library (which includes ruby.h). The
|
1308
|
+
# main source file for the library includes each additional header file.
|
1309
|
+
#
|
1310
|
+
# The File#preamble accumulator wraps its input in C comments and places it at
|
1311
|
+
# the head of the source file.
|
1475
1312
|
class CFile < CFragment
|
1476
1313
|
|
1477
1314
|
attr_reader :include_file
|
@@ -1552,10 +1389,14 @@ class CFile < CFragment
|
|
1552
1389
|
accumulator(:declare) {StatementKeyAccumulator}
|
1553
1390
|
accumulator(:define) {FunctionAccumulator}
|
1554
1391
|
|
1392
|
+
# As for the Library, but can be used on any source file within the library.
|
1393
|
+
# Used to break large projects up into many files.
|
1555
1394
|
def define_c_function c_name, subclass = Function
|
1556
1395
|
define c_name, subclass
|
1557
1396
|
end
|
1558
1397
|
|
1398
|
+
# As for the Library, but can be used on any source file within the library.
|
1399
|
+
# Used to break large projects up into many files.
|
1559
1400
|
def define_c_method mod, name, subclass = Method
|
1560
1401
|
unless subclass <= Method ## should use assert
|
1561
1402
|
raise "#{subclass.name} is not <= Method"
|
@@ -1564,18 +1405,24 @@ class CFile < CFragment
|
|
1564
1405
|
define c_name, subclass
|
1565
1406
|
end
|
1566
1407
|
|
1408
|
+
# As for the Library, but can be used on any source file within the library.
|
1409
|
+
# Used to break large projects up into many files.
|
1567
1410
|
def define_c_module_function mod, name, subclass = ModuleFunction
|
1568
1411
|
raise unless subclass <= ModuleFunction
|
1569
1412
|
c_name = library.rb_define_module_function :mod => mod, :rb_name => name
|
1570
1413
|
define c_name, subclass
|
1571
1414
|
end
|
1572
1415
|
|
1416
|
+
# As for the Library, but can be used on any source file within the library.
|
1417
|
+
# Used to break large projects up into many files.
|
1573
1418
|
def define_c_global_function name, subclass = GlobalFunction
|
1574
1419
|
raise unless subclass <= GlobalFunction
|
1575
1420
|
c_name = library.rb_define_global_function :rb_name => name
|
1576
1421
|
define c_name, subclass
|
1577
1422
|
end
|
1578
1423
|
|
1424
|
+
# As for the Library, but can be used on any source file within the library.
|
1425
|
+
# Used to break large projects up into many files.
|
1579
1426
|
def define_c_singleton_method mod, name, subclass = SingletonMethod
|
1580
1427
|
raise unless subclass <= SingletonMethod
|
1581
1428
|
c_name = library.rb_define_singleton_method :mod => mod, :rb_name => name
|
@@ -1583,7 +1430,6 @@ class CFile < CFragment
|
|
1583
1430
|
end
|
1584
1431
|
alias define_c_class_method define_c_singleton_method
|
1585
1432
|
|
1586
|
-
# For ruby 1.7/1.8 after 20Dec2002
|
1587
1433
|
def define_alloc_func klass
|
1588
1434
|
klass_c_name = declare_class klass
|
1589
1435
|
c_name = "alloc_func_#{klass_c_name}"
|
@@ -1657,6 +1503,121 @@ class Prototype < CFragment
|
|
1657
1503
|
|
1658
1504
|
end # class Prototype
|
1659
1505
|
|
1506
|
+
# The Function class manages all kinds of functions and methods.
|
1507
|
+
#
|
1508
|
+
# === Function Prototype
|
1509
|
+
#
|
1510
|
+
# scope :static
|
1511
|
+
# scope :extern
|
1512
|
+
# arguments 'int x', 'double y', 'VALUE obj', ...
|
1513
|
+
# return_type 'void'
|
1514
|
+
#
|
1515
|
+
# These accumulators affect the prototype of the function, which will be placed
|
1516
|
+
# in the declaration section of either the .h or the .c file, depending on the
|
1517
|
+
# scope setting. The default scope is static. The default return type is 'void'.
|
1518
|
+
#
|
1519
|
+
# For the Method subclasses of Function, argument and return types can be
|
1520
|
+
# omitted, in which case they default to 'VALUE'.
|
1521
|
+
#
|
1522
|
+
# === Function Body
|
1523
|
+
#
|
1524
|
+
# declare :x => "static double x", ...
|
1525
|
+
# init "x = 0", ...
|
1526
|
+
# setup 'x' => "x += 1", ...
|
1527
|
+
# body 'y = sin(x); printf("%d\n", y)', ...
|
1528
|
+
#
|
1529
|
+
# These four accumulators determine the contents of the function between the
|
1530
|
+
# opening and closing braces. The #init code is executed once when the function
|
1531
|
+
# first runs; it's useful for initializing static data. The #setup code runs
|
1532
|
+
# each time the function is called, as does the #body. Distinguishing #setup
|
1533
|
+
# from #body is useful for two reasons: first, #setup is guaranteed to execute
|
1534
|
+
# before #body, and, second, one can avoid setting up the same variable twice,
|
1535
|
+
# because of the key.
|
1536
|
+
#
|
1537
|
+
# returns "2*x"
|
1538
|
+
#
|
1539
|
+
# Specifies the string used in the final return statement of the function.
|
1540
|
+
# Subsequent uses of this method clobber the previous value. Alternately, one
|
1541
|
+
# can simply insert a "return" manually in the body.
|
1542
|
+
#
|
1543
|
+
# === Method Classes
|
1544
|
+
#
|
1545
|
+
# Method
|
1546
|
+
# ModuleFunction
|
1547
|
+
# GlobalFunction
|
1548
|
+
# SingletonMethod
|
1549
|
+
#
|
1550
|
+
# These subclasses of the Function template are designed for coding
|
1551
|
+
# Ruby-callable methods in C. The necessary registration (+rb_define_method+,
|
1552
|
+
# etc.) is handled automatically. Defaults are different from Function: +'VALUE
|
1553
|
+
# self'+ is automatically an argument, and argument and return types are assumed
|
1554
|
+
# to be +'VALUE'+ and can be omitted by the caller. The return value is +nil+ by
|
1555
|
+
# default.
|
1556
|
+
#
|
1557
|
+
# === Method Arguments
|
1558
|
+
#
|
1559
|
+
# There are three ways to declare arguments, corresponding to the three ways
|
1560
|
+
# provided by the Ruby interpreter's C API.
|
1561
|
+
#
|
1562
|
+
# arguments :arg1, :arg2, ...
|
1563
|
+
#
|
1564
|
+
# The default way of specifying arguments. Allows a fixed number of VALUE
|
1565
|
+
# arguments.
|
1566
|
+
#
|
1567
|
+
# c_array_args argc_name = 'argc', argv_name = 'argv', &block
|
1568
|
+
#
|
1569
|
+
# rb_array_args args_name = 'args'
|
1570
|
+
#
|
1571
|
+
# Specifies that arguments are to be collected and passed in a C or Ruby array,
|
1572
|
+
# instead of individually (which is the default). In each case, the array of
|
1573
|
+
# actual arguments will be bound to a C parameter with the name specified. See
|
1574
|
+
# the Ruby API documentation for details.
|
1575
|
+
#
|
1576
|
+
# If a block is given to Method#c_array_args, it will be used to specify a call
|
1577
|
+
# to the API function +rb_scan_args+ and to declare the associated variables.
|
1578
|
+
# For example:
|
1579
|
+
#
|
1580
|
+
# c_array_args('argc', 'argv') {
|
1581
|
+
# required :arg0, :arg1
|
1582
|
+
# optional :arg2, :arg3, :arg4
|
1583
|
+
# rest :rest
|
1584
|
+
# block :block
|
1585
|
+
# }
|
1586
|
+
#
|
1587
|
+
# declares all the listed symbols as variables of type +VALUE+ in function
|
1588
|
+
# scope, and arranges for the following to be called in the #setup clause (i.e.,
|
1589
|
+
# before the #body):
|
1590
|
+
#
|
1591
|
+
# rb_scan_args(argc, argv, "23*&", &arg0, &arg1, &arg2,
|
1592
|
+
# &arg3, &arg4, &rest, &block);
|
1593
|
+
#
|
1594
|
+
# The <tt>'argc', 'argv'</tt> are the default values and are usually omitted.
|
1595
|
+
#
|
1596
|
+
# The lines in the block can occur in any order, and any line can be omitted.
|
1597
|
+
# However, only one line of each kind should be used. In addition, each optional
|
1598
|
+
# argument can be associated with a fragment of C code that will be executed to
|
1599
|
+
# assign it a default value, if needed. For example, one can add the following
|
1600
|
+
# lines to the above block:
|
1601
|
+
#
|
1602
|
+
# default :arg3 => "INT2NUM(7)",
|
1603
|
+
# :arg4 => "INT2NUM(NUM2INT(arg2) + NUM2INT(arg3))"
|
1604
|
+
#
|
1605
|
+
# Otherwise, optional arguments are assigned nil.
|
1606
|
+
#
|
1607
|
+
# In this case, if +arg4+ is not provided by +argv+, then it is initialized
|
1608
|
+
# using the code given. If, in addition, +arg3+ is not provided, then it too is
|
1609
|
+
# initialized. These initializations happen in the #setup clause of the Function
|
1610
|
+
# template and are executed in the same order as the arguments are given in the
|
1611
|
+
# +optional+ line.
|
1612
|
+
#
|
1613
|
+
# Finally, argument types can be checked automatically:
|
1614
|
+
#
|
1615
|
+
# typecheck :arg2 => Numeric, :arg3 => Numeric
|
1616
|
+
#
|
1617
|
+
# The value passed to the function must either be +nil+ or match the type. Note
|
1618
|
+
# that type checking happens *before* default assignment, so that default
|
1619
|
+
# calculation code can assume types are correct. No typechecking code is
|
1620
|
+
# generated if the type is Object.
|
1660
1621
|
class Function < CFragment
|
1661
1622
|
|
1662
1623
|
def initialize name, parent
|
@@ -1932,7 +1893,11 @@ class SingletonMethod < RubyFunction
|
|
1932
1893
|
end
|
1933
1894
|
end
|
1934
1895
|
|
1935
|
-
|
1896
|
+
# A Structure instance keeps track of data members added to a struct.
|
1897
|
+
#
|
1898
|
+
# declare :x => "int x"
|
1899
|
+
#
|
1900
|
+
# Adds the specified string to define a structure member.
|
1936
1901
|
class Structure < CFragment
|
1937
1902
|
|
1938
1903
|
class InheritAccumulator < Accumulator; include SetAccumulator; end
|
@@ -1964,6 +1929,13 @@ OpName= {
|
|
1964
1929
|
'==' => :op_eqeq
|
1965
1930
|
}
|
1966
1931
|
|
1932
|
+
# Generates a unique C itentifier from the given Ruby identifier, which may
|
1933
|
+
# include +/[@$?!]/+, +'::'+, and even +'.'+. (Some special globals are not yet
|
1934
|
+
# supported: +$:+ and +$-I+, for example.)
|
1935
|
+
#
|
1936
|
+
# It is unique in the sense that distinct Ruby identifiers map to distinct C
|
1937
|
+
# identifiers. (Not completely checked. Might fail for some really obscure
|
1938
|
+
# cases.)
|
1967
1939
|
def CGenerator.make_c_name s
|
1968
1940
|
s = s.to_s
|
1969
1941
|
OpName[s] || translate_ruby_identifier(s)
|
@@ -2014,7 +1986,7 @@ end # module CGenerator
|
|
2014
1986
|
|
2015
1987
|
class String
|
2016
1988
|
|
2017
|
-
#
|
1989
|
+
# Tabs left or right by n chars, using spaces.
|
2018
1990
|
def tab n
|
2019
1991
|
if n >= 0
|
2020
1992
|
gsub(/^/, ' ' * n)
|
@@ -2023,8 +1995,8 @@ class String
|
|
2023
1995
|
end
|
2024
1996
|
end
|
2025
1997
|
|
2026
|
-
#
|
2027
|
-
#
|
1998
|
+
# The first non-empty line is adjusted to have n spaces before the first
|
1999
|
+
# nonspace. Additional lines are changed to preserve relative tabbing.
|
2028
2000
|
def tabto n
|
2029
2001
|
if self =~ /^( *)\S/
|
2030
2002
|
tab(n - $1.length)
|
@@ -2033,7 +2005,7 @@ class String
|
|
2033
2005
|
end
|
2034
2006
|
end
|
2035
2007
|
|
2036
|
-
#
|
2008
|
+
# Aligns each line to have n spaces before the first non-space.
|
2037
2009
|
def taballto n
|
2038
2010
|
gsub(/^ */, ' ' * n)
|
2039
2011
|
end
|
data/lib/cgen/cshadow.rb
CHANGED
@@ -712,7 +712,6 @@ module CShadow
|
|
712
712
|
|
713
713
|
private
|
714
714
|
|
715
|
-
# :stopdoc:
|
716
715
|
def check_overwrite_shadow_attrs(*symbols)
|
717
716
|
for attr in shadow_attrs
|
718
717
|
for sym in symbols
|
@@ -737,20 +736,19 @@ module CShadow
|
|
737
736
|
check_overwrite_shadow_attrs(*args)
|
738
737
|
super
|
739
738
|
end
|
740
|
-
# :startdoc:
|
741
739
|
|
742
740
|
# Same as #shadow_attr with the +:reader+ and +:writer+ options.
|
743
|
-
def shadow_attr_accessor(*args)
|
741
|
+
def shadow_attr_accessor(*args) # :doc:
|
744
742
|
shadow_attr :reader, :writer, *args
|
745
743
|
end
|
746
744
|
|
747
745
|
# Same as #shadow_attr with the +:reader+ option.
|
748
|
-
def shadow_attr_reader(*args)
|
746
|
+
def shadow_attr_reader(*args) # :doc:
|
749
747
|
shadow_attr :reader, *args
|
750
748
|
end
|
751
749
|
|
752
750
|
# Same as #shadow_attr with the +:writer+ option.
|
753
|
-
def shadow_attr_writer(*args)
|
751
|
+
def shadow_attr_writer(*args) # :doc:
|
754
752
|
shadow_attr :writer, *args
|
755
753
|
end
|
756
754
|
|
@@ -783,7 +781,7 @@ module CShadow
|
|
783
781
|
#
|
784
782
|
# Typically, #shadow_attr_accessor and so on are called instead.
|
785
783
|
#
|
786
|
-
def shadow_attr(*args)
|
784
|
+
def shadow_attr(*args) # :doc:
|
787
785
|
attr_persists = true
|
788
786
|
for arg in args
|
789
787
|
case arg
|