cgen 0.16.0 → 0.16.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.
- 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
|