Browse Source

Gmt module: Filters in callgmtmodule. Add default filter and lex-based filter for cutting header and footer of generated eps files.

ObjPtr
Michael Uleysky 9 years ago
parent
commit
db62ae83ec
  1. 2
      modules/gmt/.gitignore
  2. 31
      modules/gmt/filters.cpp
  3. 11
      modules/gmt/filters.h
  4. 46
      modules/gmt/gmt_filter_headfoot.l
  5. 34
      modules/gmt/makemod
  6. 25
      modules/gmt/modgmt.cpp
  7. 10
      modules/gmt/modgmt.h
  8. 12
      modules/gmt/modgmt_func.cpp
  9. 7
      modules/gmt/modgmt_func.h

2
modules/gmt/.gitignore vendored

@ -0,0 +1,2 @@
/gmt_filter_headfoot.cpp
/gmt_filter_headfoot.h

31
modules/gmt/filters.cpp

@ -0,0 +1,31 @@
#include "filters.h"
#include "gmt_filter_headfoot.h"
int gmt_filter_default(int fd, std::string* res, void* p)
{
ssize_t br;
char buffer[4096];
do
{
br=read(fd,buffer,4096);
res->append(buffer,br);
} while(0!=br);
close(fd);
return 0;
}
int gmt_filter_headfoot(int fd, std::string* res, void* p)
{
yyscan_t scanner;
FILE* in;
in=fdopen(fd,"r");
gmt_filter_headfootlex_init_extra(res,&scanner);
gmt_filter_headfootset_in(in,scanner);
gmt_filter_headfootlex(scanner);
gmt_filter_headfootlex_destroy(scanner);
fclose(in);
return 0;
}

11
modules/gmt/filters.h

@ -0,0 +1,11 @@
#ifndef MODGMT_FILTERS_H
#define MODGMT_FILTERS_H
#include <unistd.h>
#include <string>
typedef int (*gmt_filter)(int, std::string*, void*);
int gmt_filter_default(int, std::string*, void*);
int gmt_filter_headfoot(int, std::string*, void*);
#endif

46
modules/gmt/gmt_filter_headfoot.l

@ -0,0 +1,46 @@
%option 8bit reentrant
%option warn
%option yylineno
%option noyywrap
%option header-file="gmt_filter_headfoot.h"
%option outfile="gmt_filter_headfoot.cpp"
%option prefix="gmt_filter_headfoot"
%option extra-type="std::string*"
%option nounput
%x NOTCOMMENTS
%x SETUP
%x ENDHEAD
%x ENDFOOTER
%{
#include <string>
// flex use register keyword, but it deprecated in C++11.
#define register
// Get rid of warning on unused function
#define YY_NO_INPUT
#define yyterminate {return 0;}
%}
/*
For header:
1. Remove all comments from begin to %%EndComments inclusively
2. Remove %%Page, %%BeginPageSetup, %%EndPageSetup DSC comments
3. Remove all content between %%BeginSetup and %%EndSetup (skip setpagedevice)
4. Skip code after %%EndPageSetup (draw code)
For footer:
1. Remove all before %%PageTrailer, but not %%PageTrailer itself
*/
%%
<INITIAL>%%EndComments\n BEGIN(NOTCOMMENTS);
<INITIAL>%%PageTrailer\n yyextra->append(yytext,yyleng); BEGIN(ENDFOOTER);
<NOTCOMMENTS>\n%%Page:.*\n yyextra->append("\n",1);
<NOTCOMMENTS>\n%%BeginPageSetup.*\n yyextra->append("\n",1);
<NOTCOMMENTS>\n%%EndPageSetup.*\n yyextra->append("\n",1); BEGIN(ENDHEAD);
<NOTCOMMENTS>\n%%BeginSetup.*\n yyextra->append("\n",1); BEGIN(SETUP);
<NOTCOMMENTS,ENDFOOTER>.*\n yyextra->append(yytext,yyleng);
<SETUP>\n%%EndSetup.*\n yyextra->append("\n",1); BEGIN(NOTCOMMENTS);
<INITIAL,SETUP,ENDHEAD>.*\n
<*><<EOF>> yyterminate;
%%

34
modules/gmt/makemod

