/* Macros used by coccinelle-generated code */
-#define SMPI_INITIALIZE_GLOBAL(name,type) \
- NULL; \
+#define SMPI_VARINIT_GLOBAL(name,type) \
+type *name = NULL; \
void __attribute__((weak,constructor)) __preinit_##name(void) { \
if(!name) \
name = (type*)malloc(smpi_global_size() * sizeof(type)); \
name = NULL; \
}
-#define SMPI_INITIALIZE_AND_SET_GLOBAl(name,type,expr) \
- NULL; \
+#define SMPI_VARINIT_GLOBAL_AND_SET(name,type,expr) \
+type *name = NULL; \
void __attribute__((weak,constructor)) __preinit_##name(void) { \
size_t size = smpi_global_size(); \
size_t i; \
name = NULL; \
}
-#define SMPI_GLOBAL_VAR_LOCAL_ACCESS(name) name[smpi_process_index()]
+#define SMPI_VARGET_GLOBAL(name) name[smpi_process_index()]
#endif
--- /dev/null
+#!/usr/bin/perl
+
+# FIXME: here we make the assumption that people don't do things like put
+# multiple statements after a declaration, but separated by semicolons. It's a
+# reasonable assumption for the time being, but technically it could cause
+# problems for some code.
+OUTER: while ($line = <STDIN>) {
+ if ($line =~ /#include <mpi\.h>/) {
+ print "#include <smpi.h>\n";
+ print "#include <smpi_cocci.h>\n";
+ } elsif ($line =~ /SMPI_VARINIT/) {
+ do {
+ chomp $line;
+ $line =~ s/\s+/ /g;
+ while ($line =~ s/(SMPI_VARINIT[A-Z0-9_]*?\(.*?\))//) {
+ print "$1\n";
+ }
+ if ($line =~ /SMPI_VARINIT/) {
+ # should only happen for bad code...
+ if (!($nextline = <STDIN>)) {
+ last OUTER;
+ }
+ $line .= $nextline;
+
+ }
+ } while ($line =~ /SMPI_VARINIT/);
+ } else {
+ print $line;
+ }
+}
+// FIXME: seems like cocci has problems manipulating the declarations, at least
+// when there is more than one on the same line. We already need perl to split
+// up the declarations after the fact, is there another tool we can use to patch
+// up and match the declarations? In that case we could consider dropping cocci,
+// or just using it to alter global variable accesses.
+//
// FIXME: problems
-// - does not want to match dynamic arrays...
+// - array declarations not properly matched...can fix, but then can't have
+// multiple declarations on one line
// - does not match array initializers
+// - probably won't fix structure declarations with initialization either
// Function prototype looks like variable dec, but has parentheses
@funcproto@
identifier var;
position p != { localvardecl.p, funcproto.p };
expression value;
-constant size;
+expression size;
@@
(
T@p
- var
-+ *var = SMPI_INITIALIZE_GLOBAL(var, T)
++ *var = SMPI_VARINIT_GLOBAL(var, T)
;
|
T@p
- var = value
-+ *var = SMPI_INITIALIZE_AND_SET_GLOBAL(var, T, value)
-;
-|
-T@p
-- var[]
-+ *var[] = SMPI_INITIALIZE_GLOBAL_ARRAY(T, size)
-;
-|
-T@p
-- var[size]
-+ *var[] = SMPI_INITIALIZE_GLOBAL_STATIC_ARRAY(T, size)
-;
-|
-T@p
-- var[size] = { ... }
-+ *var[] = SMPI_INITIALIZE_AND_SET_GLOBAL_STATIC_ARRAY(T, size)
++ *var = SMPI_VARINIT_GLOBAL_AND_SET(var, T, value)
;
+//|
+//T@p // FIXME: matches, but complains if more than one decl on a line...
+//- var[size]
+//+ *var[size] = SMPI_VARINIT_GLOBAL_ARRAY(T, size)
+//;
+//|
+//T@p // FIXME: how to match initializer?
+//- var[size] = { ... }
+//+ *var[] = SMPI_VARINIT_GLOBAL_ARRAY_AND_SET(T, size, { ... })
+//;
+//|
+//T@p // FIXME: how to match initializer? how to figure out size?
+//- var[] = { ... }
+//+ *var[] = SMPI_VARINIT_GLOBAL_ARRAY_AND_SET(T, size, { ... }) // size = ?
+//;
)
@rewritelocalaccess@
(
lvar
|
-+SMPI_GLOBAL_VAR_LOCAL_ACCESS(
++SMPI_VARGET_GLOBAL(
var
+)
)