-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: use rewriter to modify wrapping #3
Conversation
Error checking all functions that return a |
💯 It'll be good to figure out the appropriate names for the enums too, e.g. https://github.com/visr/GDAL.jl/blob/rewriter/src/clang/common.jl#L227 versus https://github.com/wkearn/RasterIO.jl/blob/master/src/clang/gdal_cdefs.jl#L55 |
I'm not sure about going all the way in removing all the types from the function signatures either, even if it has been unnecessarily restrictive on a number of occasions |
A few other things have snuck into this PR, because I need to start testing/using this API to find the parts that need improvement. For instance, |
I'm really happy with the progress you're making here.
I personally prefer to
I think it'll be good if we can do the error-checking at the low-level GDAL layer~~, but it sounds like a tall order for the rewrite phase though. We might need auxiliary information from the documentation too, so it's probably better to wait before doing another PR for error-checking.~~ Edit: I just saw your work on checking null pointers, and emitting error messages, and it's great! Am I right to check that only the CPLErrors are left?
Sure. But my preference will be for it to not overwrite the original GDAL function (see above). |
Thanks for your comments. It is good to decide where to draw the line between the low-level GDAL interface and the higher-level Julia functions. I'm not trying to take the step from low-level to high-level directly in this PR. The way I see it, this is all still the low-level GDAL interface. It's good to have the whole thing available for if somebody wants to use a function that is not in the higher-level API. This means it should be directly usable from Julia, without it being too awkward. At the same time, I agree the higher level API should be written entirely from function calls to the lower level API, no
What I currently have in mind for the low-level API:
For the case of GDALGetMetadata returning a Regarding the low-level error checking, with a8c750b we are hooked into GDAL's internal error checking. If an error is raised, the type, code and message gets sent to our Julia function to deal with. This should take care of most low-level error handling needs, and we can change the Julia function when we're not happy. On top of that I added the C_NULL return check for selected return types, because some things GDAL doesn't consider an error that we may want to be an error. I could remove this automatic C_NULL check though. |
I think that's what I was hinting at. I guess I wasn't thinking of having a high-level API in this package. You might be able to convince me otherwise though. What I have in mind: module GDAL
module capi
# directly from Clang, i.e. "really" low-level
# pointers/error-messages/etc handled here
function GDALGetAsyncStatusTypeByName(arg1::Ptr{UInt8})
...
function GDALDestroyDriver(arg1::Ptr{Void})
end
# auto re-written, i.e. "nice" low-level
# pointers should be disambiguated into the corresponding GDAL types
abstract MajorObject
immutable Dataset <: MajorObject
ptr::Ptr{Void}
end
immutable Driver <: MajorObject
ptr::Ptr{Void}
end
# takes in and emits julian types
# (function names generated by removing GDAL/OGR/CPL in front,
# and lowercasing everything)
function getasyncstatustypebyname(name::String)
...
destroydriver(d::Driver) = capi.GDALDestroyDriver(d.ptr)
end I don't think it's the responsibility of this package to provide a nicer API than that -- that sounds like the job of downstream packages (e.g. module RasterIO # downstream package
import GDAL
type RasterDataset
dataset::GDAL.Dataset
nbands::Int
width::Int
height::Int
end
asyncstatustype(name::String) = GDAL.getasyncstatustypebyname(name)
destroy(d::GDAL.Driver) = GDAL.destroydriver(d)
end
module OGR
import GDAL
type FeatureDataset
dataset::GDAL.Dataset
...
end
...
end You might ask -- why have
|
This package will also need to provide build scripts, maintain documentation for re-written functions, and test that the wrappers are working etc, for (potentially) different GDAL versions in the future. I think that sounds like enough responsibility on its own, without having to also worry about the friendliness of the package for end-users? |
Ok that's clear. I understand the possible benefits of having a I also think the true high-level API is better suited for other packages, it was a 'thin' wrapper after all. |
function rewriter(ex::Expr) | ||
# comment out predefined expressions | ||
if in(ex, skip_expr) | ||
return string("# ", e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be return string("# ", ex)
?
Sorry for coming so late into this thread, thanks for starting this. I really like the model proposed by @yeesian. However, can we still keep the error handling as it is right now or do you think this is too high-level? |
@meggart thanks for the comments. I addressed them in the last commit. Also stopped the rewriting and put everything in a submodule |
Add an __init__ function that always runs GDALAllRegister on startup. Add tests that one ore more drivers exist. Use GDAL's custom error handler funcitonality: all errors internally reported to CPLError() are now handled by a julia function currently this function always throws an error such that we don't need to check for them For other functions such as GetDriverByName, when a driver cannot be found, this is not reported to CPLError() and a NULL pointer is returned. In this case we ofter still want an error, that is what checknull() does.
What's left here to wrap things up? Might I be able to help in any way? |
I think it is indeed best to wrap up this PR such that we can think about On Fri, 20 Nov 2015 20:04 Yeesian Ng notifications@github.com wrote:
|
Yup, I've checked it out, and it works for me. @meggart? |
I can test this evening. |
Looks good for me, too. Please merge when you are ready |
🎉 |
So far this PR should cover all manual edits to the wrapped code in RasterIO.jl, namely:
CPLErr
was added manually: solved by wrappingcpl_error.h
::Cint
with::Integer
as in wkearn/RasterIO.jl@7da9573wrap_gdal.jl
comment out some lines incommon.jl
, as in ad44facThis rewriting functionality is quite powerful, but I am not yet sure of all useful applications or what to do with those. Some ideas:
padfSrcGeoTransform::Ptr{Cdouble}
: rewrite to acceptVector{Float64}
pszDstWKT::Ptr{UInt8}
: rewrite to acceptAbstractString
Another extreme would be to omit types in function signatures altogether, like is done in
CUDArt.jl
. We could also convert all function names to lowercase for instance. But I'm currently not convinced these last two are good ideas. Any input or other ideas welcome.