here's a preliminary patch. I can provide a build if you tell me which camera and firmware version.
The patch adds two functions to Lua:
fl = get_focal_length(zoom_pos)
zoom_pos is the zoom position to get the focal length of. Out of range zoom_pos values are clamped to the closest valid value. If zoom_pos is omitted, the focal length for the current zoom position is returned.
The return value fl is the focal length, in the usual CHDK mm*1000 units.
efl = get_eff_focal_length(zoom_pos)
as above, but the 35mm equivalent focal length
But wait, you say, that's not what I asked for at all?!
The rest is in Lua module, zoomutil.lua. As usual, import the module like
zu = require'zoomutil'
The module provides
pos = zu.get_zoom_for_fl(focal_length)
where focal_length: desired focal length, expressed as mm*1000
pos: zoom position with focal length closest to specified value
zu.get_zoom_for_efl is the same, but 35mm equivalent.
zu.set_zoom_for_fl and zu.set_zoom_for_efl set the zoom position from fl/efl values using the functions above.
Additional functions allow converting between fl and efl, as well as getting the minimum and maximum. Note the actual fl/efl conversion in CHDK is per platform and only available for specific zoom steps, so it's possible the conversion functions will give slightly different values than get_focal_length and get_eff_focal_length in some instances. In other words, if you do
zu.fl_to_efl(f) == ef
might not be true, although the values should be very close.
ubasic already has get_focal_length, which returns the focal length for the current zoom step (In Lua, this was previously available through get_dofinfo only). I'm not sure if ubasic can support optional arguments. AFAIK it does not have a way to get efl. I'm not inclined to add the new functionality to ubasic, but it will make the documentation for get_focal_length somewhat confusing.
The no-argument variants of get_focal_length and get_eff_focal_length are somewhat redundant with get_dofinfo, but they are trivial to implement, and seemed convenient. I though about allowing passing a zoom pos to get_dofinfo, but that seemed ugly, since some dofinfo values are dependent on other settings.
Any feedback anyone has before I check this in is welcome.