+ map(c_out_decl($_), @$returns)),
+ ") {\n");
+ if(!defined $returns or scalar @$returns == 0) {
+ # Simple case
+ push(@c, " return disorder_simple(",
+ join(", ", "c", "NULL", "\"$cmd\"", @cargs, "(char *)NULL"),
+ ");\n");
+ } elsif(scalar @$returns == 1
+ and $returns->[0]->[0] eq 'queue-one') {
+ # Special case
+ my $return = $$returns[0];
+ push(@c, " return onequeue(c, \"$cmd\", $return->[1]p);\n");
+ } elsif(scalar @$returns == 1
+ and $returns->[0]->[0] eq 'string-raw') {
+ # Special case
+ my $return = $$returns[0];
+ push(@c, " return disorder_simple(",
+ join(", ", "c", "$return->[1]p", "\"$cmd\"", @cargs, "(char *)NULL"),
+ ");\n");
+ } elsif(scalar @$returns == 1
+ and $returns->[0]->[0] eq 'pair-list') {
+ # Special case
+ my $return = $$returns[0];
+ push(@c, " return pairlist(",
+ join(", ", "c", "$return->[1]p", "\"$cmd\"",
+ @cargs,
+ "(char *)NULL"),
+ ");\n");
+ } else {
+ my $expected = 0;
+ for(my $n = 0; $n < scalar @$returns; ++$n) {
+ my $return = $returns->[$n];
+ my $type = $return->[0];
+ my $name = $return->[1];
+ if($type eq 'string'
+ or $type eq 'boolean'
+ or $type eq 'integer'
+ or $type eq 'time'
+ or $type eq 'user') {
+ ++$expected;
+ }
+ }
+ if($expected) {
+ push(@c, " char **v;\n",
+ " int nv, rc = disorder_simple_split(",
+ join(", ",
+ "c",
+ "&v",
+ "&nv",
+ $expected,
+ "\"$cmd\"",
+ @cargs,
+ "(char *)NULL"),
+ ");\n",
+ " if(rc)\n",
+ " return rc;\n");
+ } else {
+ push(@c,
+ " int rc = disorder_simple(",
+ join(", ",
+ "c",
+ "NULL",
+ "\"$cmd\"",
+ @cargs,
+ "(char *)NULL"),
+ ");\n",
+ " if(rc)\n",
+ " return rc;\n");
+ }
+ for(my $n = 0; $n < scalar @$returns; ++$n) {
+ my $return = $returns->[$n];
+ my $type = $return->[0];
+ my $name = $return->[1];
+ if($type eq 'string') {
+ push(@c,
+ " *${name}p = v[$n];\n",
+ " v[$n] = NULL;\n");
+ } elsif($type eq 'boolean') {
+ push(@c,
+ " if(boolean(\"$cmd\", v[$n], ${name}p))\n",
+ " return -1;\n");
+ } elsif($type eq 'integer') {
+ push(@c,
+ " *${name}p = atol(v[$n]);\n");
+ } elsif($type eq 'time') {
+ push(@c,
+ " *${name}p = atoll(v[$n]);\n");
+ } elsif($type eq 'user') {
+ push(@c,
+ " c->user = v[$n];\n",
+ " v[$n] = NULL;\n");
+ } elsif($type eq 'body') {
+ push(@c,
+ " if(readlist(c, ${name}p, n${name}p))\n",
+ " return -1;\n");
+ } elsif($type eq 'queue') {
+ push(@c,
+ " if(readqueue(c, ${name}p))\n",
+ " return -1;\n");
+ } else {
+ die "$0: C API: unknown return type '$type' for '$name'\n";
+ }
+ }
+ if($expected) {
+ push(@c,
+ " free_strings(nv, v);\n");
+ }
+ push(@c, " return 0;\n");
+ }
+ push(@c, "}\n\n");