any.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <grass/gis.h>
  5. #include <grass/glocale.h>
  6. #include "list.h"
  7. #include "mapcalc.h"
  8. #include "any.h"
  9. /*
  10. * This is a backdoor for strange types only. We only handle void pointer
  11. * references and make no kind of typecheck; lot's of errors can be made
  12. * by the user. But at least it's possible to deal with minor issues
  13. * without touching the parser.
  14. * Memory for "any" should be one single block.
  15. */
  16. typedef ANY *(*a_func) (void);
  17. typedef ANY *(*a_func_a) (void *a0);
  18. typedef ANY *(*a_func_aa) (void *a0, void *a1);
  19. typedef struct Anyfunc
  20. {
  21. char *name;
  22. void *func;
  23. char *proto;
  24. } ANYFUNC;
  25. static ANY *mkstring(void *a);
  26. void setany(SYMBOL * var, SYMBOL * any);
  27. SYMBOL *mkanyvar(SYMBOL * var, SYMBOL * any);
  28. SYMBOL *anyfunc(SYMBOL * func, SYMBOL * arglist);
  29. static ANYFUNC af[] = {
  30. {"mkstring", mkstring, "a"},
  31. {NULL, NULL, NULL}
  32. };
  33. /***************************************************************************
  34. * Test function only
  35. */
  36. static ANY *mkstring(void *a)
  37. {
  38. ANY *str;
  39. str = (ANY *) listitem(sizeof(ANY));
  40. str->type = st_str;
  41. str->any = (char *)strdup(a);
  42. str->refcnt = 1;
  43. fprintf(stdout, "\t%s\n", (char *)a);
  44. return str;
  45. }
  46. /*
  47. * End test function only
  48. ***************************************************************************/
  49. void init_any(void)
  50. {
  51. SYMBOL *sym;
  52. int i;
  53. for (i = 0; af[i].name; i++) {
  54. sym = putsym(af[i].name);
  55. sym->type = sym->itype = st_afunc;
  56. sym->v.p = af[i].func;
  57. sym->proto = af[i].proto;
  58. sym->rettype = st_any;
  59. }
  60. }
  61. void setany(SYMBOL * var, SYMBOL * any)
  62. {
  63. SYMBOL *sym;
  64. if (var->name) {
  65. sym = getsym(var->name);
  66. if (sym) {
  67. if (--((ANY *) sym->v.p)->refcnt < 1)
  68. G_free(sym->v.p);
  69. sym->v.p = any->v.p;
  70. }
  71. }
  72. if (--((ANY *) var->v.p)->refcnt < 1)
  73. G_free(var->v.p);
  74. var->v.p = NULL;
  75. freesym(var);
  76. /* can't show an anyvar */
  77. any->v.p = NULL;
  78. freesym(any);
  79. }
  80. SYMBOL *mkanyvar(SYMBOL * var, SYMBOL * any)
  81. {
  82. var->type = var->itype = st_any;
  83. var->name = var->v.p;
  84. var->v.p = any->v.p;
  85. any->v.p = NULL;
  86. symtab = (SYMBOL *) listadd((LIST *) symtab, (LIST *) var, cmpsymsym);
  87. /* can't show any */
  88. return var;
  89. }
  90. SYMBOL *anyfunc(SYMBOL * func, SYMBOL * arglist)
  91. {
  92. SYMBOL *sym;
  93. ANY *res = NULL;
  94. int argc = -1;
  95. if (!func || !func->v.p || func->type != st_afunc) {
  96. parseerror = 1;
  97. G_warning(_("Can't call bad any-function"));
  98. }
  99. else
  100. argc = listcnt((LIST *) arglist);
  101. if (argc == 0 && (!func->proto || !*func->proto))
  102. res = (*(a_func) func->v.p) ();
  103. else if (argc == 1 && !strcmp(func->proto, "a"))
  104. res = (*(a_func_a) func->v.p) (arglist->v.p);
  105. else if (argc == 2 && !strcmp(func->proto, "aa"))
  106. res = (*(a_func_aa) func->v.p) (arglist->v.p, arglist->next->v.p);
  107. else {
  108. G_warning(_("Bad arguments to anyfunc %s (argc = %d)"), func->name,
  109. argc);
  110. parseerror = 1;
  111. }
  112. listdelall((LIST *) func, freesym);
  113. listdelall((LIST *) arglist, freesym);
  114. sym = (SYMBOL *) listitem(sizeof(SYMBOL));
  115. sym->type = st_any;
  116. sym->v.p = res;
  117. return sym;
  118. }