~ubuntu-branches/debian/stretch/libxr/stretch

« back to all changes in this revision

Viewing changes to xdl-compiler/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabien Boucher
  • Date: 2009-10-14 00:52:51 UTC
  • Revision ID: james.westby@ubuntu.com-20091014005251-epx05xv5ef9188q0
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * Copyright 2006-2008 Ondrej Jirman <ondrej.jirman@zonio.net>
 
3
 * 
 
4
 * This file is part of libxr.
 
5
 *
 
6
 * Libxr is free software: you can redistribute it and/or modify it under the
 
7
 * terms of the GNU Lesser General Public License as published by the Free
 
8
 * Software Foundation, either version 2 of the License, or (at your option) any
 
9
 * later version.
 
10
 *
 
11
 * Libxr is distributed in the hope that it will be useful, but WITHOUT ANY
 
12
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 
13
 * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 
14
 * details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public License
 
17
 * along with libxr.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include <glib.h>
 
21
#include <stdio.h>
 
22
#include <stdlib.h>
 
23
#include <string.h>
 
24
 
 
25
#include "xdl.h"
 
26
 
 
27
/* codegen helpers */
 
28
 
 
29
#define EL(i, fmt, args...) \
 
30
  line_fprintf(f, i, fmt "\n", ##args)
 
31
 
 
32
#define E(i, fmt, args...) \
 
33
  line_fprintf(f, i, fmt, ##args)
 
34
 
 
35
#define NL \
 
36
  line_fprintf(f, 0, "\n")
 
37
 
 
38
#define S(args...) \
 
39
  g_strdup_printf(args)
 
40
 
 
41
#define OPEN(fmt, args...) { \
 
42
  if (f) \
 
43
    fclose(f); \
 
44
  f = fopen(current_file = S(fmt, ##args), "w"); \
 
45
  if (f == NULL) { \
 
46
    fprintf(stderr, "Can't open output file for writing."); exit(1); } \
 
47
  } \
 
48
  current_line = 1
 
49
 
 
50
static int current_line;
 
51
static char* current_file = NULL;
 
52
 
 
53
static void line_fprintf(FILE* f, int indent, const char* fmt, ...)
 
54
{
 
55
  int i;
 
56
  va_list ap;
 
57
 
 
58
  for (i=0; i<indent; i++)
 
59
    fprintf(f, "    ");
 
60
 
 
61
  va_start(ap, fmt);
 
62
  char* v = g_strdup_vprintf(fmt, ap);
 
63
  va_end(ap);
 
64
 
 
65
  fprintf(f, "%s", v);
 
66
 
 
67
  for (i=0; i<strlen(v); i++)
 
68
    if (v[i] == '\n')
 
69
      current_line++;
 
70
}
 
71
 
 
72
#define ORIG_LINE() \
 
73
  EL(0, "#line %d \"%s\"", current_line+1, current_file)
 
74
 
 
75
#define FILE_LINE(_line, _file) \
 
76
  EL(0, "#line %d \"%s\"", _line, _file)
 
77
 
 
78
#define STUB(s) \
 
79
  do { \
 
80
    if (s) \
 
81
    { \
 
82
      FILE_LINE(s##_line+1, xdl_file); \
 
83
      EL(0, "%s", s); \
 
84
      ORIG_LINE(); \
 
85
    } \
 
86
  } while(0)
 
87
 
 
88
static void gen_type_marchalizers(FILE* f, xdl_typedef* t)
 
89
{
 
90
  GSList *i, *j, *k;
 
91
    if (t->type == TD_STRUCT)
 
92
    {
 
93
      EL(0, "G_GNUC_UNUSED static xr_value* %s(%s _nstruct)", t->march_name, t->ctype);
 
94
      EL(0, "{");
 
95
      EL(1, "xr_value* _struct;");
 
96
      for (k=t->struct_members; k; k=k->next)
 
97
      {
 
98
        xdl_struct_member* m = k->data;
 
99
        EL(1, "xr_value* %s = NULL;", m->name);
 
100
      }
 
101
      NL;
 
102
      EL(1, "if (_nstruct == NULL)");
 
103
      EL(2, "return NULL;");
 
104
      NL;
 
105
      EL(1, "if (");
 
106
      for (k=t->struct_members; k; k=k->next)
 
107
      {
 
108
        xdl_struct_member* m = k->data;
 
109
        EL(2, "(%s = %s(_nstruct->%s)) == NULL%s", m->name, m->type->march_name, m->name, k->next ? " ||" : "");
 
110
      }
 
111
      EL(1, ")");
 
112
      EL(1, "{");
 
113
      for (k=t->struct_members; k; k=k->next)
 
114
      {
 
115
        xdl_struct_member* m = k->data;
 
116
        EL(2, "xr_value_unref(%s);", m->name);
 
117
      }
 
118
      EL(2, "return NULL;");
 
119
      EL(1, "}");
 
120
      NL;
 
121
      EL(1, "_struct = xr_value_struct_new();");
 
122
      for (k=t->struct_members; k; k=k->next)
 
123
      {
 
124
        xdl_struct_member* m = k->data;
 
125
        EL(1, "xr_value_struct_set_member(_struct, \"%s\", %s);", m->name, m->name);
 
126
      }
 
127
      EL(1, "return _struct;");
 
128
      EL(0, "}");
 
129
      NL;
 
130
 
 
131
      EL(0, "G_GNUC_UNUSED static gboolean %s(xr_value* _struct, %s* _nstruct)", t->demarch_name, t->ctype);
 
132
      EL(0, "{");
 
133
      EL(1, "%s _tmp_nstruct;", t->ctype);
 
134
      NL;
 
135
      EL(1, "g_return_val_if_fail(_nstruct != NULL, FALSE);");
 
136
      NL;
 
137
      EL(1, "if (_struct == NULL || xr_value_get_type(_struct) != XRV_STRUCT)");
 
138
      EL(2, "return FALSE;");
 
139
      NL;
 
140
      EL(1, "_tmp_nstruct = %s_new();", t->cname);
 
141
      EL(1, "if (");
 
142
      for (k=t->struct_members; k; k=k->next)
 
143
      {
 
144
        xdl_struct_member* m = k->data;
 
145
        EL(2, "!%s(xr_value_get_member(_struct, \"%s\"), &_tmp_nstruct->%s)%s", m->type->demarch_name, m->name, m->name, k->next ? " ||" : "");
 
146
      }
 
147
      EL(1, ")");
 
148
      EL(1, "{");
 
149
      EL(2, "%s(_tmp_nstruct);", t->free_func);
 
150
      EL(2, "return FALSE;");
 
151
      EL(1, "}");
 
152
      NL;
 
153
      EL(1, "*_nstruct = _tmp_nstruct;");
 
154
      EL(1, "return TRUE;");
 
155
      EL(0, "}");
 
156
      NL;
 
157
    }
 
158
    else if (t->type == TD_ARRAY)
 
159
    {
 
160
      EL(0, "G_GNUC_UNUSED static xr_value* %s(%s _narray)", t->march_name, t->ctype);
 
161
      EL(0, "{");
 
162
      EL(1, "GSList* _item;");
 
163
      EL(1, "xr_value* _array = xr_value_array_new();");
 
164
      NL;
 
165
      EL(1, "for (_item = _narray; _item; _item = _item->next)");
 
166
      EL(1, "{");
 
167
      EL(2, "xr_value* _item_value = %s((%s)_item->data);", t->item_type->march_name, t->item_type->ctype);
 
168
      NL;
 
169
      EL(2, "if (_item_value == NULL)");
 
170
      EL(2, "{");
 
171
      EL(3, "xr_value_unref(_array);");
 
172
      EL(3, "return NULL;");
 
173
      EL(2, "}");
 
174
      NL;
 
175
      EL(2, "xr_value_array_append(_array, _item_value);");
 
176
      EL(1, "}");
 
177
      NL;
 
178
      EL(1, "return _array;");
 
179
      EL(0, "}");
 
180
      NL;
 
181
 
 
182
      EL(0, "G_GNUC_UNUSED static gboolean %s(xr_value* _array, %s* _narray)", t->demarch_name, t->ctype);
 
183
      EL(0, "{");
 
184
      EL(1, "GSList *_tmp_narray = NULL, *_item;");
 
185
      NL;
 
186
      EL(1, "g_return_val_if_fail(_narray != NULL, FALSE);");
 
187
      NL;
 
188
      EL(1, "if (_array == NULL || xr_value_get_type(_array) != XRV_ARRAY)");
 
189
      EL(2, "return FALSE;");
 
190
      NL;
 
191
      EL(1, "for (_item = xr_value_get_items(_array); _item; _item = _item->next)");
 
192
      EL(1, "{");
 
193
      EL(2, "%s _item_value = %s;", t->item_type->ctype, t->item_type->cnull);
 
194
      NL;
 
195
      EL(2, "if (!%s((xr_value*)_item->data, &_item_value))", t->item_type->demarch_name);
 
196
      EL(2, "{");
 
197
      EL(3, "%s(_tmp_narray);", t->free_func);
 
198
      EL(3, "return FALSE;");
 
199
      EL(2, "}");
 
200
      NL;
 
201
      EL(2, "_tmp_narray = g_slist_append(_tmp_narray, (void*)_item_value);");
 
202
      EL(1, "}");
 
203
      NL;
 
204
      EL(1, "*_narray = _tmp_narray;");
 
205
      EL(1, "return TRUE;");
 
206
      EL(0, "}");
 
207
      NL;
 
208
    }
 
209
}
 
210
 
 
211
static void gen_type_freealloc(FILE* f, xdl_typedef* t, int def)
 
212
{
 
213
  GSList *i, *j, *k;
 
214
 
 
215
  if (def)
 
216
  {
 
217
    if (t->type == TD_STRUCT)
 
218
      EL(0, "%s %s_new();", t->ctype, t->cname);
 
219
    if (t->type == TD_STRUCT || t->type == TD_ARRAY)
 
220
    {
 
221
      EL(0, "void %s(%s val);", t->free_func, t->ctype);
 
222
      EL(0, "%s %s(%s orig);", t->ctype, t->copy_func, t->ctype);
 
223
    }
 
224
    return;
 
225
  }
 
226
 
 
227
  if (t->type == TD_STRUCT)
 
228
  {
 
229
    /* new */
 
230
    EL(0, "%s %s_new()", t->ctype, t->cname);
 
231
    EL(0, "{");
 
232
    EL(1, "return g_new0(%s, 1);", t->cname);
 
233
    EL(0, "}");
 
234
    NL;
 
235
 
 
236
    /* free */
 
237
    EL(0, "void %s(%s val)", t->free_func, t->ctype);
 
238
    EL(0, "{");
 
239
    EL(1, "if (val == NULL)");
 
240
    EL(2, "return;");
 
241
    NL;
 
242
    for (k=t->struct_members; k; k=k->next)
 
243
    {
 
244
      xdl_struct_member* m = k->data;
 
245
      if (m->type->free_func)
 
246
        EL(1, "%s(val->%s);", m->type->free_func, m->name);
 
247
    }
 
248
    EL(1, "g_free(val);");
 
249
    EL(0, "}");
 
250
    NL;
 
251
 
 
252
    /* copy */
 
253
    EL(0, "%s %s(%s orig)", t->ctype, t->copy_func, t->ctype);
 
254
    EL(0, "{");
 
255
    EL(1, "%s copy;", t->ctype);
 
256
    NL;
 
257
    EL(1, "if (orig == NULL)");
 
258
    EL(2, "return NULL;");
 
259
    NL;
 
260
    EL(1, "copy = %s_new();", t->cname);
 
261
    for (k=t->struct_members; k; k=k->next)
 
262
    {
 
263
      xdl_struct_member* m = k->data;
 
264
      if (m->type->copy_func)
 
265
        EL(1, "copy->%s = %s(orig->%s);", m->name, m->type->copy_func, m->name);
 
266
      else
 
267
        EL(1, "copy->%s = orig->%s;", m->name, m->name);
 
268
    }
 
269
    NL;
 
270
    EL(1, "return copy;");
 
271
    EL(0, "}");
 
272
    NL;
 
273
  }
 
274
  else if (t->type == TD_ARRAY)
 
275
  {
 
276
    /* free */
 
277
    EL(0, "void %s(%s val)", t->free_func, t->ctype);
 
278
    EL(0, "{");
 
279
    if (t->item_type->free_func)
 
280
      EL(1, "g_slist_foreach(val, (GFunc)%s, NULL);", t->item_type->free_func);
 
281
    EL(1, "g_slist_free(val);");
 
282
    EL(0, "}");
 
283
    NL;
 
284
 
 
285
    /* copy */
 
286
    EL(0, "%s %s(%s orig)", t->ctype, t->copy_func, t->ctype);
 
287
    EL(0, "{");
 
288
    EL(1, "%s copy = NULL;", t->ctype);
 
289
    NL;
 
290
    EL(1, "while (orig)");
 
291
    EL(1, "{");
 
292
    if (t->item_type->copy_func)
 
293
      EL(2, "copy = g_slist_prepend(copy, (gpointer)%s((%s)orig->data));", t->item_type->copy_func, t->item_type->ctype);
 
294
    else
 
295
      EL(2, "copy = g_slist_prepend(copy, orig->data);");
 
296
    EL(2, "orig = orig->next;");
 
297
    EL(1, "}");
 
298
    NL;
 
299
    EL(1, "return g_slist_reverse(copy);");
 
300
    EL(0, "}");
 
301
    NL;
 
302
  }
 
303
}
 
304
 
 
305
static void gen_type_defs(FILE* f, GSList* types)
 
306
{
 
307
  GSList *i, *j, *k;
 
308
 
 
309
  for (j=types; j; j=j->next)
 
310
  {
 
311
    xdl_typedef* t = j->data;
 
312
    if (t->type == TD_STRUCT)
 
313
    {
 
314
      if (t->doc)
 
315
      {
 
316
        NL;
 
317
        EL(0, "%s", t->doc);
 
318
      }
 
319
      EL(0, "typedef struct _%s %s;", t->cname, t->cname);
 
320
    }
 
321
  }
 
322
  NL;
 
323
 
 
324
  for (j=types; j; j=j->next)
 
325
  {
 
326
    xdl_typedef* t = j->data;
 
327
    if (t->type == TD_STRUCT)
 
328
    {
 
329
      if (t->doc)
 
330
        EL(0, "%s", t->doc);
 
331
      EL(0, "struct _%s", t->cname);
 
332
      EL(0, "{");
 
333
      for (k=t->struct_members; k; k=k->next)
 
334
      {
 
335
        xdl_struct_member* m = k->data;
 
336
        EL(1, "%s %s;%s", m->type->ctype, m->name, m->type->type == TD_ARRAY ? S(" /* %s */", m->type->cname) : "");
 
337
      }
 
338
      EL(0, "};");
 
339
      NL;
 
340
    }
 
341
  }
 
342
}
 
343
 
 
344
static void gen_marchalizers(FILE* f, xdl_model* xdl, xdl_servlet* s)
 
345
{
 
346
  GSList *j;
 
347
 
 
348
  for (j=xdl->types; j; j=j->next)
 
349
  {
 
350
    xdl_typedef* t = j->data;
 
351
    if (t->type == TD_ANY)
 
352
      continue;
 
353
    gen_type_marchalizers(f, t);
 
354
  }
 
355
  for (j=s->types; j; j=j->next)
 
356
  {
 
357
    xdl_typedef* t = j->data;
 
358
    if (t->type == TD_ANY)
 
359
      continue;
 
360
    gen_type_marchalizers(f, t);
 
361
  }
 
362
}
 
363
 
 
364
static void gen_errors_header(FILE* f, xdl_model* xdl, xdl_servlet* s)
 
365
{
 
366
  GSList* j;
 
367
  GSList* errs = s ? s->errors : xdl->errors;
 
368
  if (errs == NULL)
 
369
    return;
 
370
 
 
371
  EL(0, "enum");
 
372
  EL(0, "{");
 
373
  for (j=errs; j; j=j->next)
 
374
  {
 
375
    xdl_error_code* e = j->data;
 
376
    EL(1, "%s = %d,", e->cenum, e->code);
 
377
  }
 
378
  EL(0, "};");
 
379
  NL;
 
380
  EL(0, "const char* %s%s_xmlrpc_error_to_string(int code);", xdl->name, s ? s->name : "");
 
381
  NL;
 
382
}
 
383
 
 
384
static void gen_errors_impl(FILE* f, xdl_model* xdl, xdl_servlet* s)
 
385
{
 
386
  GSList* j;
 
387
  GSList* errs = s ? s->errors : xdl->errors;
 
388
  if (errs == NULL)
 
389
    return;
 
390
 
 
391
  EL(0, "const char* %s%s_xmlrpc_error_to_string(int code)", xdl->name, s ? s->name : "");
 
392
  EL(0, "{");
 
393
  for (j=errs; j; j=j->next)
 
394
  {
 
395
    xdl_error_code* e = j->data;
 
396
    EL(1, "if (code == %s)", e->cenum);
 
397
    EL(2, "return \"%s\";", e->name);
 
398
  }
 
399
  EL(1, "return NULL;");
 
400
  EL(0, "}");
 
401
  NL;
 
402
}
 
403
 
 
404
/* main() */
 
405
 
 
406
static gchar* out_dir = NULL;
 
407
static gchar* xdl_file = NULL;
 
408
static gchar* mode = "all";
 
409
static const GOptionEntry entries[] = 
 
410
{
 
411
  { "xdl", 'i', 0, G_OPTION_ARG_STRING, &xdl_file, "Interface description file.", "FILE" },
 
412
  { "out", 'o', 0, G_OPTION_ARG_STRING, &out_dir, "Output directory.", "DIR" },
 
413
  { "mode", 'm', 0, G_OPTION_ARG_STRING, &mode, "Compiler mode (all, server-impl, pub-headers, pub-impl, vapi).", "MODE" },
 
414
  { NULL, 0, 0, 0, NULL, NULL, NULL }
 
415
};
 
416
 
 
417
#define MODE_IS(str) !strcmp(mode, G_STRINGIFY(str))
 
418
 
 
419
int main(int ac, char* av[])
 
420
{
 
421
  GError* err = NULL;
 
422
  GOptionContext* ctx = g_option_context_new("- XML-RPC Interface Generator.");
 
423
  g_option_context_add_main_entries(ctx, entries, NULL);
 
424
  g_option_context_parse(ctx, &ac, &av, NULL);
 
425
  g_option_context_set_help_enabled(ctx, TRUE);
 
426
 
 
427
  if (out_dir == NULL)
 
428
  {
 
429
    printf("You must specify output directory.\n");
 
430
    return 1;
 
431
  }
 
432
 
 
433
  if (xdl_file == NULL)
 
434
  {
 
435
    printf("You must specify XDL file.\n");
 
436
    return 1;
 
437
  }
 
438
  
 
439
  xdl_model* xdl = xdl_parse_file(xdl_file, &err);
 
440
  if (err)
 
441
  {
 
442
    printf("%s\n", err->message);
 
443
    exit(1);
 
444
  }
 
445
  xdl_process(xdl);
 
446
 
 
447
  FILE* f = NULL;
 
448
  GSList *i, *j, *k;
 
449
  
 
450
  int pub_headers = !strcmp(mode, "all") || !strcmp(mode, "pub-headers");
 
451
  int pub_impl = !strcmp(mode, "all") || !strcmp(mode, "pub-impl");
 
452
  int server_impl = !strcmp(mode, "all") || !strcmp(mode, "server-impl");
 
453
  int vapi_file = !strcmp(mode, "vapi");
 
454
  int xdl_gen = !strcmp(mode, "xdl");
 
455
  int js_client = !strcmp(mode, "js");
 
456
 
 
457
  /***********************************************************
 
458
   * common types header                                     *
 
459
   ***********************************************************/
 
460
 
 
461
  if (pub_headers)
 
462
  {
 
463
 
 
464
  OPEN("%s/%sCommon.h", out_dir, xdl->name);
 
465
 
 
466
  EL(0, "#ifndef __%s_Common_H__", xdl->name);
 
467
  EL(0, "#define __%s_Common_H__", xdl->name);
 
468
  NL;
 
469
 
 
470
  EL(0, "#include <xr-value.h>");
 
471
  NL;
 
472
 
 
473
  gen_errors_header(f, xdl, NULL);
 
474
 
 
475
  gen_type_defs(f, xdl->types);
 
476
 
 
477
  for (j=xdl->types; j; j=j->next)
 
478
  {
 
479
    xdl_typedef* t = j->data;
 
480
    gen_type_freealloc(f, t, 1);
 
481
  }
 
482
  NL;
 
483
 
 
484
  EL(0, "#endif");
 
485
 
 
486
  }
 
487
 
 
488
  /***********************************************************
 
489
   * common types implementation                             *
 
490
   ***********************************************************/
 
491
 
 
492
  if (pub_impl)
 
493
  {
 
494
 
 
495
  OPEN("%s/%sCommon.c", out_dir, xdl->name);
 
496
 
 
497
  EL(0, "#include \"%sCommon.h\"", xdl->name);
 
498
  NL;
 
499
 
 
500
  for (j=xdl->types; j; j=j->next)
 
501
  {
 
502
    xdl_typedef* t = j->data;
 
503
    gen_type_freealloc(f, t, 0);
 
504
  }
 
505
 
 
506
  gen_errors_impl(f, xdl, NULL);
 
507
 
 
508
  }
 
509
 
 
510
  /* client/servlet implementations for specific interfaces */
 
511
 
 
512
  for (i=xdl->servlets; i; i=i->next)
 
513
  {
 
514
    xdl_servlet* s = i->data;
 
515
 
 
516
    /***********************************************************
 
517
     * servlet types header                                    *
 
518
     ***********************************************************/
 
519
 
 
520
    if (pub_headers)
 
521
    {
 
522
 
 
523
    OPEN("%s/%s%s.h", out_dir, xdl->name, s->name);
 
524
 
 
525
    EL(0, "#ifndef __%s_%s_H__", xdl->name, s->name);
 
526
    EL(0, "#define __%s_%s_H__", xdl->name, s->name);
 
527
    NL;
 
528
 
 
529
    EL(0, "#include \"%sCommon.h\"", xdl->name);
 
530
    NL;
 
531
 
 
532
    gen_errors_header(f, xdl, s);
 
533
 
 
534
    gen_type_defs(f, s->types);
 
535
 
 
536
    for (j=s->types; j; j=j->next)
 
537
    {
 
538
      xdl_typedef* t = j->data;
 
539
      gen_type_freealloc(f, t, 1);
 
540
    }
 
541
    NL;
 
542
 
 
543
    EL(0, "#endif");
 
544
 
 
545
    }
 
546
 
 
547
    /***********************************************************
 
548
     * servlet types implementation                            *
 
549
     ***********************************************************/
 
550
 
 
551
    if (pub_impl)
 
552
    {
 
553
 
 
554
    OPEN("%s/%s%s.c", out_dir, xdl->name, s->name);
 
555
 
 
556
    EL(0, "#include \"%s%s.h\"", xdl->name, s->name);
 
557
    NL;
 
558
 
 
559
    for (j=s->types; j; j=j->next)
 
560
    {
 
561
      xdl_typedef* t = j->data;
 
562
      gen_type_freealloc(f, t, 0);
 
563
    }
 
564
 
 
565
    gen_errors_impl(f, xdl, s);
 
566
    
 
567
    }
 
568
 
 
569
    /***********************************************************
 
570
     * servlet client interface definition                     *
 
571
     ***********************************************************/
 
572
 
 
573
    if (pub_headers)
 
574
    {
 
575
 
 
576
    OPEN("%s/%s%s.xrc.h", out_dir, xdl->name, s->name);
 
577
 
 
578
    EL(0, "#ifndef __%s_%s_XRC_H__", xdl->name, s->name);
 
579
    EL(0, "#define __%s_%s_XRC_H__", xdl->name, s->name);
 
580
    NL;
 
581
 
 
582
    EL(0, "#include <xr-client.h>");
 
583
    EL(0, "#include \"%s%s.h\"", xdl->name, s->name);
 
584
    NL;
 
585
 
 
586
    for (j=s->methods; j; j=j->next)
 
587
    {
 
588
      xdl_method* m = j->data;
 
589
 
 
590
      EL(0, "/** ");
 
591
      EL(0, " * ");
 
592
      EL(0, " * @param _conn Client connection object.");
 
593
      for (k=m->params; k; k=k->next)
 
594
      {
 
595
        xdl_method_param* p = k->data;
 
596
        EL(0, " * @param %s", p->name);
 
597
      }
 
598
      EL(0, " * @param _error Error variable pointer (may be NULL).");
 
599
      EL(0, " * ");
 
600
      EL(0, " * @return ");
 
601
      EL(0, " */ ");
 
602
 
 
603
      E(0, "%s %s%s_%s(xr_client_conn* _conn", m->return_type->ctype, xdl->name, s->name, m->name);
 
604
      for (k=m->params; k; k=k->next)
 
605
      {
 
606
        xdl_method_param* p = k->data;
 
607
        E(0, ", %s%s %s", !strcmp(p->type->ctype, "char*") ? "const " : "", p->type->ctype, p->name);
 
608
      }
 
609
      EL(0, ", GError** _error);");
 
610
      NL;
 
611
    }
 
612
 
 
613
    EL(0, "#endif");
 
614
    
 
615
    }
 
616
 
 
617
    /***********************************************************
 
618
     * servlet client interface implementation                 *
 
619
     ***********************************************************/
 
620
 
 
621
    if (pub_impl)
 
622
    {
 
623
 
 
624
    OPEN("%s/%s%s.xrc.c", out_dir, xdl->name, s->name);
 
625
 
 
626
    EL(0, "#include \"%s%s.xrc.h\"", xdl->name, s->name);
 
627
    NL;
 
628
 
 
629
    gen_marchalizers(f, xdl, s);
 
630
    NL;
 
631
 
 
632
    for (j=s->methods; j; j=j->next)
 
633
    {
 
634
      xdl_method* m = j->data;
 
635
 
 
636
      E(0, "%s %s%s_%s(xr_client_conn* _conn", m->return_type->ctype, xdl->name, s->name, m->name);
 
637
      for (k=m->params; k; k=k->next)
 
638
      {
 
639
        xdl_method_param* p = k->data;
 
640
        E(0, ", %s%s %s", !strcmp(p->type->ctype, "char*") ? "const " : "", p->type->ctype, p->name);
 
641
      }
 
642
      EL(0, ", GError** _error)");
 
643
      EL(0, "{");
 
644
      EL(1, "%s _retval = %s;", m->return_type->ctype, m->return_type->cnull);
 
645
      EL(1, "xr_value* _param_value;");
 
646
      EL(1, "xr_call* _call;");
 
647
      NL;
 
648
      EL(1, "g_return_val_if_fail(_conn != NULL, _retval);");
 
649
      EL(1, "g_return_val_if_fail(_error == NULL || *_error == NULL, _retval);");
 
650
      NL;
 
651
      EL(1, "_call = xr_call_new(\"%s%s.%s\");", xdl->name, s->name, m->name);
 
652
      for (k=m->params; k; k=k->next)
 
653
      {
 
654
        xdl_method_param* p = k->data;
 
655
        NL;
 
656
        EL(1, "_param_value = %s(%s);", p->type->march_name, p->name);
 
657
        EL(1, "if (_param_value == NULL)");
 
658
        EL(1, "{");
 
659
        EL(2, "g_set_error(_error, XR_CLIENT_ERROR, XR_CLIENT_ERROR_MARCHALIZER, \"Call parameter value marchalization failed (param=%s).\");", p->name);
 
660
        EL(2, "xr_call_free(_call);");
 
661
        EL(2, "return _retval;");
 
662
        EL(1, "}");
 
663
        EL(1, "xr_call_add_param(_call, _param_value);");
 
664
      }
 
665
      NL;
 
666
      EL(1, "if (xr_client_call(_conn, _call, _error))");
 
667
      EL(1, "{");
 
668
      EL(2, "if (!%s(xr_call_get_retval(_call), &_retval))", m->return_type->demarch_name);
 
669
      EL(3, "g_set_error(_error, XR_CLIENT_ERROR, XR_CLIENT_ERROR_MARCHALIZER, \"Call return value demarchalization failed.\");");
 
670
      EL(1, "}");
 
671
      NL;
 
672
      EL(1, "xr_call_free(_call);");
 
673
      EL(1, "return _retval;");
 
674
      EL(0, "}");
 
675
      NL;
 
676
    }
 
677
 
 
678
    }
 
679
 
 
680
    /***********************************************************
 
681
     * servlet server stubs for implementation                 *
 
682
     ***********************************************************/
 
683
 
 
684
    if (server_impl)
 
685
    {
 
686
 
 
687
    OPEN("%s/%s%s.stubs.h", out_dir, xdl->name, s->name);
 
688
 
 
689
    EL(0, "#ifndef __%s_%s_STUBS_H__", xdl->name, s->name);
 
690
    EL(0, "#define __%s_%s_STUBS_H__", xdl->name, s->name);
 
691
    NL;
 
692
 
 
693
    EL(0, "#include <xr-server.h>");
 
694
    EL(0, "#include \"%s%s.h\"", xdl->name, s->name);
 
695
    NL;
 
696
 
 
697
    if (s->doc)
 
698
      EL(0, "%s", s->doc);
 
699
    else
 
700
    {
 
701
      EL(0, "/** Implementation specific servlet data.");
 
702
      EL(0, " */ ");
 
703
    }
 
704
    EL(0, "typedef struct _%s%sServlet %s%sServlet;", xdl->name, s->name, xdl->name, s->name);
 
705
    NL;
 
706
 
 
707
    EL(0, "/** Utility method that returns size of the servlet private data.");
 
708
    EL(0, " * ");
 
709
    EL(0, " * @return Size of the @ref %s%sServlet struct.", xdl->name, s->name);
 
710
    EL(0, " */ ");
 
711
    EL(0, "int __%s%sServlet_get_priv_size();", xdl->name, s->name);
 
712
    NL;
 
713
 
 
714
    EL(0, "/** Servlet constructor.");
 
715
    EL(0, " * ");
 
716
    EL(0, " * @param _servlet Servlet object.");
 
717
    EL(0, " * ");
 
718
    EL(0, " * @return TRUE if all is ok.");
 
719
    EL(0, " */ ");
 
720
    EL(0, "gboolean %s%sServlet_init(xr_servlet* _servlet);", xdl->name, s->name);
 
721
    NL;
 
722
 
 
723
    EL(0, "/** Servlet destructor.");
 
724
    EL(0, " * ");
 
725
    EL(0, " * @param _servlet Servlet object.");
 
726
    EL(0, " */ ");
 
727
    EL(0, "void %s%sServlet_fini(xr_servlet* _servlet);", xdl->name, s->name);
 
728
    NL;
 
729
 
 
730
    EL(0, "/** Pre-call hook.");
 
731
    EL(0, " * ");
 
732
    EL(0, " * @param _servlet Servlet object.");
 
733
    EL(0, " * @param _call Call object.");
 
734
    EL(0, " * ");
 
735
    EL(0, " * @return TRUE if you want to continue execution of the call.");
 
736
    EL(0, " */ ");
 
737
    EL(0, "gboolean %s%sServlet_pre_call(xr_servlet* _servlet, xr_call* _call);", xdl->name, s->name);
 
738
    NL;
 
739
 
 
740
    EL(0, "/** Post-call hook.");
 
741
    EL(0, " * ");
 
742
    EL(0, " * @param _servlet Servlet object.");
 
743
    EL(0, " * @param _call Call object.");
 
744
    EL(0, " * ");
 
745
    EL(0, " * @return TRUE if you want to continue execution of the call.");
 
746
    EL(0, " */ ");
 
747
    EL(0, "gboolean %s%sServlet_post_call(xr_servlet* _servlet, xr_call* _call);", xdl->name, s->name);
 
748
    NL;
 
749
 
 
750
    EL(0, "/** Fallback hook. (for undefined methods)");
 
751
    EL(0, " * ");
 
752
    EL(0, " * @param _servlet Servlet object.");
 
753
    EL(0, " * @param _call Call object.");
 
754
    EL(0, " * ");
 
755
    EL(0, " * @return TRUE if you handled the call.");
 
756
    EL(0, " */ ");
 
757
    EL(0, "gboolean %s%sServlet_fallback(xr_servlet* _servlet, xr_call* _call);", xdl->name, s->name);
 
758
    NL;
 
759
 
 
760
    EL(0, "/** Download hook.");
 
761
    EL(0, " * ");
 
762
    EL(0, " * @param _servlet Servlet object.");
 
763
    EL(0, " * ");
 
764
    EL(0, " * @return TRUE if you want to continue execution of the call.");
 
765
    EL(0, " */ ");
 
766
    EL(0, "gboolean %s%sServlet_download(xr_servlet* _servlet);", xdl->name, s->name);
 
767
    NL;
 
768
 
 
769
    EL(0, "/** Upload hook.");
 
770
    EL(0, " * ");
 
771
    EL(0, " * @param _servlet Servlet object.");
 
772
    EL(0, " * ");
 
773
    EL(0, " * @return TRUE if you want to continue execution of the call.");
 
774
    EL(0, " */ ");
 
775
    EL(0, "gboolean %s%sServlet_upload(xr_servlet* _servlet);", xdl->name, s->name);
 
776
    NL;
 
777
 
 
778
    for (j=s->methods; j; j=j->next)
 
779
    {
 
780
      xdl_method* m = j->data;
 
781
 
 
782
      if (m->doc)
 
783
      {
 
784
        EL(0, "%s", m->doc);
 
785
      }
 
786
      else
 
787
      {
 
788
        EL(0, "/** ");
 
789
        EL(0, " * ");
 
790
        EL(0, " * @param _servlet Servlet object.");
 
791
        for (k=m->params; k; k=k->next)
 
792
        {
 
793
          xdl_method_param* p = k->data;
 
794
          EL(0, " * @param %s", p->name);
 
795
        }
 
796
        EL(0, " * ");
 
797
        EL(0, " * @return ");
 
798
        EL(0, " */ ");
 
799
      }
 
800
 
 
801
      E(0, "%s %s%sServlet_%s(xr_servlet* _servlet", m->return_type->ctype, xdl->name, s->name, m->name);
 
802
      for (k=m->params; k; k=k->next)
 
803
      {
 
804
        xdl_method_param* p = k->data;
 
805
        E(0, ", %s %s", p->type->ctype, p->name);
 
806
      }
 
807
      EL(0, ", GError** _error);");
 
808
      NL;
 
809
    }
 
810
 
 
811
    EL(0, "#endif");
 
812
 
 
813
    /***********************************************************
 
814
     * servlet server stubs for implementation                 *
 
815
     ***********************************************************/
 
816
 
 
817
    OPEN("%s/%s%s.stubs.c", out_dir, xdl->name, s->name);
 
818
 
 
819
    EL(0, "#include \"%s%s.stubs.h\"", xdl->name, s->name);
 
820
    NL;
 
821
 
 
822
    if (s->stub_header)
 
823
    {
 
824
      STUB(s->stub_header);
 
825
      NL;
 
826
    }
 
827
 
 
828
    EL(0, "struct _%s%sServlet", xdl->name, s->name);
 
829
    EL(0, "{");
 
830
    STUB(s->stub_attrs);
 
831
    EL(0, "};");
 
832
    NL;
 
833
 
 
834
    EL(0, "int __%s%sServlet_get_priv_size()", xdl->name, s->name);
 
835
    EL(0, "{");
 
836
    EL(1, "return sizeof(%s%sServlet);", xdl->name, s->name);
 
837
    EL(0, "}");
 
838
    NL;
 
839
 
 
840
    EL(0, "gboolean %s%sServlet_init(xr_servlet* _servlet)", xdl->name, s->name);
 
841
    EL(0, "{");
 
842
    EL(1, "%s%sServlet* _priv = xr_servlet_get_priv(_servlet);", xdl->name, s->name);
 
843
    STUB(s->stub_init);
 
844
    EL(1, "return TRUE;");
 
845
    EL(0, "}");
 
846
    NL;
 
847
 
 
848
    EL(0, "void %s%sServlet_fini(xr_servlet* _servlet)", xdl->name, s->name);
 
849
    EL(0, "{");
 
850
    EL(1, "%s%sServlet* _priv = xr_servlet_get_priv(_servlet);", xdl->name, s->name);
 
851
    STUB(s->stub_fini);
 
852
    EL(0, "}");
 
853
    NL;
 
854
 
 
855
    EL(0, "gboolean %s%sServlet_pre_call(xr_servlet* _servlet, xr_call* _call)", xdl->name, s->name);
 
856
    EL(0, "{");
 
857
    EL(1, "%s%sServlet* _priv = xr_servlet_get_priv(_servlet);", xdl->name, s->name);
 
858
    STUB(s->stub_pre_call);
 
859
    EL(1, "return TRUE;");
 
860
    EL(0, "}");
 
861
    NL;
 
862
 
 
863
    EL(0, "gboolean %s%sServlet_post_call(xr_servlet* _servlet, xr_call* _call)", xdl->name, s->name);
 
864
    EL(0, "{");
 
865
    EL(1, "%s%sServlet* _priv = xr_servlet_get_priv(_servlet);", xdl->name, s->name);
 
866
    STUB(s->stub_post_call);
 
867
    EL(1, "return TRUE;");
 
868
    EL(0, "}");
 
869
    NL;
 
870
 
 
871
    EL(0, "gboolean %s%sServlet_fallback(xr_servlet* _servlet, xr_call* _call)", xdl->name, s->name);
 
872
    EL(0, "{");
 
873
    EL(1, "%s%sServlet* _priv = xr_servlet_get_priv(_servlet);", xdl->name, s->name);
 
874
    STUB(s->stub_fallback);
 
875
    EL(1, "return TRUE;");
 
876
    EL(0, "}");
 
877
    NL;
 
878
 
 
879
    EL(0, "gboolean %s%sServlet_download(xr_servlet* _servlet)", xdl->name, s->name);
 
880
    EL(0, "{");
 
881
    EL(1, "%s%sServlet* _priv = xr_servlet_get_priv(_servlet);", xdl->name, s->name);
 
882
    EL(1, "xr_http* _http = xr_servlet_get_http(_servlet);");
 
883
    STUB(s->stub_download);
 
884
    EL(1, "return FALSE;");
 
885
    EL(0, "}");
 
886
    NL;
 
887
 
 
888
    EL(0, "gboolean %s%sServlet_upload(xr_servlet* _servlet)", xdl->name, s->name);
 
889
    EL(0, "{");
 
890
    EL(1, "%s%sServlet* _priv = xr_servlet_get_priv(_servlet);", xdl->name, s->name);
 
891
    EL(1, "xr_http* _http = xr_servlet_get_http(_servlet);");
 
892
    STUB(s->stub_upload);
 
893
    EL(1, "return FALSE;");
 
894
    EL(0, "}");
 
895
    NL;
 
896
 
 
897
    for (j=s->methods; j; j=j->next)
 
898
    {
 
899
      xdl_method* m = j->data;
 
900
 
 
901
      E(0, "%s %s%sServlet_%s(xr_servlet* _servlet", m->return_type->ctype, xdl->name, s->name, m->name);
 
902
      for (k=m->params; k; k=k->next)
 
903
      {
 
904
        xdl_method_param* p = k->data;
 
905
        E(0, ", %s %s", p->type->ctype, p->name);
 
906
      }
 
907
      EL(0, ", GError** _error)");
 
908
      EL(0, "{");
 
909
      EL(1, "%s%sServlet* _priv = xr_servlet_get_priv(_servlet);", xdl->name, s->name);
 
910
      EL(1, "%s retval = %s;", m->return_type->ctype, m->return_type->cnull);
 
911
      if (m->stub_impl)
 
912
        STUB(m->stub_impl);
 
913
      else
 
914
        EL(1, "g_set_error(_error, 0, 1, \"Method is not implemented. (%s)\");", m->name);
 
915
      EL(1, "return retval;");
 
916
      EL(0, "}");
 
917
      NL;
 
918
    }
 
919
 
 
920
    /***********************************************************
 
921
     * servlet server interface internals header               *
 
922
     ***********************************************************/
 
923
 
 
924
    OPEN("%s/%s%s.xrs.h", out_dir, xdl->name, s->name);
 
925
 
 
926
    EL(0, "#ifndef __%s_%s_XRS_H__", xdl->name, s->name);
 
927
    EL(0, "#define __%s_%s_XRS_H__", xdl->name, s->name);
 
928
    NL;
 
929
 
 
930
    EL(0, "#include <xr-server.h>");
 
931
    EL(0, "#include \"%s%s.stubs.h\"", xdl->name, s->name);
 
932
    NL;
 
933
 
 
934
    EL(0, "xr_servlet_def* __%s%sServlet_def();", xdl->name, s->name);
 
935
    NL;
 
936
 
 
937
    EL(0, "#endif");
 
938
 
 
939
    /***********************************************************
 
940
     * servlet server interface implementation                 *
 
941
     ***********************************************************/
 
942
 
 
943
    OPEN("%s/%s%s.xrs.c", out_dir, xdl->name, s->name);
 
944
 
 
945
    EL(0, "#include \"%s%s.xrs.h\"", xdl->name, s->name);
 
946
    NL;
 
947
 
 
948
    gen_marchalizers(f, xdl, s);
 
949
    NL;
 
950
 
 
951
    for (j=s->methods; j; j=j->next)
 
952
    {
 
953
      xdl_method* m = j->data;
 
954
      int n = 0;
 
955
 
 
956
      EL(0, "static gboolean __method_%s(xr_servlet* _servlet, xr_call* _call)", m->name);
 
957
      EL(0, "{");
 
958
      // forward declarations
 
959
      EL(1, "gboolean _retval = FALSE;");
 
960
      EL(1, "%s _nreturn_value = %s;", m->return_type->ctype, m->return_type->cnull);
 
961
      EL(1, "xr_value* _return_value;");
 
962
      EL(1, "GError* _error = NULL;");
 
963
      for (k=m->params; k; k=k->next)
 
964
      {
 
965
        xdl_method_param* p = k->data;
 
966
        EL(1, "%s %s = %s;", p->type->ctype, p->name, p->type->cnull);
 
967
      }
 
968
      NL;
 
969
      EL(1, "g_return_val_if_fail(_servlet != NULL, FALSE);");
 
970
      EL(1, "g_return_val_if_fail(_call != NULL, FALSE);");
 
971
      // prepare parameters
 
972
      for (k=m->params; k; k=k->next)
 
973
      {
 
974
        xdl_method_param* p = k->data;
 
975
        NL;
 
976
        EL(1, "if (!%s(xr_call_get_param(_call, %d), &%s))", p->type->demarch_name, n++, p->name);
 
977
        EL(1, "{");
 
978
        EL(2, "xr_call_set_error(_call, -1, \"Stub parameter value demarchalization failed. (%s:%s)\");", m->name, p->name);
 
979
        EL(2, "goto out;");
 
980
        EL(1, "}");
 
981
      }
 
982
 
 
983
      // call stub
 
984
      NL;
 
985
      E(1, "_nreturn_value = %s%sServlet_%s(_servlet", xdl->name, s->name, m->name);
 
986
      for (k=m->params; k; k=k->next)
 
987
      {
 
988
        xdl_method_param* p = k->data;
 
989
        E(0, ", %s", p->name);
 
990
      }
 
991
      EL(0, ", &_error);");
 
992
 
 
993
      // check for errors
 
994
      EL(1, "if (_error)");
 
995
      EL(1, "{");
 
996
      EL(2, "xr_call_set_error(_call, _error->code, _error->message);");
 
997
      EL(2, "g_error_free(_error);");
 
998
      EL(2, "goto out;");
 
999
      EL(1, "}");
 
1000
 
 
1001
      // prepare retval
 
1002
      NL;
 
1003
      EL(1, "_return_value = %s(_nreturn_value);", m->return_type->march_name);
 
1004
      EL(1, "if (_return_value == NULL)");
 
1005
      EL(1, "{");
 
1006
      EL(2, "xr_call_set_error(_call, -1, \"Stub return value marchalization failed. (%s)\");", m->name);
 
1007
      EL(2, "goto out;");
 
1008
      EL(1, "}");
 
1009
      NL;
 
1010
      EL(1, "xr_call_set_retval(_call, _return_value);");
 
1011
      EL(1, "_retval = TRUE;");
 
1012
 
 
1013
      // free native types and return
 
1014
      NL;
 
1015
      EL(0, "out:");
 
1016
      if (m->return_type->free_func)
 
1017
        EL(1, "%s(_nreturn_value);", m->return_type->free_func);
 
1018
      for (k=m->params; k; k=k->next)
 
1019
      {
 
1020
        xdl_method_param* p = k->data;
 
1021
        if (!p->pass_ownership && p->type->free_func)
 
1022
          EL(1, "%s(%s);", p->type->free_func, p->name);
 
1023
      }
 
1024
      EL(1, "return _retval;");
 
1025
      EL(0, "}");
 
1026
      NL;
 
1027
    }
 
1028
 
 
1029
    EL(0, "static xr_servlet_method_def __servlet_methods[] = {");
 
1030
    for (j=s->methods; j; j=j->next)
 
1031
    {
 
1032
      xdl_method* m = j->data;
 
1033
      EL(1, "{");
 
1034
      EL(2, ".name = \"%s\",", m->name);
 
1035
      EL(2, ".cb = __method_%s", m->name);
 
1036
      EL(1, "}%s", j->next ? "," : "");
 
1037
    }
 
1038
    EL(0, "};");
 
1039
    NL;
 
1040
 
 
1041
#define SET_STUB(n) \
 
1042
  if (s->stub_##n) \
 
1043
    EL(1, "." G_STRINGIFY(n) " = %s%sServlet_" G_STRINGIFY(n) ",", xdl->name, s->name); \
 
1044
  else \
 
1045
    EL(1, "." G_STRINGIFY(n) " = NULL,")
 
1046
 
 
1047
    EL(0, "static xr_servlet_def __servlet = {");
 
1048
    EL(1, ".name = \"%s%s\",", xdl->name, s->name);
 
1049
    SET_STUB(init);
 
1050
    SET_STUB(fini);
 
1051
    SET_STUB(pre_call);
 
1052
    SET_STUB(post_call);
 
1053
    SET_STUB(fallback);
 
1054
    SET_STUB(download);
 
1055
    SET_STUB(upload);
 
1056
    EL(1, ".methods_count = %d,", g_slist_length(s->methods));
 
1057
    EL(1, ".methods = __servlet_methods");
 
1058
    EL(0, "};");
 
1059
    NL;
 
1060
 
 
1061
    EL(0, "xr_servlet_def* __%s%sServlet_def()", xdl->name, s->name);
 
1062
    EL(0, "{");
 
1063
    EL(1, "__servlet.size = __%s%sServlet_get_priv_size();", xdl->name, s->name);
 
1064
    EL(1, "return &__servlet;");
 
1065
    EL(0, "}");
 
1066
  }
 
1067
 
 
1068
  }
 
1069
  
 
1070
  /***********************************************************
 
1071
   * VAPI file                                               *
 
1072
   ***********************************************************/
 
1073
 
 
1074
  if (vapi_file)
 
1075
  {
 
1076
 
 
1077
  OPEN("%s/%s.vapi", out_dir, xdl->name);
 
1078
 
 
1079
  EL(0, "/* VALA bindings */");
 
1080
  NL;
 
1081
  EL(0, "[CCode (cheader_filename = \"xr-lib.h\", lower_case_cprefix = \"xr_\", cprefix = \"xr_\")]");
 
1082
  EL(0, "namespace XR");
 
1083
  EL(0, "{");
 
1084
  EL(1, "public static void init();");
 
1085
  EL(1, "public static void fini();");
 
1086
  NL;
 
1087
  EL(1, "[CCode (cheader_filename = \"xr-value.h\", free_function = \"xr_blob_unref\", cname = \"xr_blob\", cprefix = \"xr_blob_\")]");
 
1088
  EL(1, "public class Blob");
 
1089
  EL(1, "{");
 
1090
  EL(2, "public string buf;");
 
1091
  EL(2, "public int len;");
 
1092
  EL(2, "[CCode (cname = \"xr_blob_new\")]");
 
1093
  EL(2, "public Blob(string buf, int len);");
 
1094
  EL(1, "}");
 
1095
  NL;
 
1096
  EL(1, "[CCode (cprefix = \"XRV_\")]");
 
1097
  EL(1, "public enum ValueType { ARRAY, STRUCT, MEMBER, INT, STRING, BOOLEAN, DOUBLE, TIME, BLOB }");
 
1098
  NL;
 
1099
  EL(1, "[CCode (cheader_filename = \"xr-value.h\", unref_function = \"xr_value_unref\", ref_function = \"xr_value_ref\", cname = \"xr_value\", cprefix = \"xr_value_\")]");
 
1100
  EL(1, "public class Value");
 
1101
  EL(1, "{");
 
1102
  EL(2, "[CCode (cname = \"xr_value_int_new\")]");
 
1103
  EL(2, "public Value.int(int val);");
 
1104
  EL(2, "[CCode (cname = \"xr_value_string_new\")]");
 
1105
  EL(2, "public Value.string(string val);");
 
1106
  EL(2, "[CCode (cname = \"xr_value_bool_new\")]");
 
1107
  EL(2, "public Value.bool(bool val);");
 
1108
  EL(2, "[CCode (cname = \"xr_value_double_new\")]");
 
1109
  EL(2, "public Value.double(double val);");
 
1110
  EL(2, "[CCode (cname = \"xr_value_time_new\")]");
 
1111
  EL(2, "public Value.time(string val);");
 
1112
  EL(2, "[CCode (cname = \"xr_value_blob_new\")]");
 
1113
  EL(2, "public Value.blob(XR.Blob# val);");
 
1114
  EL(2, "[CCode (cname = \"xr_value_array_new\")]");
 
1115
  EL(2, "public Value.array();");
 
1116
  EL(2, "[CCode (cname = \"xr_value_struct_new\")]");
 
1117
  EL(2, "public Value.@struct();");
 
1118
  EL(2, "public bool to_int(ref int nval);");
 
1119
  EL(2, "public bool to_string(ref string nval);");
 
1120
  EL(2, "public bool to_bool(ref bool nval);");
 
1121
  EL(2, "public bool to_double(ref double nval);");
 
1122
  EL(2, "public bool to_time(ref string nval);");
 
1123
  EL(2, "public bool to_blob(ref XR.Blob nval);");
 
1124
  EL(2, "public bool to_value(ref XR.Value nval);");
 
1125
  EL(2, "public ValueType get_type();");
 
1126
  EL(2, "public void array_append(Value val);");
 
1127
  EL(2, "public GLib.SList<weak Value> get_items();");
 
1128
  EL(2, "public void set_member(string name, Value# val);");
 
1129
  EL(2, "public weak Value get_member(string name);");
 
1130
  EL(2, "public weak GLib.SList<weak Value> get_members();");
 
1131
  EL(2, "public weak string get_member_name();");
 
1132
  EL(2, "public weak Value get_member_value();");
 
1133
  EL(2, "public bool is_error_retval(ref int code, ref string msg);");
 
1134
  EL(2, "public void dump(GLib.StringBuilder str, int indent);");
 
1135
  EL(1, "}");
 
1136
  NL;
 
1137
  EL(1, "[Compact]");
 
1138
  EL(1, "[CCode (cheader_filename = \"xr-call.h\", free_function = \"xr_call_free\", cname = \"xr_call\", cprefix = \"xr_call_\")]");
 
1139
  EL(1, "public class Call");
 
1140
  EL(1, "{");
 
1141
  EL(2, "public Call(string method);");
 
1142
  EL(2, "public weak string get_method();");
 
1143
  EL(2, "public weak string get_method_full();");
 
1144
  EL(2, "public void add_param(Value# val);");
 
1145
  EL(2, "public weak Value get_param(uint pos);");
 
1146
  EL(2, "public void set_retval(Value# val);");
 
1147
  EL(2, "public weak Value get_retval();");
 
1148
  EL(2, "public void set_error(int code, string msg);");
 
1149
  EL(2, "public int get_error_code();");
 
1150
  EL(2, "public weak string get_error_message();");
 
1151
  EL(2, "public string dump_string(int indent);");
 
1152
  EL(2, "public void dump(int indent);");
 
1153
  EL(1, "}");
 
1154
  EL(0, "}");
 
1155
  NL;  
 
1156
  EL(0, "[CCode (cheader_filename = \"%sCommon.h\", lower_case_cprefix = \"xr_\", cprefix = \"%s\")]", xdl->name, xdl->name);
 
1157
  EL(0, "namespace %s", xdl->name);
 
1158
  EL(0, "{");
 
1159
  EL(1, "[CCode (cprefix = \"%s_XMLRPC_ERROR_\")]", xdl->name);
 
1160
  EL(1, "public enum Error");
 
1161
  EL(1, "{");
 
1162
  for (j=xdl->errors; j; j=j->next)
 
1163
  {
 
1164
    xdl_error_code* e = j->data;
 
1165
    EL(2, "%s = %d,", e->name, e->code);
 
1166
  }
 
1167
  EL(1, "}");
 
1168
  for (j=xdl->types; j; j=j->next)
 
1169
  {
 
1170
    xdl_typedef* t = j->data;
 
1171
    if (t->type == TD_STRUCT)
 
1172
    {
 
1173
      NL;
 
1174
      EL(1, "[Compact]");
 
1175
      EL(1, "[CCode (free_function = \"%s\", copy_function = \"%s\")]", t->free_func, t->copy_func);
 
1176
      EL(1, "public class %s", t->name);
 
1177
      EL(1, "{");
 
1178
      for (k=t->struct_members; k; k=k->next)
 
1179
      {
 
1180
        xdl_struct_member* m = k->data;
 
1181
        EL(2, "public %s %s;", xdl_typedef_vala_name(m->type), m->name);
 
1182
      }
 
1183
      EL(1, "}");
 
1184
    }
 
1185
  }
 
1186
 
 
1187
  for (i=xdl->servlets; i; i=i->next)
 
1188
  {
 
1189
    xdl_servlet* s = i->data;
 
1190
    NL;
 
1191
    EL(1, "[Compact]");
 
1192
    EL(1, "[CCode (cheader_filename = \"%s%s.xrc.h\", free_function = \"xr_client_free\", cname = \"xr_client_conn\", cprefix = \"%s%s_\")]", xdl->name, s->name, xdl->name, s->name);
 
1193
    EL(1, "public class %s", s->name);
 
1194
    EL(1, "{");
 
1195
    EL(2, "[CCode (cname = \"xr_client_new\")]");
 
1196
    EL(2, "public %s() throws GLib.Error;", s->name);
 
1197
    EL(2, "[CCode (cname = \"xr_client_open\")]");
 
1198
    EL(2, "public bool open(string uri) throws GLib.Error;");
 
1199
    EL(2, "[CCode (cname = \"xr_client_close\")]");
 
1200
    EL(2, "public void close();");
 
1201
    EL(2, "[CCode (cname = \"xr_client_set_http_header\")]");
 
1202
    EL(2, "public void set_http_header(string name, string? value);");
 
1203
    EL(2, "[CCode (cname = \"xr_client_reset_http_headers\")]");
 
1204
    EL(2, "public void reset_http_headers();");
 
1205
    EL(2, "[CCode (cname = \"xr_client_basic_auth\")]");
 
1206
    EL(2, "public void basic_auth(string username, string password);");
 
1207
    for (j=s->methods; j; j=j->next)
 
1208
    {
 
1209
      xdl_method* m = j->data;
 
1210
 
 
1211
      E(2, "public %s %s(", xdl_typedef_vala_name(m->return_type), m->name);
 
1212
      for (k=m->params; k; k=k->next)
 
1213
      {
 
1214
        xdl_method_param* p = k->data;
 
1215
        E(0, "%s %s%s", xdl_typedef_vala_name(p->type), p->name, k->next ? ", " : "");
 
1216
      }
 
1217
      EL(0, ") throws GLib.Error;");
 
1218
    }
 
1219
    EL(1, "}");
 
1220
  }
 
1221
  EL(0, "}");
 
1222
 
 
1223
  }
 
1224
 
 
1225
  if (xdl_gen)
 
1226
  {
 
1227
  OPEN("%s/%s.xdl", out_dir, xdl->name);
 
1228
 
 
1229
  EL(0, "/* Generated XDL */");
 
1230
  NL;
 
1231
 
 
1232
  EL(0, "namespace %s;", xdl->name);
 
1233
  NL;
 
1234
 
 
1235
  for (j=xdl->errors; j; j=j->next)
 
1236
  {
 
1237
    xdl_error_code* e = j->data;
 
1238
    EL(0, "error %-22s = %d;", e->name, e->code);
 
1239
  }
 
1240
 
 
1241
  for (j=xdl->types; j; j=j->next)
 
1242
  {
 
1243
    xdl_typedef* t = j->data;
 
1244
    if (t->type == TD_STRUCT)
 
1245
    {
 
1246
      NL;
 
1247
      EL(0, "struct %s", t->name);
 
1248
      EL(0, "{");
 
1249
      for (k=t->struct_members; k; k=k->next)
 
1250
      {
 
1251
        xdl_struct_member* m = k->data;
 
1252
        EL(1, "%-24s %s;", xdl_typedef_xdl_name(m->type), m->name);
 
1253
      }
 
1254
      EL(0, "}");
 
1255
    }
 
1256
  }
 
1257
 
 
1258
  for (i=xdl->servlets; i; i=i->next)
 
1259
  {
 
1260
    xdl_servlet* s = i->data;
 
1261
    NL;
 
1262
    EL(0, "servlet %s", s->name);
 
1263
    EL(0, "{");
 
1264
 
 
1265
    for (j=s->errors; j; j=j->next)
 
1266
    {
 
1267
      xdl_error_code* e = j->data;
 
1268
      EL(1, "error %-18s = %d;", e->name, e->code);
 
1269
    }
 
1270
    if (s->errors)
 
1271
      NL;
 
1272
 
 
1273
    for (j=s->types; j; j=j->next)
 
1274
    {
 
1275
      xdl_typedef* t = j->data;
 
1276
      if (t->type == TD_STRUCT)
 
1277
      {
 
1278
        EL(1, "struct %s", t->name);
 
1279
        EL(1, "{");
 
1280
        for (k=t->struct_members; k; k=k->next)
 
1281
        {
 
1282
          xdl_struct_member* m = k->data;
 
1283
          EL(2, "%-20s %s;", xdl_typedef_xdl_name(m->type), m->name);
 
1284
        }
 
1285
        EL(1, "}");
 
1286
        NL;
 
1287
      }
 
1288
    }
 
1289
 
 
1290
    s->methods = g_slist_sort(s->methods, (GCompareFunc)xdl_method_compare);
 
1291
 
 
1292
    for (j=s->methods; j; j=j->next)
 
1293
    {
 
1294
      xdl_method* m = j->data;
 
1295
 
 
1296
      E(1, "%-24s %-25s(", xdl_typedef_xdl_name(m->return_type), m->name);
 
1297
      for (k=m->params; k; k=k->next)
 
1298
      {
 
1299
        xdl_method_param* p = k->data;
 
1300
        if (k == m->params)
 
1301
          EL(0, "%-15s %s%s", xdl_typedef_xdl_name(p->type), p->name, k->next ? "," : ");");
 
1302
        else
 
1303
          EL(0, "%-55s%-15s %s%s", "", xdl_typedef_xdl_name(p->type), p->name, k->next ? "," : ");");
 
1304
      }
 
1305
      if (m->params == NULL)
 
1306
        EL(0, ");");
 
1307
    }
 
1308
    EL(0, "}");
 
1309
  }
 
1310
 
 
1311
  }
 
1312
 
 
1313
  if (js_client)
 
1314
  {
 
1315
    OPEN("%s/%s.js", out_dir, xdl->name);
 
1316
 
 
1317
    EL(0, "/* Generated JS client code */");
 
1318
    NL;
 
1319
    EL(0, "var %s = {};", xdl->name);
 
1320
 
 
1321
    if (xdl->errors)
 
1322
      NL;
 
1323
    for (j = xdl->errors; j; j = j->next)
 
1324
    {
 
1325
      xdl_error_code* e = j->data;
 
1326
      EL(0, "%-30s = %d;", S("%s.%s", xdl->name, e->name), e->code);
 
1327
    }
 
1328
 
 
1329
    for (i = xdl->servlets; i; i = i->next)
 
1330
    {
 
1331
      xdl_servlet* s = i->data;
 
1332
 
 
1333
      NL;
 
1334
      EL(0, "%s.%s = Class.create(Client,", xdl->name, s->name);
 
1335
      EL(0, "{");
 
1336
 
 
1337
      for (j=s->methods; j; j=j->next)
 
1338
      {
 
1339
        xdl_method* m = j->data;
 
1340
 
 
1341
        E(1, "%s: function(", m->name);
 
1342
        for (k=m->params; k; k=k->next)
 
1343
        {
 
1344
          xdl_method_param* p = k->data;
 
1345
          E(0, "%s%s", p->name, k->next ? ", " : "");
 
1346
        }
 
1347
        EL(0, ")");
 
1348
        EL(1, "{");
 
1349
        /*
 
1350
        for (k=m->params; k; k=k->next)
 
1351
        {
 
1352
          xdl_method_param* p = k->data;
 
1353
          EL(2, "if (!Object.is%s(%s))", p->type->name, p->name);
 
1354
          EL(3, "throw new Error('Parameter %s must be of type %s.');", p->name, p->type->name);
 
1355
        }
 
1356
        */
 
1357
        E(2, "return this.call('%s%s.%s', [ ", xdl->name, s->name, m->name);
 
1358
        for (k=m->params; k; k=k->next)
 
1359
        {
 
1360
          xdl_method_param* p = k->data;
 
1361
          E(0, "%s%s", p->name, k->next ? ", " : "");
 
1362
        }
 
1363
        EL(0, " ]);");
 
1364
        EL(1, "}%s", j->next ? "," : "");
 
1365
        if (j->next)
 
1366
          NL;
 
1367
      }
 
1368
      EL(0, "});");
 
1369
    }
 
1370
  }
 
1371
 
 
1372
  /* end */
 
1373
 
 
1374
  if (f)
 
1375
    fclose(f);
 
1376
 
 
1377
  return 0;
 
1378
}