gmt 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/gmt/gmt.c +124 -0
- data/ext/gmt/option.c +161 -0
- data/ext/gmt/option.h +20 -0
- data/lib/gmt.rb +20 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1348e925157b856022bda1c2f6c83a848be3972
|
4
|
+
data.tar.gz: f935f6dab2efd89e6129b9846596adc72373fa06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bec6cdaf7e5fe4e47435154e10e3186fd019bf5d7aaacd18ebbc195eef642d476c3a5fdf2ef2c66a7afb2249af68da01503025c71d795ac02cbaa98a45aa6f1a
|
7
|
+
data.tar.gz: 5a90a50514f7715956e8e1e57bd0a4c8d6059341e98a9185b16d0e8af99bc756fd0bceca45035db6bd3753f30f180b890547196d19494f1ec770e422004eda95
|
data/ext/gmt/gmt.c
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <gmt.h>
|
3
|
+
|
4
|
+
#include "option.h"
|
5
|
+
|
6
|
+
typedef struct
|
7
|
+
{
|
8
|
+
void *session;
|
9
|
+
} gmt_t;
|
10
|
+
|
11
|
+
static void raise_unless_class_data(gmt_t *gmt)
|
12
|
+
{
|
13
|
+
if (gmt == NULL)
|
14
|
+
rb_raise(rb_eRuntimeError, "failed fetch of GMT class data");
|
15
|
+
}
|
16
|
+
|
17
|
+
static void raise_if_error(int err, const char *module)
|
18
|
+
{
|
19
|
+
if (err)
|
20
|
+
rb_raise(rb_eRuntimeError, "failed call to GMT module %s", module);
|
21
|
+
}
|
22
|
+
|
23
|
+
static VALUE gmt_simple(const char *name, int argc, VALUE *argv, VALUE self)
|
24
|
+
{
|
25
|
+
VALUE files, opts;
|
26
|
+
rb_scan_args(argc, argv, "*:", &files, &opts);
|
27
|
+
if (TYPE(opts) == T_NIL) opts = rb_hash_new();
|
28
|
+
|
29
|
+
gmt_t *gmt;
|
30
|
+
Data_Get_Struct(self, gmt_t, gmt);
|
31
|
+
raise_unless_class_data(gmt);
|
32
|
+
|
33
|
+
void *session = gmt->session;
|
34
|
+
|
35
|
+
gmt_option_t *gmt_opts;
|
36
|
+
gmt_opts = ruby_hash_to_gmt_options(opts, session);
|
37
|
+
gmt_opts = append_inputs_to_gmt_options(files, gmt_opts, session);
|
38
|
+
|
39
|
+
int err = GMT_Call_Module(session, name, -1, gmt_opts);
|
40
|
+
|
41
|
+
GMT_Destroy_Options(session, &gmt_opts);
|
42
|
+
raise_if_error(err, name);
|
43
|
+
|
44
|
+
return Qtrue;
|
45
|
+
}
|
46
|
+
|
47
|
+
static VALUE gmt_makecpt(int argc, VALUE *argv, VALUE self)
|
48
|
+
{
|
49
|
+
return gmt_simple("makecpt", argc, argv, self);
|
50
|
+
}
|
51
|
+
|
52
|
+
static VALUE gmt_pstext(int argc, VALUE *argv, VALUE self)
|
53
|
+
{
|
54
|
+
return gmt_simple("pstext", argc, argv, self);
|
55
|
+
}
|
56
|
+
|
57
|
+
static VALUE gmt_psxy(int argc, VALUE *argv, VALUE self)
|
58
|
+
{
|
59
|
+
return gmt_simple("psxy", argc, argv, self);
|
60
|
+
}
|
61
|
+
|
62
|
+
static void gmt_free(void *p)
|
63
|
+
{
|
64
|
+
gmt_t *gmt = p;
|
65
|
+
|
66
|
+
if (gmt->session)
|
67
|
+
{
|
68
|
+
GMT_Destroy_Session(gmt->session);
|
69
|
+
gmt->session = NULL;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
static VALUE gmt_alloc(VALUE klass)
|
74
|
+
{
|
75
|
+
gmt_t *gmt;
|
76
|
+
|
77
|
+
VALUE obj = Data_Make_Struct(klass, gmt_t, NULL, gmt_free, gmt);
|
78
|
+
|
79
|
+
gmt->session = NULL;
|
80
|
+
|
81
|
+
return obj;
|
82
|
+
}
|
83
|
+
|
84
|
+
static VALUE gmt_init(VALUE self)
|
85
|
+
{
|
86
|
+
gmt_t *gmt;
|
87
|
+
|
88
|
+
Data_Get_Struct(self, gmt_t, gmt);
|
89
|
+
|
90
|
+
gmt->session =
|
91
|
+
GMT_Create_Session("Session name", 2, 0, NULL);
|
92
|
+
|
93
|
+
if (gmt->session == NULL)
|
94
|
+
rb_raise(rb_eNoMemError, "failed to create GMT session");
|
95
|
+
|
96
|
+
return self;
|
97
|
+
}
|
98
|
+
|
99
|
+
static VALUE gmt_release(VALUE self)
|
100
|
+
{
|
101
|
+
gmt_t *gmt;
|
102
|
+
|
103
|
+
Data_Get_Struct(self, gmt_t, gmt);
|
104
|
+
|
105
|
+
if (gmt->session)
|
106
|
+
{
|
107
|
+
GMT_Destroy_Session(gmt->session);
|
108
|
+
gmt->session = NULL;
|
109
|
+
}
|
110
|
+
|
111
|
+
return self;
|
112
|
+
}
|
113
|
+
|
114
|
+
void Init_gmt(void)
|
115
|
+
{
|
116
|
+
VALUE cGMT = rb_const_get(rb_cObject, rb_intern("GMT"));
|
117
|
+
|
118
|
+
rb_define_alloc_func(cGMT, gmt_alloc);
|
119
|
+
rb_define_method(cGMT, "initialize", gmt_init, 0);
|
120
|
+
rb_define_method(cGMT, "free", gmt_release, 0);
|
121
|
+
rb_define_method(cGMT, "makecpt", gmt_makecpt, -1);
|
122
|
+
rb_define_method(cGMT, "pstext", gmt_pstext, -1);
|
123
|
+
rb_define_method(cGMT, "psxy", gmt_psxy, -1);
|
124
|
+
}
|
data/ext/gmt/option.c
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
/*
|
2
|
+
option.c
|
3
|
+
|
4
|
+
GMT expects arguments to be in a linked-list format and provides
|
5
|
+
some library support for creating these. We here convert a hash
|
6
|
+
to this linked-list format.
|
7
|
+
*/
|
8
|
+
|
9
|
+
#include "option.h"
|
10
|
+
|
11
|
+
typedef struct {
|
12
|
+
void *session;
|
13
|
+
gmt_option_t *gmt_opts;
|
14
|
+
} rhtgo_cb_arg_t;
|
15
|
+
|
16
|
+
static void rhtgo_cb_arg_free(void *arg){ };
|
17
|
+
|
18
|
+
static VALUE rhtgo_cb_arg_class;
|
19
|
+
|
20
|
+
static ID append_id(void)
|
21
|
+
{
|
22
|
+
static ID cached = 0;
|
23
|
+
|
24
|
+
if (! cached)
|
25
|
+
cached = rb_intern(">>");
|
26
|
+
|
27
|
+
return cached;
|
28
|
+
}
|
29
|
+
|
30
|
+
static ID id_of_key(VALUE key)
|
31
|
+
{
|
32
|
+
if (TYPE(key) != T_SYMBOL)
|
33
|
+
rb_raise(rb_eArgError, "option keys should be symbols");
|
34
|
+
|
35
|
+
return SYM2ID(key);
|
36
|
+
}
|
37
|
+
|
38
|
+
static char char_of_key_id(ID key_id)
|
39
|
+
{
|
40
|
+
const char *key_s = rb_id2name(key_id);
|
41
|
+
|
42
|
+
if (key_s == NULL || *key_s == '\0')
|
43
|
+
rb_raise(rb_eRuntimeError, "problem getting name of option");
|
44
|
+
|
45
|
+
return *key_s;
|
46
|
+
}
|
47
|
+
|
48
|
+
static gmt_option_t* append_option(void *session,
|
49
|
+
char option_name,
|
50
|
+
const char *option_arg,
|
51
|
+
gmt_option_t *gmt_opts)
|
52
|
+
{
|
53
|
+
gmt_option_t *gmt_opt = GMT_Make_Option(session, option_name, option_arg);
|
54
|
+
return GMT_Append_Option(session, gmt_opt, gmt_opts);
|
55
|
+
}
|
56
|
+
|
57
|
+
static int rhtgo_cb(VALUE key, VALUE value, VALUE arg)
|
58
|
+
{
|
59
|
+
rhtgo_cb_arg_t *rhtgo_cb_arg;
|
60
|
+
|
61
|
+
Data_Get_Struct(arg, rhtgo_cb_arg_t, rhtgo_cb_arg);
|
62
|
+
|
63
|
+
void *session = rhtgo_cb_arg->session;
|
64
|
+
gmt_option_t *gmt_opt, *gmt_opts = rhtgo_cb_arg->gmt_opts;
|
65
|
+
|
66
|
+
ID key_id = id_of_key(key);
|
67
|
+
|
68
|
+
if (key_id == append_id())
|
69
|
+
{
|
70
|
+
/*
|
71
|
+
the append key (>>) is a special case, since this needs to be converted
|
72
|
+
to the (option, argument) pair ('>', '>filename'), see the discussion at
|
73
|
+
http://gmt.soest.hawaii.edu/boards/1/topics/3665?r=3677
|
74
|
+
*/
|
75
|
+
|
76
|
+
if (TYPE(value) != T_STRING)
|
77
|
+
rb_raise(rb_eArgError, "argument for >> option must be a string");
|
78
|
+
|
79
|
+
const char *filename = StringValueCStr(value);
|
80
|
+
size_t len = strlen(filename);
|
81
|
+
char option_arg[len+2];
|
82
|
+
snprintf(option_arg, len+2, ">%s", filename);
|
83
|
+
|
84
|
+
gmt_opts = append_option(session, '>', option_arg, gmt_opts);
|
85
|
+
}
|
86
|
+
else
|
87
|
+
{
|
88
|
+
char option_name = char_of_key_id(key_id);
|
89
|
+
|
90
|
+
switch (TYPE(value))
|
91
|
+
{
|
92
|
+
const char *option_arg;
|
93
|
+
|
94
|
+
case T_STRING:
|
95
|
+
option_arg = StringValueCStr(value);
|
96
|
+
gmt_opts = append_option(session, option_name, option_arg, gmt_opts);
|
97
|
+
break;
|
98
|
+
|
99
|
+
case T_NIL:
|
100
|
+
gmt_opts = append_option(session, option_name, NULL, gmt_opts);
|
101
|
+
break;
|
102
|
+
|
103
|
+
case T_ARRAY:
|
104
|
+
for (size_t i = 0 ; i < RARRAY_LEN(value) ; i++)
|
105
|
+
{
|
106
|
+
VALUE item = RARRAY_PTR(value)[i];
|
107
|
+
if (TYPE(item) != T_STRING)
|
108
|
+
rb_raise(rb_eArgError, "option arguments should be strings");
|
109
|
+
option_arg = StringValueCStr(item);
|
110
|
+
gmt_opts = append_option(session, option_name, option_arg, gmt_opts);
|
111
|
+
}
|
112
|
+
break;
|
113
|
+
|
114
|
+
default:
|
115
|
+
rb_raise(rb_eArgError, "option arguments should be strings or arrays");
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
rhtgo_cb_arg->gmt_opts = gmt_opts;
|
120
|
+
|
121
|
+
return ST_CONTINUE;
|
122
|
+
}
|
123
|
+
|
124
|
+
extern gmt_option_t* ruby_hash_to_gmt_options(VALUE opts, void *session)
|
125
|
+
{
|
126
|
+
gmt_option_t *gmt_opt, *gmt_opts = NULL;
|
127
|
+
rhtgo_cb_arg_t *rhtgo_cb_arg = ALLOC(rhtgo_cb_arg_t);
|
128
|
+
|
129
|
+
rhtgo_cb_arg->session = session;
|
130
|
+
rhtgo_cb_arg->gmt_opts = NULL;
|
131
|
+
|
132
|
+
VALUE arg =
|
133
|
+
Data_Wrap_Struct(rhtgo_cb_arg_class,
|
134
|
+
NULL,
|
135
|
+
rhtgo_cb_arg_free,
|
136
|
+
rhtgo_cb_arg);
|
137
|
+
|
138
|
+
|
139
|
+
rb_hash_foreach(opts, rhtgo_cb, arg);
|
140
|
+
|
141
|
+
return rhtgo_cb_arg->gmt_opts;
|
142
|
+
}
|
143
|
+
|
144
|
+
extern gmt_option_t* append_inputs_to_gmt_options(VALUE files,
|
145
|
+
gmt_option_t* gmt_opts,
|
146
|
+
void *session)
|
147
|
+
{
|
148
|
+
if (TYPE(files) != T_ARRAY)
|
149
|
+
rb_raise(rb_eArgError, "inputs should be an array");
|
150
|
+
|
151
|
+
for (size_t i = 0 ; i < RARRAY_LEN(files) ; i++)
|
152
|
+
{
|
153
|
+
VALUE file = RARRAY_PTR(files)[i];
|
154
|
+
if (TYPE(file) != T_STRING)
|
155
|
+
rb_raise(rb_eArgError, "each input should be a string");
|
156
|
+
const char *option_arg = StringValueCStr(file);
|
157
|
+
gmt_opts = append_option(session, '<', option_arg, gmt_opts);
|
158
|
+
}
|
159
|
+
|
160
|
+
return gmt_opts;
|
161
|
+
}
|
data/ext/gmt/option.h
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
/*
|
2
|
+
option.h
|
3
|
+
|
4
|
+
handle the conversion to GMT linked-list arguments
|
5
|
+
|
6
|
+
Copyright (c) J.J. Green 2016
|
7
|
+
*/
|
8
|
+
|
9
|
+
#ifndef OPTION_H
|
10
|
+
#define OPTION_H
|
11
|
+
|
12
|
+
#include <ruby.h>
|
13
|
+
#include <gmt.h>
|
14
|
+
|
15
|
+
typedef struct GMT_OPTION gmt_option_t;
|
16
|
+
|
17
|
+
extern gmt_option_t* ruby_hash_to_gmt_options(VALUE, void*);
|
18
|
+
extern gmt_option_t* append_inputs_to_gmt_options(VALUE, gmt_option_t*, void*);
|
19
|
+
|
20
|
+
#endif
|
data/lib/gmt.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
class GMT
|
2
|
+
|
3
|
+
def self.psopt(file, position, options)
|
4
|
+
file_options =
|
5
|
+
case position
|
6
|
+
when :first
|
7
|
+
{ :K => nil, :> => file }
|
8
|
+
when :middle
|
9
|
+
{ :O => nil, :K => nil, :>> => file }
|
10
|
+
when :last
|
11
|
+
{ :O => nil, :>> => file }
|
12
|
+
else
|
13
|
+
raise ArguemntError, 'position should be :first, :miidle or :last'
|
14
|
+
end
|
15
|
+
options.merge(file_options)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'gmt/gmt'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gmt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- J.J. Green
|
@@ -54,7 +54,9 @@ dependencies:
|
|
54
54
|
version: '3.4'
|
55
55
|
description: |
|
56
56
|
A Ruby extension for the Generic Mapping Tools (GMT)
|
57
|
-
cartographic toolset (work-in-progress)
|
57
|
+
cartographic toolset (work-in-progress).
|
58
|
+
|
59
|
+
Requires the GMT5 development libraries.
|
58
60
|
email: j.j.green@gmx.co.uk
|
59
61
|
executables: []
|
60
62
|
extensions:
|
@@ -62,6 +64,10 @@ extensions:
|
|
62
64
|
extra_rdoc_files: []
|
63
65
|
files:
|
64
66
|
- ext/gmt/extconf.rb
|
67
|
+
- ext/gmt/gmt.c
|
68
|
+
- ext/gmt/option.c
|
69
|
+
- ext/gmt/option.h
|
70
|
+
- lib/gmt.rb
|
65
71
|
homepage: https://github.com/jjgreen/ruby-gmt
|
66
72
|
licenses:
|
67
73
|
- MIT
|
@@ -70,6 +76,7 @@ post_install_message:
|
|
70
76
|
rdoc_options: []
|
71
77
|
require_paths:
|
72
78
|
- lib
|
79
|
+
- ext
|
73
80
|
required_ruby_version: !ruby/object:Gem::Requirement
|
74
81
|
requirements:
|
75
82
|
- - ">="
|