map.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /****************************************************************************
  2. *
  3. * MODULE: v.mapcalc
  4. * AUTHOR(S): Christoph Simon (original contributor)
  5. *
  6. * PURPOSE:
  7. * COPYRIGHT: (C) 2002 by the GRASS Development Team
  8. *
  9. * This program is free software under the GNU General Public
  10. * License (>=v2). Read the file COPYING that comes with GRASS
  11. * for details.
  12. *
  13. *****************************************************************************/
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <dirent.h>
  18. #include <sys/stat.h>
  19. #include <grass/gis.h>
  20. #include <grass/glocale.h>
  21. #include "list.h"
  22. #include "mapcalc.h"
  23. #include "map.h"
  24. typedef MAP *(*m_func) (void);
  25. typedef MAP *(*m_func_m) (void *m0);
  26. typedef MAP *(*m_func_mm) (void *m0, void *m1);
  27. typedef struct Mapfunc
  28. {
  29. char *name;
  30. void *func;
  31. char *proto;
  32. } MAPFUNC;
  33. static MAP *testmap(MAP * m);
  34. static MAP *test2map(MAP * m, MAP * n);
  35. static MAP *map_op_func_plus(MAP * m, MAP * n);
  36. static void find_maps(void);
  37. void init_map(void);
  38. void showmap(SYMBOL * map);
  39. void setmap(SYMBOL * var, SYMBOL * map);
  40. SYMBOL *mkmapvar(SYMBOL * var, SYMBOL * map);
  41. SYMBOL *mapfunc(SYMBOL * func, SYMBOL * arglist);
  42. SYMBOL *mapop(int op, SYMBOL * map1, SYMBOL * map2);
  43. static MAPFUNC mf[] = {
  44. {"testmap", testmap, "m"},
  45. {"test2map", test2map, "mm"},
  46. {"map_op_func_+", map_op_func_plus, "mm"},
  47. {NULL, NULL, NULL}
  48. };
  49. /*************************************************************************
  50. * This function represents a built-in map function.
  51. * Should probably go to another file
  52. */
  53. static MAP *testmap(MAP * m)
  54. {
  55. char namebuf[128];
  56. /*
  57. * The map name always exists, as it represents data on disk, but
  58. * might be a temporary name, when it should not be displayed
  59. * (should it?).
  60. */
  61. G_message(_("Performing 1 arg map function on map %s"), m->name);
  62. sprintf(namebuf, "t-%s", m->name);
  63. m = (MAP *) listitem(sizeof(MAP));
  64. m->name = strdup(namebuf);
  65. return m;
  66. }
  67. static MAP *test2map(MAP * m, MAP * n)
  68. {
  69. char namebuf[128];
  70. G_message(_("Performing 2 arg map function on maps %s and %s"), m->name,
  71. n->name);
  72. sprintf(namebuf, "%s.%s", m->name, n->name);
  73. m = (MAP *) listitem(sizeof(MAP));
  74. m->name = strdup(namebuf);
  75. return m;
  76. }
  77. static MAP *map_op_func_plus(MAP * m, MAP * n)
  78. {
  79. char namebuf[128];
  80. G_message(_("Performing map %s + %s"), m->name, n->name);
  81. sprintf(namebuf, "%s.%s", m->name, n->name);
  82. m = (MAP *) listitem(sizeof(MAP));
  83. m->name = strdup(namebuf);
  84. return m;
  85. }
  86. /*
  87. * end of move to other file
  88. ***********************************************************************/
  89. static void find_maps(void)
  90. {
  91. char *gisdbase, *location, *mapset;
  92. char basepath[4096], subdirpath[4096], path[4096];
  93. DIR *dir, *subdir;
  94. struct dirent *ent, *subent;
  95. gisdbase = getenv("GISDBASE");
  96. if (!gisdbase)
  97. gisdbase = ".";
  98. location = getenv("LOCATION_NAME");
  99. if (!location)
  100. location = ".";
  101. mapset = getenv("MAPSET");
  102. if (!mapset)
  103. mapset = ".";
  104. /*
  105. * Now, if I'm not in grass, I can simulate the existence of a vector
  106. * map creating a directory vector with one subdirectory for each `map'
  107. * having a file `head'
  108. */
  109. sprintf(basepath, "%s/%s/%s/vector", gisdbase, location, mapset);
  110. dir = opendir(basepath);
  111. if (!dir)
  112. return;
  113. while ((ent = readdir(dir)) != NULL) {
  114. struct stat buf;
  115. if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
  116. continue;
  117. strcpy(path, basepath);
  118. strcat(path, "/");
  119. strcat(path, ent->d_name);
  120. if (stat(path, &buf))
  121. continue;
  122. if (S_ISDIR(buf.st_mode)) {
  123. strcpy(subdirpath, path);
  124. subdir = opendir(subdirpath);
  125. if (!subdir)
  126. continue;
  127. while ((subent = readdir(subdir)) != NULL) {
  128. if (!strcmp(subent->d_name, ".") ||
  129. !strcmp(subent->d_name, ".."))
  130. continue;
  131. if (!strcmp(subent->d_name, "head")) {
  132. MAP *map;
  133. SYMBOL *sym;
  134. map = (MAP *) listitem(sizeof(MAP));
  135. map->name = strdup(ent->d_name);
  136. map->refcnt++;
  137. sym = putsym(map->name);
  138. sym->type = sym->itype = st_map;
  139. sym->v.p = map;
  140. }
  141. }
  142. closedir(subdir);
  143. }
  144. }
  145. closedir(dir);
  146. }
  147. void init_map(void)
  148. {
  149. SYMBOL *sym;
  150. int i;
  151. for (i = 0; mf[i].name; i++) {
  152. sym = putsym(mf[i].name);
  153. sym->type = sym->itype = st_mfunc;
  154. sym->v.p = mf[i].func;
  155. sym->proto = mf[i].proto;
  156. sym->rettype = st_map;
  157. }
  158. find_maps();
  159. }
  160. void printmap(SYMBOL * sym)
  161. {
  162. MAP *map;
  163. map = (MAP *) sym->v.p;
  164. if (map->name)
  165. fprintf(stdout, "\t%s\n", map->name);
  166. }
  167. void showmap(SYMBOL * sym)
  168. {
  169. MAP *map;
  170. map = (MAP *) sym->v.p;
  171. printmap(sym);
  172. if (--map->refcnt > 0)
  173. sym->v.p = NULL;
  174. freesym(sym);
  175. }
  176. MAP *freemap(MAP * map)
  177. {
  178. if (map) {
  179. if (map->refcnt > 0)
  180. return map;
  181. if (map->name)
  182. G_free(map->name);
  183. if (map->mapinfo)
  184. G_free(map->mapinfo); /* call grass to handle map */
  185. G_free(map);
  186. }
  187. return NULL;
  188. }
  189. void setmap(SYMBOL * var, SYMBOL * map)
  190. {
  191. SYMBOL *sym;
  192. if (var->name) {
  193. sym = getsym(var->name);
  194. if (sym) {
  195. sym->v.p = freemap(sym->v.p);
  196. sym->v.p = map->v.p;
  197. }
  198. }
  199. freemap(var->v.p);
  200. var->v.p = NULL;
  201. freesym(var);
  202. printmap(map);
  203. map->v.p = NULL;
  204. freesym(map);
  205. }
  206. SYMBOL *mkmapvar(SYMBOL * var, SYMBOL * map)
  207. {
  208. var->type = var->itype = st_map;
  209. var->name = var->v.p;
  210. var->v.p = map->v.p;
  211. map->v.p = NULL;
  212. freesym(map);
  213. symtab = (SYMBOL *) listadd((LIST *) symtab, (LIST *) var, cmpsymsym);
  214. printmap(var);
  215. return var;
  216. }
  217. SYMBOL *mapfunc(SYMBOL * func, SYMBOL * arglist)
  218. {
  219. SYMBOL *sym;
  220. MAP *res = NULL;
  221. int argc = -1;
  222. if (!func || !func->v.p || func->type != st_mfunc) {
  223. parseerror = 1;
  224. G_warning(_("Can't call bad map-function"));
  225. }
  226. else
  227. argc = listcnt((LIST *) arglist);
  228. if (argc == 0 && (!func->proto || !*func->proto))
  229. res = (*(m_func) func->v.p) ();
  230. else if (argc == 1 && !strcmp(func->proto, "m"))
  231. res = (*(m_func_m) func->v.p) (arglist->v.p);
  232. else if (argc == 2 && !strcmp(func->proto, "mm"))
  233. res = (*(m_func_mm) func->v.p) (arglist->v.p, arglist->next->v.p);
  234. else {
  235. G_warning(_("Bad arguments to mapfunc %s (argc = %d)"), func->name,
  236. argc);
  237. parseerror = 1;
  238. }
  239. listdelall((LIST *) func, freesym);
  240. listdelall((LIST *) arglist, freesym);
  241. sym = (SYMBOL *) listitem(sizeof(SYMBOL));
  242. sym->type = st_map;
  243. sym->v.p = res;
  244. return sym;
  245. }
  246. SYMBOL *mapop(int op, SYMBOL * map1, SYMBOL * map2)
  247. {
  248. SYMBOL *func, *arglist, *res = NULL;
  249. char buf[32];
  250. sprintf(buf, "map_op_func_%c", op);
  251. func = getsym(buf);
  252. if (!func) {
  253. G_warning(_("No function defined to perform map %c map"), op);
  254. parseerror = 1;
  255. }
  256. else {
  257. res = (SYMBOL *) listitem(sizeof(SYMBOL));
  258. symcpy(res, func);
  259. res->next = NULL;
  260. func = res;
  261. arglist = (SYMBOL *) listapp(NULL, (LIST *) map1);
  262. arglist = (SYMBOL *) listapp((LIST *) arglist, (LIST *) map2);
  263. res = mapfunc(func, arglist);
  264. }
  265. /* free map1/map2 ? only if they have no name? */
  266. return res;
  267. }