Imported Upstream version 3.2.0
[debian/amanda] / perl / amglue / constants.swg
1 /*
2  * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16  *
17  * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
18  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19  */
20
21 /*
22  * This file contains SWIG macros to handle C constants, enums, and flags
23  */
24
25 %include "amglue/exports.swg"
26
27 /*
28  * Internal support for iterating over lists of symbols; users will define
29  * the list as e.g.,
30  *
31  *   #define FOR_ALL_WHATEVER(APPLY) APPLY(SYMBOL1) APPLY(SYMBOL2) ..
32  *
33  * and then passes FOR_ALL_WHATEVER as the FORALL_FN argument to one of the
34  * macros below.  This uses the "X Macro" trick; see
35  * http://www.drdobbs.com/blog/archives/2010/06/the_x_macro.html
36  *
37  * NOTE: SWIG's %define macros add C-style comments when they are expanded, so
38  * this method must use #define, not %define.  Also note that this always expands
39  * to a single line, making the result very ugly.
40  */
41
42 #define _amglue_apply_null(V) V
43 #define _amglue_apply_leading_scalar(V) $V
44 #define _amglue_apply_trailing_comma(V) V,
45 #define _amglue_apply_C_scalar(V) C<$V>
46 #define _amglue_forall_join_whitespace(FORALL_FN) FORALL_FN(_amglue_apply_null)
47 #define _amglue_forall_scalars(FORALL_FN) FORALL_FN(_amglue_apply_leading_scalar)
48 #define _amglue_forall_terminated_by_comma(FORALL_FN) FORALL_FN(_amglue_apply_trailing_comma)
49
50 /* Rather than try to use glib's flag/enum architecture, which is only used
51  * for a few constants (mostly in property.h), .swg files define constants using
52  * these macros.  A typical definition would look like:
53  *   amglue_add_flag_tag_fns(Permissions);
54  *   amglue_add_constant(PERM_READ, Permissions);
55  *   amglue_add_constant(PERM_WRITE, Permissions);
56  * note that the values of the constants do not appear here, although the header
57  * file in which they are defined must be included in the %{ .. %} block.
58  *
59  * The above would result in:
60  *  - typedef int Permissions;
61  *  - $PERM_READ and $PERM_WRITE in @EXPORT_OK
62  *  - $PERM_READ and $PERM_WRITE in %EXPORT_TAGS{'Permissions'}
63  *  - Permissions_to_strings($flags) -> ( name, name, .. )
64  *
65  * Similarly, amglue_add_enum_tag_fns(FileType) would add the same
66  * EXPORTs, but a function
67  *  - FileType_to_string($enum) -> name
68  */
69
70 %define amglue_add_flag_tag_fns(TAG)
71 typedef int TAG;
72 amglue_export_tag(TAG, TAG ## _to_strings);
73 %perlcode %{
74 my %_ ## TAG ## _VALUES;
75 # Convert a flag value to a list of names for flags that are set.
76 sub TAG ## _to_strings {
77     my ($flags) = @_;
78     my @result = ();
79
80     for my $k (keys %_ ## TAG ## _VALUES) {
81         my $v = $_ ## TAG ## _VALUES{$k};
82
83         # is this a matching flag?
84         if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
85             push @result, $k;
86         }
87     }
88
89     # by default, just return the number as a 1-element list
90     if (!@result) {
91         return ($flags);
92     }
93
94     return @result;
95 }
96 %}
97 %enddef
98
99 %define amglue_add_enum_tag_fns(TAG)
100 typedef int TAG;
101 amglue_export_tag(TAG, TAG ## _to_string);
102 %perlcode %{
103 my %_ ## TAG ## _VALUES;
104 # Convert an enum value to a single string
105 sub TAG ## _to_string {
106     my ($enumval) = @_;
107
108     for my $k (keys %_ ## TAG ## _VALUES) {
109         my $v = $_ ## TAG ## _VALUES{$k};
110
111         # is this a matching flag?
112         if ($enumval == $v) {
113             return $k;
114         }
115     }
116
117     # default, just return the number
118     return $enumval;
119 }
120 %}
121 %enddef
122
123 /* Add the given constant, assuming the constant name is the 
124  * short name
125  *
126  * @param CONSTNAME: the name of the constant, as used in C code
127  * @param TAG: the tag for this constant (enum name, etc.)
128  */
129 %define amglue_add_constant(CONSTNAME, TAG)
130 enum { CONSTNAME }; /* pass the constant to SWIG */
131 amglue_export_tag(TAG, $CONSTNAME);
132 %perlcode %{
133 $_ ## TAG ## _VALUES{`CONSTNAME`} = $CONSTNAME;
134 %}
135 %enddef
136
137 /* Add a bunch of constants all at once; this is more efficient with
138  * a large list of constants
139  *
140  * @param FORALL_FN: the FORALL_FN listing all of the constants (see above)
141  * @param TAG: the tag for these constants
142  */
143 #define amglue_add_constants(FORALL_FN, TAG) \
144 enum { _amglue_forall_terminated_by_comma(FORALL_FN) }; \
145 amglue_export_tag(TAG, _amglue_forall_scalars(FORALL_FN)) \
146 %perlcode %{ \
147     foreach (qw( _amglue_forall_join_whitespace(FORALL_FN))) { \
148         $_ ## TAG ## _VALUES{$_} = $$_; \
149     } \
150 %}
151
152 /* Add the given constant with a short name
153  *
154  * @param CONSTNAME: the name of the constant, as used in C code
155  * @param SHORTNAME: the name to be shown by TAG_to_string(s) (a string)
156  * @param TAG: the tag for this constant (enum name, etc.)
157  */
158 %define amglue_add_constant_short(CONSTNAME, SHORTNAME, TAG)
159 enum { CONSTNAME }; /* pass the constant to SWIG */
160 amglue_export_tag(TAG, $CONSTNAME);
161 %perlcode %{
162 $_ ## TAG ## _VALUES{`SHORTNAME`} = $CONSTNAME;
163 %}
164 %enddef
165
166 /* Add the given constant.  No shortname is supplied, so the constant
167  * will not be used for conversion to strings.  Use this function for
168  * bit combinations and other metadata, e.g., FOO_MASK or FOO_MAX
169  *
170  * @param CONSTNAME: the name of the constant, as used in C code
171  * @param TAG: the tag for this constant (enum name, etc.)
172  */
173 %define amglue_add_constant_noshort(CONSTNAME, TAG)
174 enum { CONSTNAME }; /* pass the constant to SWIG */
175 amglue_export_tag(TAG, $CONSTNAME);
176 %enddef
177
178 /* Return the symbols alone, separated by whitespace.  Note that this will
179  * being with whitespace, too.  Be careful if using it in POD.
180  *
181  * @param FORALL_FN: the forall function to use (see above)
182  */
183 #define amglue_constants_list(FORALL_FN) \
184     FORALL_FN(_amglue_apply_C_scalar)
185