pro mg_dlm::setProperty, basename=basename, $
name=name, description=description, version=version, $
source=source, build_date=build_date
compile_opt strictarr
if (n_elements(basename) gt 0L) then self.basename = basename
if (n_elements(name) gt 0L) then self.name = name
if (n_elements(description) gt 0L) then self.description = description
if (n_elements(version) gt 0L) then self.version = version
if (n_elements(source) gt 0L) then self.source = source
if (n_elements(build_date) gt 0L) then self.build_date = build_date
end
pro mg_dlm::getProperty, name=name
compile_opt strictarr
if (arg_present(name)) then name = self.name
end
function mg_dlm::output_c
compile_opt strictarr
output = string(systime(), format='(%"// Generated by dist_tools: %s")')
output += mg_newline()
foreach i, self.systemIncludes do begin
output += string(mg_newline(), i, format='(%"%s#include <%s>")')
endforeach
output += mg_newline()
foreach i, self.userIncludes do begin
output += string(mg_newline(), i, format='(%"%s#include \"%s\"")')
endforeach
output += mg_newline()
idltypes_filename = filepath('mg_get_idltypes.c', root=mg_src_root())
nlines = file_lines(idltypes_filename)
lines = strarr(nlines)
openr, lun, idltypes_filename, /get_lun
readf, lun, lines
free_lun, lun
output += mg_strmerge(lines)
output += mg_newline()
output += mg_newline()
foreach r, self.routines do begin
output += r->output()
output += mg_newline()
output += mg_newline()
endforeach
output += mg_newline()
output += string(mg_newline(), format='(%"int IDL_Load(void) {%s")')
output += string(self.name, mg_newline(), mg_newline(), $
format='(%" if (!(msg_block = IDL_MessageDefineBlock(\"%s\", IDL_CARRAY_ELTS(msg_arr), msg_arr))) { return IDL_FALSE; } %s%s")')
if (self.nFunctions gt 0L) then begin
output += string(mg_newline(), format='(%" static IDL_SYSFUN_DEF2 function_addr[] = {%s")')
foreach r, self.routines do begin
r->getProperty, name=name, $
prefix=prefix, $
cprefix=cprefix, $
return_type=returnType, $
n_min_parameters=nMinParameters, $
n_max_parameters=nMaxParameters
if (returnType eq 0L) then continue
output += string(cprefix, $
name, $
strupcase(prefix + name), $
nMinParameters, $
nMaxParameters, $
mg_newline(), $
format='(%" { %s_%s, \"%s\", %d, %d, 0, 0 },%s")')
endforeach
output += string(mg_newline(), format='(%" };%s")')
output += mg_newline()
endif
if (self.nProcedures gt 0L) then begin
output += string(mg_newline(), format='(%" static IDL_SYSFUN_DEF2 pro_addr[] = {%s")')
foreach r, self.routines do begin
r->getProperty, name=name, $
prefix=prefix, $
cprefix=cprefix, $
return_type=returnType, $
n_min_parameters=nMinParameters, $
n_max_parameters=nMaxParameters
if (returnType ne 0L) then continue
output += string(cprefix, $
name, $
strupcase(prefix + name), $
nMinParameters, $
nMaxParameters, $
mg_newline(), $
format='(%" { (IDL_SYSRTN_GENERIC) %s_%s, \"%s\", %d, %d, 0, 0 },%s")')
endforeach
output += string(mg_newline(), format='(%" };%s")')
output += mg_newline()
endif
func_reg = 'IDL_SysRtnAdd(function_addr, TRUE, IDL_CARRAY_ELTS(function_addr))'
pro_reg = 'IDL_SysRtnAdd(pro_addr, FALSE, IDL_CARRAY_ELTS(pro_addr))'
output += string(self.nFunctions gt 0L ? func_reg : '', $
(self.nFunctions gt 0L && self.nProcedures gt 0L) ? ' && ' : '', $
self.nProcedures gt 0L ? pro_reg : '', $
format='(%" return %s%s%s;")')
output += string(mg_newline(), format='(%"%s}")')
return, output
end
function mg_dlm::output_dlm
compile_opt strictarr
output = ''
output += string(self.name, mg_newline(), format='(%"MODULE %s%s")')
if (self.description ne '') then begin
output += string(self.description, mg_newline(), format='(%"DESCRIPTION %s%s")')
endif
if (self.version ne '') then begin
output += string(self.version, mg_newline(), format='(%"VERSION %s%s")')
endif
if (self.source ne '') then begin
output += string(self.source, mg_newline(), format='(%"SOURCE %s%s")')
endif
output += string(self.build_date, mg_newline(), format='(%"BUILD_DATE %s%s")')
output += mg_newline()
foreach r, self.routines do begin
r->getProperty, name=name, $
prefix=prefix, $
return_type=returnType, $
n_min_parameters=nMinParameters, $
n_max_parameters=nMaxParameters
format = string(strlen(name) > 30, format='(%"(\%\"\%-10s \%-%ds \%4d \%4d\%s\")")')
output += string(returnType eq 0L ? 'PROCEDURE' : 'FUNCTION', $
strupcase(prefix + name), $
nMinParameters, $
nMaxParameters, $
mg_newline(), $
format=format)
endforeach
return, output
end
pro mg_dlm::write
compile_opt strictarr
output = [self->output_c(), self->output_dlm()]
ext = ['.c', '.dlm']
for i = 0, 1 do begin
openw, lun, self.basename + ext[i], /get_lun
printf, lun, output[i]
free_lun, lun
endfor
end
pro mg_dlm::build, _extra=e
compile_opt strictarr
if (n_elements(self.includeDirs) gt 0L) then begin
includes = strjoin('-I"' + self.includeDirs->toArray() + '"', ' ')
endif else includes = ''
if (n_elements(self.libFiles) gt 0L) then begin
if (n_elements(self.libDirs) gt 0L) then begin
libs = strjoin('-L' + self.libDirs->toArray(), ' ')
endif else libs = ''
libs += ' '
if (n_elements(self.libFiles) gt 0L) then begin
libs += strjoin('-l' + self.libFiles->toArray(), ' ')
endif
endif else libs = ''
mg_make_dll, self.basename, $
extra_cflags=includes, extra_lflags=libs, $
_extra=e
end
pro mg_dlm::register
compile_opt strictarr
dlm_register, self.basename + '.dlm'
end
pro mg_dlm::load
compile_opt strictarr
dlm_load, self.basename
end
pro mg_dlm::addInclude, name, system=system, $
header_directory=headerDir, $
lib_directory=libDir, lib_files=libFiles
compile_opt strictarr
if (keyword_set(system)) then begin
if (total(self.systemIncludes eq name, /integer) eq 0L) then begin
self.systemIncludes->add, name
endif
endif else begin
found = 0B
foreach n, name do begin
if (total(self.userIncludes eq n, /integer) eq 0L) then begin
self.userIncludes->add, n
endif else found = 1B
endforeach
if (~found) then begin
if (n_elements(headerDir) gt 0L) then self.includeDirs->add, expand_path(headerDir)
if (n_elements(libDir) gt 0L) then begin
_libDir = libDir
for d = 0L, n_elements(libDir) - 1L do begin
_libDir[d] = expand_path(libDir[d])
endfor
self.libDirs->add, _libDir, /extract
endif
if (n_elements(libFiles) gt 0L) then self.libFiles->add, libFiles, /extract
endif
endelse
end
pro mg_dlm::addRoutine, routine
compile_opt strictarr
self.routines->add, routine
routine->getProperty, return_type=returnType
if (returnType eq 0L) then self.nProcedures++ else self.nFunctions++
end
pro mg_dlm::addRoutineFromPrototype, proto
compile_opt strictarr
name = mg_parse_cprototype(proto, params=params, return_type=return_type)
r = mg_routinebinding(name=name, return_type=return_type, prototype=proto)
for i = 0L, n_elements(params) - 1L do begin
param_type = mg_parse_cdeclaration(params[i], $
pointer=pointer, array=array, $
device=device)
if (param_type ne 0) then begin
r->addParameter, type=param_type, $
pointer=pointer, array=array, device=device, $
prototype=params[i]
endif
endfor
self->addRoutine, r
end
pro mg_dlm::addRoutinesFromHeaderFile, filename
compile_opt strictarr
on_error, 2
if (~file_test(filename)) then message, 'header file not found'
nlines = file_lines(filename)
prototypes = strarr(nlines)
openr, lun, filename, /get_lun
readf, lun, prototypes
free_lun, lun
foreach p, prototypes do begin
if (strtrim(p, 2) ne '' && strmid(strtrim(p, 2), 0, 2) ne '//') then begin
self->addRoutineFromPrototype, p
endif
endforeach
end
pro mg_dlm::addPoundDefineAccessor, name, type=type
compile_opt strictarr
self->addRoutine, mg_routinePoundDefineAccessor(name=name, return_type=type)
end
pro mg_dlm::cleanup
compile_opt strictarr
obj_destroy, [self.routines, $
self.systemIncludes, self.userIncludes, $
self.includeDirs, self.libDirs, self.libFiles]
end
function mg_dlm::init, _extra=e
compile_opt strictarr
self.systemIncludes = list()
self.userIncludes = list()
self.routines = list()
self.includeDirs = list()
self.libDirs = list()
self.libFiles = list()
self.systemIncludes->add, 'stdio.h'
self.userIncludes->add, 'idl_export.h'
self.source = 'Generated by dist_tools'
self.build_date = systime()
self->setProperty, _extra=e
return, 1
end
pro mg_dlm__define
compile_opt strictarr
define = { mg_dlm, $
basename: '', $
name: '', $
description: '', $
version: '', $
source: '', $
build_date: '', $
routines: obj_new(), $
nFunctions: 0L, $
nProcedures: 0L, $
systemIncludes: obj_new(), $
userIncludes: obj_new(), $
includeDirs: obj_new(), $
libDirs: obj_new(), $
libFiles: obj_new() $
}
end
f = mg_dlm(basename='format_example', $
name='FORMAT_EXAMPLE', $
description='Example of using dist_tools bindings', $
version='1.0', source='dist_tools')
f->addRoutineFromPrototype, 'char *IDL_OutputFormatFunc(int type)'
f->addRoutineFromPrototype, 'int IDL_OutputFormatLenFunc(int type)'
f->addRoutineFromPrototype, 'int IDL_TypeSizeFunc(int type)'
f->addRoutineFromPrototype, 'char *IDL_TypeNameFunc(int type)'
f->addRoutineFromPrototype, 'void IDL_TTYReset(void)'
f->addRoutineFromPrototype, 'IDL_LONG64 IDL_SysRtnNumEnabled(int is_function, int enabled)'
f->addPoundDefineAccessor, 'IDL_TYP_UNDEF', type=3L
f->write
f->build, /show_all_output
f->register
obj_destroy, f
print, 'Calling a routine from the created DLM...'
status = execute('print, IDL_OutputFormatFunc(5L), format=''(%"Default double format: %s")''')
print, 'Accessing a #define from idl_export.h...'
status = execute('print, get_idl_typ_undef(), format=''(%"#define IDL_TYP_UNDEF %d")''')
end