Browse Source

Gmt module: Gmt module initial commit

ObjPtr
Michael Uleysky 9 years ago
parent
commit
b0a801a855
  1. 1
      modules/gmt/makemod
  2. 86
      modules/gmt/modgmt.cpp
  3. 31
      modules/gmt/modgmt.h

1
modules/gmt/makemod

@ -0,0 +1 @@
MODLIBS+=-lgmt

86
modules/gmt/modgmt.cpp

@ -0,0 +1,86 @@
#include "modgmt.h"
#if defined MODGMT_WORKAROUND_EXIT
// Exit handler.
static void gmtonexithandler(int ret, void* x)
{
reinterpret_cast<struct gmtworkthreadpars*>(x)->ret=ret;
close(reinterpret_cast<struct gmtworkthreadpars*>(x)->fd);
pthread_exit(&(reinterpret_cast<struct gmtworkthreadpars*>(x)->ret));
}
#endif
// This function call GMT_Call_Module in separate thread. It just a hack to workaround absence of callbacks.
static void* gmtworkthread(void* x)
{
struct gmtworkthreadpars* p=reinterpret_cast<struct gmtworkthreadpars*>(x);
#if defined MODGMT_WORKAROUND_EXIT
on_exit(gmtonexithandler,x);
#endif
GMT_Append_Option(p->api,GMT_Make_Option(p->api,'>',const_cast<char*>(("/dev/fd/"+std::to_string(p->fd)).c_str())),p->opts);
p->ret=GMT_Call_Module(p->api,p->module,GMT_MODULE_OPT,p->opts);
#if defined MODGMT_WORKAROUND_EXIT
exit(p->ret);
#endif
close(p->fd);
return &p->ret;
}
// Wrapper for GMT_Call_Module, res is output.
int callgmtmodule(void *api, const char *module, struct GMT_OPTION *opts, std::string& res)
{
int pipefd[2];
ssize_t br;
char buffer[4096];
pthread_t wthr;
struct gmtworkthreadpars p;
int *pret;
pipe(pipefd);
p.api=api;
p.module=module;
p.opts=opts;
p.fd=pipefd[1];
pthread_create(&wthr,0,&gmtworkthread,&p);
res.erase();
do
{
br=read(pipefd[0],buffer,4096);
res.append(buffer,br);
} while(0!=br);
close(pipefd[0]);
res.shrink_to_fit();
pthread_join(wthr,reinterpret_cast<void**>(&pret));
return *pret;
}
// Initialisation function
int gmt_module_init(void* p)
{
// Fill header and footer
struct GMT_OPTION* opts;
void* gmtapi;
int ret;
const char* ch="--GMT_HISTORY=f -C -P -K";
const char* cf="--GMT_HISTORY=f -C -P -O";
char* h=strdup(ch);
char* f=strdup(cf);
gmtapi=GMT_Create_Session("gmt_makemap",2,3,0);
if(0==gmtapi) return 1;
opts=GMT_Create_Options(gmtapi,0,h);
ret=callgmtmodule(gmtapi,"psclip",opts,header);
GMT_Destroy_Options(gmtapi,&opts);
opts=GMT_Create_Options(gmtapi,0,f);
if(0==ret) ret=callgmtmodule(gmtapi,"psclip",opts,footer);
GMT_Destroy_Options(gmtapi,&opts);
GMT_Destroy_Session(gmtapi);
free(h); free(f);
if(0!=ret) return ret;
return 0;
}

31
modules/gmt/modgmt.h

@ -0,0 +1,31 @@
#include <pthread.h>
#include <unistd.h>
#include <gmt.h>
#include <string.h>
#include "common.h"
// Workaround exit() in GMT_Call_Module. May need because return mode of gmt api is not very reliable
#if defined MODGMT_WORKAROUND_EXIT
#define GMTMODE 0
#else
#define GMTMODE 3
#endif
// here we save header and footer of gmt-produced eps files
std::string header,footer;
// Parameters for working thread
struct gmtworkthreadpars
{
void* api;
const char* module;
struct GMT_OPTION* opts;
int fd;
int ret;
};
extern "C" {
EXPORT int gmt_module_init(void* p);
}
int callgmtmodule(void *api, const char *module, struct GMT_OPTION *opts, std::string& res);
Loading…
Cancel
Save