123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- /****************************************************************************
- *
- * MODULE: v.mapcalc
- * AUTHOR(S): Christoph Simon (original contributor)
- *
- * PURPOSE:
- * COPYRIGHT: (C) 2002 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
- *
- *****************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dirent.h>
- #include <sys/stat.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- #include "list.h"
- #include "mapcalc.h"
- #include "map.h"
- typedef MAP *(*m_func) (void);
- typedef MAP *(*m_func_m) (void *m0);
- typedef MAP *(*m_func_mm) (void *m0, void *m1);
- typedef struct Mapfunc
- {
- char *name;
- void *func;
- char *proto;
- } MAPFUNC;
- static MAP *testmap(MAP * m);
- static MAP *test2map(MAP * m, MAP * n);
- static MAP *map_op_func_plus(MAP * m, MAP * n);
- static void find_maps(void);
- void init_map(void);
- void showmap(SYMBOL * map);
- void setmap(SYMBOL * var, SYMBOL * map);
- SYMBOL *mkmapvar(SYMBOL * var, SYMBOL * map);
- SYMBOL *mapfunc(SYMBOL * func, SYMBOL * arglist);
- SYMBOL *mapop(int op, SYMBOL * map1, SYMBOL * map2);
- static MAPFUNC mf[] = {
- {"testmap", testmap, "m"},
- {"test2map", test2map, "mm"},
- {"map_op_func_+", map_op_func_plus, "mm"},
- {NULL, NULL, NULL}
- };
- /*************************************************************************
- * This function represents a built-in map function.
- * Should probably go to another file
- */
- static MAP *testmap(MAP * m)
- {
- char namebuf[128];
- /*
- * The map name always exists, as it represents data on disk, but
- * might be a temporary name, when it should not be displayed
- * (should it?).
- */
- G_message(_("Performing 1 arg map function on map %s"), m->name);
- sprintf(namebuf, "t-%s", m->name);
- m = (MAP *) listitem(sizeof(MAP));
- m->name = strdup(namebuf);
- return m;
- }
- static MAP *test2map(MAP * m, MAP * n)
- {
- char namebuf[128];
- G_message(_("Performing 2 arg map function on maps %s and %s"), m->name,
- n->name);
- sprintf(namebuf, "%s.%s", m->name, n->name);
- m = (MAP *) listitem(sizeof(MAP));
- m->name = strdup(namebuf);
- return m;
- }
- static MAP *map_op_func_plus(MAP * m, MAP * n)
- {
- char namebuf[128];
- G_message(_("Performing map %s + %s"), m->name, n->name);
- sprintf(namebuf, "%s.%s", m->name, n->name);
- m = (MAP *) listitem(sizeof(MAP));
- m->name = strdup(namebuf);
- return m;
- }
- /*
- * end of move to other file
- ***********************************************************************/
- static void find_maps(void)
- {
- char *gisdbase, *location, *mapset;
- char basepath[4096], subdirpath[4096], path[4096];
- DIR *dir, *subdir;
- struct dirent *ent, *subent;
- gisdbase = getenv("GISDBASE");
- if (!gisdbase)
- gisdbase = ".";
- location = getenv("LOCATION_NAME");
- if (!location)
- location = ".";
- mapset = getenv("MAPSET");
- if (!mapset)
- mapset = ".";
- /*
- * Now, if I'm not in grass, I can simulate the existence of a vector
- * map creating a directory vector with one subdirectory for each `map'
- * having a file `head'
- */
- sprintf(basepath, "%s/%s/%s/vector", gisdbase, location, mapset);
- dir = opendir(basepath);
- if (!dir)
- return;
- while ((ent = readdir(dir)) != NULL) {
- struct stat buf;
- if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
- continue;
- strcpy(path, basepath);
- strcat(path, "/");
- strcat(path, ent->d_name);
- if (stat(path, &buf))
- continue;
- if (S_ISDIR(buf.st_mode)) {
- strcpy(subdirpath, path);
- subdir = opendir(subdirpath);
- if (!subdir)
- continue;
- while ((subent = readdir(subdir)) != NULL) {
- if (!strcmp(subent->d_name, ".") ||
- !strcmp(subent->d_name, ".."))
- continue;
- if (!strcmp(subent->d_name, "head")) {
- MAP *map;
- SYMBOL *sym;
- map = (MAP *) listitem(sizeof(MAP));
- map->name = strdup(ent->d_name);
- map->refcnt++;
- sym = putsym(map->name);
- sym->type = sym->itype = st_map;
- sym->v.p = map;
- }
- }
- closedir(subdir);
- }
- }
- closedir(dir);
- }
- void init_map(void)
- {
- SYMBOL *sym;
- int i;
- for (i = 0; mf[i].name; i++) {
- sym = putsym(mf[i].name);
- sym->type = sym->itype = st_mfunc;
- sym->v.p = mf[i].func;
- sym->proto = mf[i].proto;
- sym->rettype = st_map;
- }
- find_maps();
- }
- void printmap(SYMBOL * sym)
- {
- MAP *map;
- map = (MAP *) sym->v.p;
- if (map->name)
- fprintf(stdout, "\t%s\n", map->name);
- }
- void showmap(SYMBOL * sym)
- {
- MAP *map;
- map = (MAP *) sym->v.p;
- printmap(sym);
- if (--map->refcnt > 0)
- sym->v.p = NULL;
- freesym(sym);
- }
- MAP *freemap(MAP * map)
- {
- if (map) {
- if (map->refcnt > 0)
- return map;
- if (map->name)
- G_free(map->name);
- if (map->mapinfo)
- G_free(map->mapinfo); /* call grass to handle map */
- G_free(map);
- }
- return NULL;
- }
- void setmap(SYMBOL * var, SYMBOL * map)
- {
- SYMBOL *sym;
- if (var->name) {
- sym = getsym(var->name);
- if (sym) {
- sym->v.p = freemap(sym->v.p);
- sym->v.p = map->v.p;
- }
- }
- freemap(var->v.p);
- var->v.p = NULL;
- freesym(var);
- printmap(map);
- map->v.p = NULL;
- freesym(map);
- }
- SYMBOL *mkmapvar(SYMBOL * var, SYMBOL * map)
- {
- var->type = var->itype = st_map;
- var->name = var->v.p;
- var->v.p = map->v.p;
- map->v.p = NULL;
- freesym(map);
- symtab = (SYMBOL *) listadd((LIST *) symtab, (LIST *) var, cmpsymsym);
- printmap(var);
- return var;
- }
- SYMBOL *mapfunc(SYMBOL * func, SYMBOL * arglist)
- {
- SYMBOL *sym;
- MAP *res = NULL;
- int argc = -1;
- if (!func || !func->v.p || func->type != st_mfunc) {
- parseerror = 1;
- G_warning(_("Can't call bad map-function"));
- }
- else
- argc = listcnt((LIST *) arglist);
- if (argc == 0 && (!func->proto || !*func->proto))
- res = (*(m_func) func->v.p) ();
- else if (argc == 1 && !strcmp(func->proto, "m"))
- res = (*(m_func_m) func->v.p) (arglist->v.p);
- else if (argc == 2 && !strcmp(func->proto, "mm"))
- res = (*(m_func_mm) func->v.p) (arglist->v.p, arglist->next->v.p);
- else {
- G_warning(_("Bad arguments to mapfunc %s (argc = %d)"), func->name,
- argc);
- parseerror = 1;
- }
- listdelall((LIST *) func, freesym);
- listdelall((LIST *) arglist, freesym);
- sym = (SYMBOL *) listitem(sizeof(SYMBOL));
- sym->type = st_map;
- sym->v.p = res;
- return sym;
- }
- SYMBOL *mapop(int op, SYMBOL * map1, SYMBOL * map2)
- {
- SYMBOL *func, *arglist, *res = NULL;
- char buf[32];
- sprintf(buf, "map_op_func_%c", op);
- func = getsym(buf);
- if (!func) {
- G_warning(_("No function defined to perform map %c map"), op);
- parseerror = 1;
- }
- else {
- res = (SYMBOL *) listitem(sizeof(SYMBOL));
- symcpy(res, func);
- res->next = NULL;
- func = res;
- arglist = (SYMBOL *) listapp(NULL, (LIST *) map1);
- arglist = (SYMBOL *) listapp((LIST *) arglist, (LIST *) map2);
- res = mapfunc(func, arglist);
- }
- /* free map1/map2 ? only if they have no name? */
- return res;
- }
|