1
/* libctl: flexible Guile-based control files for scientific software
2
* Copyright (C) 1998, 1999, 2000, 2001, 2002, Steven G. Johnson
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the
16
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
* Boston, MA 02111-1307, USA.
19
* Steven G. Johnson can be contacted at stevenj@alum.mit.edu.
28
/* This file contains glue code that enables us to call libctl from
29
Fortran. We have to take into account several things:
31
1) All Fortran parameters are passed by reference.
33
2) Fortran compilers are case-insensitive, so they munge identifiers
34
in a weird way for the linker. If we want a Fortran program to
35
be able to call us, we have to munge our identifiers in the same
36
way. (We do this with the F77_FUNC macro--every Fortran compiler
37
is different. F77_FUNC is determined by the configure script.)
39
3) Fortran represents strings in a different way than C. To handle
40
this, we require that Fortran callers pass us the length of a
41
string as an explicit parameter. We also have to include ugly
42
hacks to accomodate the fact that Cray Fortran compilers pass
43
a data structure instead of a char* for string parameters.
45
4) On some machines, C functions return their results in a way
46
that the Fortran compiler can't handle. To get around this,
47
all return results of functions are converted into an extra parameter.
49
The name of our Fortran routines is the same as the corresponding
50
C routine with the underscores removed. So, we to construct the
51
Fortran call, you do something like:
53
C: foo = bar_baz(x,y,z);
54
Fortran: call barbaz(x,y,z,foo)
56
C: foo = bar_baz(x,string,y);
57
Fortran: call barbaz(x,string,length(string),y,foo)
59
(Note that string parameters get converted into two parameters: the
60
string and its length.)
63
#ifdef F77_FUNC /* if we know how to mangle identifiers for Fortran */
65
/**************************************************************************/
67
/* Convert Fortran string parameters to C char*. This is required
68
in order to accomodate the ugly things that the Cray compilers do. */
70
#if defined(CRAY) || defined(_UNICOS) || defined(_CRAYMPP)
72
typedef _fcd fortran_string;
73
#define fcp2ccp(fs) _fcdtocp(fs)
75
typedef char *fortran_string;
76
#define fcp2ccp(fs) (fs)
79
/**************************************************************************/
82
(vector3 can be declared as an array of 3 reals in Fortran) */
84
void F77_FUNC(vector3scale,VECTOR3SCALE)
85
(number *s, vector3 *v, vector3 *vscaled)
87
*vscaled = vector3_scale(*s,*v);
90
void F77_FUNC(vector3plus,VECTOR3PLUS)
91
(vector3 *v1, vector3 *v2, vector3 *vresult)
93
*vresult = vector3_plus(*v1,*v2);
96
void F77_FUNC(vector3minus,VECTOR3MINUS)
97
(vector3 *v1, vector3 *v2, vector3 *vresult)
99
*vresult = vector3_minus(*v1,*v2);
102
void F77_FUNC(vector3cross,VECTOR3CROSS)
103
(vector3 *v1, vector3 *v2, vector3 *vresult)
105
*vresult = vector3_cross(*v1,*v2);
108
void F77_FUNC(vector3dot,VECTOR3DOT)
109
(vector3 *v1, vector3 *v2, number *result)
111
*result = vector3_dot(*v1,*v2);
114
void F77_FUNC(vector3norm,VECTOR3DOT)
115
(vector3 *v, number *result)
117
*result = vector3_norm(*v);
120
/**************************************************************************/
122
/* variable get/set functions */
124
/* Note that list and object variables in Fortran should be declared
125
as something the same size as the corresponding type in C. (This
126
turns out to be the same size as a long int.) */
130
void F77_FUNC(ctlgetnumber,CTLGETNUMBER)
131
(fortran_string identifier, int *length, number *result)
133
char *s = fcp2ccp(identifier); s[*length] = 0;
134
*result = ctl_get_number(s);
137
void F77_FUNC(ctlgetinteger,CTLGETINTEGER)
138
(fortran_string identifier, int *length, integer *result)
140
char *s = fcp2ccp(identifier); s[*length] = 0;
141
*result = ctl_get_integer(s);
144
void F77_FUNC(ctlgetboolean,CTLGETBOOLEAN)
145
(fortran_string identifier, int *length, boolean *result)
147
char *s = fcp2ccp(identifier); s[*length] = 0;
148
*result = ctl_get_boolean(s);
151
void F77_FUNC(ctlgetlist,CTLGETLIST)
152
(fortran_string identifier, int *length, list *result)
154
char *s = fcp2ccp(identifier); s[*length] = 0;
155
*result = ctl_get_list(s);
158
void F77_FUNC(ctlgetobject,CTLGETOBJECT)
159
(fortran_string identifier, int *length, object *result)
161
char *s = fcp2ccp(identifier); s[*length] = 0;
162
*result = ctl_get_object(s);
165
void F77_FUNC(ctlgetvector3,CTLGETVECTOR3)
166
(fortran_string identifier, int *length, vector3 *result)
168
char *s = fcp2ccp(identifier); s[*length] = 0;
169
*result = ctl_get_vector3(s);
172
/* ctl_get_string doesn't work perfectly--there
173
is no portable way to set the length of the Fortran string.
174
The length is returned in result_length. */
175
void F77_FUNC(ctlgetstring,CTLGETSTRING)
176
(fortran_string identifier, int *length,
177
fortran_string result, int *result_length)
180
char *s = fcp2ccp(identifier); s[*length] = 0;
181
r = ctl_get_string(s);
182
strncpy(fcp2ccp(result), r, *result_length);
183
if (*result_length < strlen(r))
184
*result_length = strlen(r);
190
void F77_FUNC(ctlsetnumber,CTLSETNUMBER)
191
(fortran_string identifier, int *length, number *value)
193
char *s = fcp2ccp(identifier); s[*length] = 0;
194
ctl_set_number(s, *value);
197
void F77_FUNC(ctlsetinteger,CTLSETINTEGER)
198
(fortran_string identifier, int *length, integer *value)
200
char *s = fcp2ccp(identifier); s[*length] = 0;
201
ctl_set_integer(s, *value);
204
void F77_FUNC(ctlsetboolean,CTLSETBOOLEAN)
205
(fortran_string identifier, int *length, boolean *value)
207
char *s = fcp2ccp(identifier); s[*length] = 0;
208
ctl_set_boolean(s, *value);
211
void F77_FUNC(ctlsetlist,CTLSETLIST)
212
(fortran_string identifier, int *length, list *value)
214
char *s = fcp2ccp(identifier); s[*length] = 0;
215
ctl_set_list(s, *value);
218
void F77_FUNC(ctlsetobject,CTLSETOBJECT)
219
(fortran_string identifier, int *length, object *value)
221
char *s = fcp2ccp(identifier); s[*length] = 0;
222
ctl_set_object(s, *value);
225
void F77_FUNC(ctlsetvector3,CTLSETVECTOR3)
226
(fortran_string identifier, int *length, vector3 *value)
228
char *s = fcp2ccp(identifier); s[*length] = 0;
229
ctl_set_vector3(s, *value);
232
void F77_FUNC(ctlsetstring,CTLSETSTRING)
233
(fortran_string identifier, int *length,
234
fortran_string value, int *value_length)
236
char *s = fcp2ccp(identifier);
237
char *v = fcp2ccp(value);
239
v[*value_length] = 0;
240
ctl_set_string(s, v);
243
/**************************************************************************/
247
void F77_FUNC(listlength,LISTLENGTH)(list *l, int *len)
249
*len = list_length(*l);
252
void F77_FUNC(numberlistref,NUMBERLISTREF)
253
(list *l, int *index, number *value)
255
*value = number_list_ref(*l, *index);
258
void F77_FUNC(integerlistref,INTEGERLISTREF)
259
(list *l, int *index, integer *value)
261
*value = integer_list_ref(*l, *index);
264
void F77_FUNC(booleanlistref,BOOLEANLISTREF)
265
(list *l, int *index, boolean *value)
267
*value = boolean_list_ref(*l, *index);
270
void F77_FUNC(vector3listref,VECTOR3LISTREF)
271
(list *l, int *index, vector3 *value)
273
*value = vector3_list_ref(*l, *index);
276
void F77_FUNC(listlistref,LISTLISTREF)
277
(list *l, int *index, list *value)
279
*value = list_list_ref(*l, *index);
282
void F77_FUNC(objectlistref,OBJECTLISTREF)
283
(list *l, int *index, object *value)
285
*value = object_list_ref(*l, *index);
288
void F77_FUNC(stringlistref,STRINGLISTREF)
289
(list *l, int *index, fortran_string value, int *value_length)
292
v = string_list_ref(*l, *index);
293
strncpy(fcp2ccp(value), v, *value_length);
294
if (*value_length < strlen(v))
295
*value_length = strlen(v);
299
/**************************************************************************/
303
void F77_FUNC(makenumberlist,MAKENUMBERLIST)
304
(int *num_items, number *items, list *result)
306
*result = make_number_list(*num_items, items);
309
void F77_FUNC(makeintegerlist,MAKEINTEGERLIST)
310
(int *num_items, integer *items, list *result)
312
*result = make_integer_list(*num_items, items);
315
void F77_FUNC(makebooleanlist,MAKEBOOLEANLIST)
316
(int *num_items, boolean *items, list *result)
318
*result = make_boolean_list(*num_items, items);
321
void F77_FUNC(makevector3list,MAKEVECTOR3LIST)
322
(int *num_items, vector3 *items, list *result)
324
*result = make_vector3_list(*num_items, items);
327
void F77_FUNC(makelistlist,MAKELISTLIST)
328
(int *num_items, list *items, list *result)
330
*result = make_list_list(*num_items, items);
333
void F77_FUNC(makeobjectlist,MAKEOBJECTLIST)
334
(int *num_items, object *items, list *result)
336
*result = make_object_list(*num_items, items);
339
/* make_string_list is not supported. Strings in Fortran suck. */
341
/**************************************************************************/
343
/* object properties */
345
void F77_FUNC(objectismember,OBJECTISMEMBER)
346
(fortran_string type_name, int *length, object *o, boolean *result)
348
char *s = fcp2ccp(type_name); s[*length] = 0;
349
*result = object_is_member(s,*o);
352
void F77_FUNC(numberobjectproperty,NUMBEROBJECTPROPERTY)
353
(object *o, fortran_string property_name, int *length, number *result)
355
char *s = fcp2ccp(property_name); s[*length] = 0;
356
*result = number_object_property(*o,s);
359
void F77_FUNC(integerobjectproperty,INTEGEROBJECTPROPERTY)
360
(object *o, fortran_string property_name, int *length, integer *result)
362
char *s = fcp2ccp(property_name); s[*length] = 0;
363
*result = integer_object_property(*o,s);
366
void F77_FUNC(booleanobjectproperty,BOOLEANOBJECTPROPERTY)
367
(object *o, fortran_string property_name, int *length, boolean *result)
369
char *s = fcp2ccp(property_name); s[*length] = 0;
370
*result = boolean_object_property(*o,s);
373
void F77_FUNC(vector3objectproperty,VECTOR3OBJECTPROPERTY)
374
(object *o, fortran_string property_name, int *length, vector3 *result)
376
char *s = fcp2ccp(property_name); s[*length] = 0;
377
*result = vector3_object_property(*o,s);
380
void F77_FUNC(listobjectproperty,LISTOBJECTPROPERTY)
381
(object *o, fortran_string property_name, int *length, list *result)
383
char *s = fcp2ccp(property_name); s[*length] = 0;
384
*result = list_object_property(*o,s);
387
void F77_FUNC(objectobjectproperty,OBJECTOBJECTPROPERTY)
388
(object *o, fortran_string property_name, int *length, object *result)
390
char *s = fcp2ccp(property_name); s[*length] = 0;
391
*result = object_object_property(*o,s);
394
void F77_FUNC(stringobjectproperty,STRINGOBJECTPROPERTY)
395
(object *o, fortran_string property_name, int *length,
396
fortran_string result, int *result_length)
399
char *s = fcp2ccp(property_name); s[*length] = 0;
400
r = string_object_property(*o,s);
401
strncpy(fcp2ccp(result), r, *result_length);
402
if (*result_length < strlen(r))
403
*result_length = strlen(r);
407
/**************************************************************************/
409
#endif /* F77_FUNC */