C API and stdout

Concerning the GMT C API, for modules which only write to stdout (grdinfo for example), I’d like to be able to capture that output. As I understand it, this needs virtual files which I’d not come across before (there is an intriguing mention of “the hidden option ->filename” in the documentation). Are there any examples of usage of this which might be helpful for the virtual file n00b?

Thanks in advance!

Jim

Jim,
In the src dir there are a series of testapi_xxx.c that may be of some help. I don’t know any programs that read directly from the API memory other than the GMTMEX and GMT.jl. The first is C so it may be of help too, though GMT.jl also reads pretty much like C i the functions that interface with the GMT API. Sorry, I don’t remember more without diving into the code.

Thanks Jaoquim, I’ll have a look t those

A further question on this having had a read around the code: so if one wants to capture stdout, create a virtual file, then add ->filename to the command-line options of the module (where filename was specified in the creation of the virtual file). But virtual file creation requires specification of the family of the data (GMT_IS_GRID and so on), and there seems to be no “generic” family, suggesting that this mechanism is solely for the capture of structured data. One would not use this to capture the verbose output of modules who’s data output is already directed to file, or the semi-structured output of grdinfo for example. Would that be a fair summary?

If so, not a problem, I can capture stdout in the usual generic POSIX fashion with dup etc.

My motivation here is for my Ruby interface to GMT, I’d like to always capture stdout (structured, unstructured, verbose output etc) and then pass it back to Ruby’s stdout abstraction for the caller to handle as they see fit.

GMT has the GMTgrid, GMTimage, GMTdataset and GMTcpt types much like in https://www.generic-mapping-tools.org/GMTjl_doc/documentation/general/types/index.html#the_gmtjl_types_important

Have a deep look at GMT.jl gmt_main.jl, namely to

GMTdatasets store both matrices and text data. With them we can have both numeric

julia> D = grdinfo("@earth_relief_10m", C=true)

1×12 GMTdataset{Float64, 2}
 Row │ lon_min  lon_max  lat_min  lat_max    z_min   z_max        dx        dy  n_cols  n_rows  reg  isgeog
─────┼──────────────────────────────────────────────────────────────────────────────────────────────────────
   1 │  -180.0    180.0    -90.0     90.0  -9732.5  6118.5  0.166667  0.166667  2161.0  1081.0  0.0     1.0

or text

julia> D = grdinfo("@earth_relief_10m")
11-element Vector{String}:
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 53 bytes ⋯ "h Relief v2.7 at 10 arc minutes"
 "C:/Users/j/.gmt/server/earth/earth_relief/earth_relief_10m_g.grd: Command: "
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 151 bytes ⋯ "/doi.org/10.1029/2019EA000658]"
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 53 bytes ⋯ "stration used [Geographic grid]"
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 69 bytes ⋯ "format (16-bit integer), CF-1.7"
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 89 bytes ⋯ "name: longitude n_columns: 2161"
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 83 bytes ⋯ "in) name: latitude n_rows: 1081"
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 52 bytes ⋯ "max: 6118.5 name: elevation (m)"
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 66 bytes ⋯ " packed z-range: [-19465,12237]"
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 71 bytes ⋯ " shuffle: on deflation_level: 9"
 "C:/Users/j/.gmt/server/earth/ea" ⋯ 17 bytes ⋯ "relief_10m_g.grd: Default CPT: "
julia> D.text[1]
"C:/Users/j/.gmt/server/earth/earth_relief/earth_relief_10m_g.grd: Title: SRTM15 Earth Relief v2.7 at 10 arc minutes"

If Ruby has FFI I’m sure you can replicate this behavior by mimicking the closest possible the GMT.jl interface (that, in turn, mimicked the GMTMEX).