@ -1 +1,35 @@
MODLIBS+=-lgmt
GMT_FLSOURCE=gmt_filter_headfoot.cpp
GMT_FLHEADERS=$(subst .cpp,.h,$(GMT_FLSOURCE))
ifeq ($(subst ,$(GMT_FLSOURCE),$(SOURCE)),$(SOURCE))
SOURCE+=$(GMT_FLSOURCE)
MODSOURCE+=modules/gmt/$(GMT_FLSOURCE)
MODHEADERS+=modules/gmt/$(GMT_FLHEADERS)
endif
ifdef MODULE
filters.d: gmt_filter_headfoot.h
gmt_filter_headfoot.cpp: gmt_filter_headfoot.l
flex $<
[ -f gmt_filter_headfoot.h ] && touch gmt_filter_headfoot.h
gmt_filter_headfoot.h: gmt_filter_headfoot.l gmt_filter_headfoot.cpp
.PHONY: gmt_clean
clean: gmt_clean
gmt_clean:
rm -f $(GMT_FLSOURCE) $(GMT_FLHEADERS)
else
modules/gmt/gmt_filter_headfoot.cpp: modules/gmt/gmt_filter_headfoot.l
make -C modules/gmt -f ../../Makefile MODULE=gmt gmt_filter_headfoot.cpp
modules/gmt/gmt_filter_headfoot.h: modules/gmt/gmt_filter_headfoot.cpp
endif

25
modules/gmt/modgmt.cpp

@ -1,4 +1,7 @@
#include "modgmt.h"
#include "modgmt_func.h"
std::string header,footer;
#if defined MODGMT_WORKAROUND_EXIT
// Exit handler.
@ -27,11 +30,9 @@ static void* gmtworkthread(void* x)
}
// Wrapper for GMT_Call_Module, res is output.
int callgmtmodule(void *api, const char *module, struct GMT_OPTION *opts, std::string& res)
int callgmtmodule(void *api, const char *module, struct GMT_OPTION *opts, std::string* res, gmt_filter filt, void* filtpar)
{
int pipefd[2];
ssize_t br;
char buffer[4096];
pthread_t wthr;
struct gmtworkthreadpars p;
int *pret;
@ -43,15 +44,11 @@ int callgmtmodule(void *api, const char *module, struct GMT_OPTION *opts, std::s
p.fd=pipefd[1];
pthread_create(&wthr,0,&gmtworkthread,&p);
res->erase();
(*filt)(pipefd[0],res,filtpar);
res.erase();
do
{
br=read(pipefd[0],buffer,4096);
res.append(buffer,br);
} while(0!=br);
close(pipefd[0]);
res.shrink_to_fit();
res->shrink_to_fit();
pthread_join(wthr,reinterpret_cast<void**>(&pret));
return *pret;
@ -73,14 +70,16 @@ int gmt_module_init(void* p)
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);
ret=callgmtmodule(gmtapi,"psclip",opts,&header,gmt_filter_headfoot);
GMT_Destroy_Options(gmtapi,&opts);
opts=GMT_Create_Options(gmtapi,0,f);
if(0==ret) ret=callgmtmodule(gmtapi,"psclip",opts,footer);
if(0==ret) ret=callgmtmodule(gmtapi,"psclip",opts,&footer,gmt_filter_headfoot);
GMT_Destroy_Options(gmtapi,&opts);
GMT_Destroy_Session(gmtapi);
free(h); free(f);
if(0!=ret) return ret;
RegisterFunction("GMT_Header",GMT_Header);
RegisterFunction("GMT_Footer",GMT_Footer);
return 0;
}

10
modules/gmt/modgmt.h

@ -1,8 +1,10 @@
#ifndef MODGMT_H
#define MODGMT_H
#include <pthread.h>
#include <unistd.h>
#include <gmt.h>
#include <string.h>
#include "common.h"
#include "filters.h"
// Workaround exit() in GMT_Call_Module. May need because return mode of gmt api is not very reliable
#if defined MODGMT_WORKAROUND_EXIT
@ -12,7 +14,7 @@
#endif
// here we save header and footer of gmt-produced eps files
std::string header,footer;
extern std::string header,footer;
// Parameters for working thread
struct gmtworkthreadpars
@ -28,4 +30,6 @@ extern "C" {
EXPORT int gmt_module_init(void* p);
}
int callgmtmodule(void *api, const char *module, struct GMT_OPTION *opts, std::string& res);
int callgmtmodule(void *api, const char *module, struct GMT_OPTION *opts, std::string* res, gmt_filter filt=gmt_filter_default, void* filtpar=0);
#endif

12
modules/gmt/modgmt_func.cpp

@ -0,0 +1,12 @@
#include "modgmt.h"
#include "object.h"
ObjectBase* GMT_Header(const ObjectList* input)
{
return new ObjectString(header);
}
ObjectBase* GMT_Footer(const ObjectList* input)
{
return new ObjectString(footer);
}

7
modules/gmt/modgmt_func.h

@ -0,0 +1,7 @@
#ifndef MODGMT_FUNC_H
#define MODGMT_FUNC_H
ObjectBase* GMT_Header(const ObjectList* input);
ObjectBase* GMT_Footer(const ObjectList* input);
#endif
Loading…
Cancel
Save