;+ ; NAME: ; DXHELP ; ; AUTHOR: ; Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770 ; craigm@lheamail.gsfc.nasa.gov ; ; PURPOSE: ; Perform HELP equivalent at any point in IDL call stack ; ; CALLING SEQUENCE: ; DXHELP, X0, X1, ..., [ LEVEL=LEVEL ] ; ; DESCRIPTION: ; ; DXHELP performs the equivalent of HELP for the variables at any ; level in the IDL call stack. ; ; The call level to be examined is determined by the current ; debugging "focus." By default this is the deepest level in the ; call stack -- where the breakpoint occurred. However, this level ; can be changed by using the DXUP and DXDOWN procedures. ; ; If the ALL keyword is set, then all variables are examined. ; ; INPUTS: ; ; Xi - variables to be examined, either quoted or unquoted. ; Non-string expressions are diagnosed, but of course refer to ; the deepest call level. If the ALL keyword is set then the ; Xi parameters are ignored. ; ; KEYWORDS: ; ; LEVEL - the call level to be examined, if not the current ; debugging focus. ; ; ALL - if set, then all variables at the current focus level are ; examined. ; ; ; EXAMPLE: ; ; dxhelp ; ; Print all variables at current debugging focus level ; ; SEE ALSO: ; ; DXUP, DXDOWN, DXHELP, DXPRINT ; ; MODIFICATION HISTORY: ; Written, 15 Apr 2000 ; Added ALL keyword; changed N_PARAMS() EQ 0 behavior, CM 17 Apr ; 2000 ; DXHELP_VALUE now prints correct string and byte values, CM 23 Apr ; 2000 ; Add support for printing structures with FULL_STRUCT, CM 08 Feb ; 2001 ; Added forward_function for DXHELPFORM, CM 08 Apr 2001 ; Print more info about POINTER type, CM 30 Apr 2001 ; ; ; $Id: dxhelp.pro,v 1.5 2001/04/30 15:26:53 craigm Exp $ ;- ; Copyright (C) 2000-2001, Craig Markwardt ; This software is provided as is without any warranty whatsoever. ; Permission to use, copy, modify, and distribute modified or ; unmodified copies is granted, provided this copyright and disclaimer ; are included unchanged. ;- ; INCLUDED FROM HELPFORM.PRO forward_function dxhelpform function dxhelpform, name0, value, single=single, shortform=short, $ width=width0, tagform=tagform, structure=struct, $ _EXTRA=extra ;; Names of all the known IDL types, as of IDL 5.2 typenames = ['UNDEFINED', 'BYTE', 'INT', 'LONG', 'FLOAT', 'DOUBLE', $ 'COMPLEX', 'STRING', 'STRUCT', 'DCOMPLEX', 'POINTER', $ 'OBJREF', 'UINT', 'ULONG', $ 'LONG64', 'ULONG64', 'UNKNOWN'] blanks = string(replicate(32b,80)) if n_elements(sz) LT 3 then sz = size(value) tp = sz(sz(0)+1) < 16 if n_elements(name0) EQ 0 then name0 = '' name = strtrim(name0(0),2) nlen = 15 ;; Length of name tlen = 9 ;; Length of type name if n_elements(width0) EQ 0 then width0 = 80 width = floor(width0(0)) if tp EQ 8 AND keyword_set(struct) then begin sz1 = size(value) if sz1(sz1(0)+1) NE 8 then goto, NOT_STRUCT nt = n_tags(value) len = n_tags(value, /length) tn = tag_names(value) sn = tag_names(value, /structure_name) if sn EQ '' then sn = '' a = string(sn, nt, len, $ format='("** Structure ",A0,", ",I0," tags, length=",I0,":")') for i = 0, nt-1 do begin a = [a, ' '+dxhelpform(tn(i), value(0).(i), /tagform)] endfor return, a endif NOT_STRUCT: if NOT keyword_set(short) then begin ;; Pad the name out, or else put the name on a line by itself if strlen(name) GT nlen then begin if keyword_set(single) then begin a1 = name+' ' endif else begin a0 = name a1 = strmid(blanks,0,nlen)+' ' endelse endif else begin a1 = strmid(name+blanks,0,nlen)+' ' endelse a1 = a1 + strmid(typenames(tp)+blanks,0,tlen) if NOT keyword_set(tagform) then $ a1 = a1 +' = ' endif else begin a1 = strmid(typenames(tp)+blanks,0,tlen) endelse ndims = sz(0) if ndims GT 0 then begin ;; It is an array, compose the dimensions dims = sz(1:ndims) v = 'Array[' for i = 0L, ndims-1 do begin v = v + strtrim(dims(i),2) if i LT ndims-1 then v = v + ', ' endfor v = v + ']' ;; If it is a structure, add the structure name (structures are ;; never scalars) if NOT keyword_set(short) AND tp EQ 8 then begin ;; Protect against empty value if n_elements(stname) EQ 0 then begin if n_elements(value) GT 0 then v0 = value(0) else v0 = {dummy:0} sn = tag_names(v0, /structure_name) sn = sn(0) endif else begin sn = strtrim(stname(0),2) endelse if sn EQ '' then sn = '' v = '-> '+sn+' ' + v endif endif else begin ;; It is a scalar ;; Protect against empty or vector value if n_elements(value) GT 0 then begin v0 = value(0) endif else begin if tp NE 10 AND tp NE 11 then tp = 0 endelse case tp < 16 of 0: v = '' 1: v = string(v0, format='(I4)') 7: begin w = (width - 35) > 5 if strlen(v0) GT w then $ v = "'"+strmid(v0,0,w)+"'..." $ else $ v = "'"+v0+"'" end 10: begin sz = size(v0) if sz(sz(0)+1) EQ 10 then v = string(v0(0), /print) $ else v = '' end 11: begin if n_elements(stname) EQ 0 then begin forward_function obj_class sz = size(v0) if sz(sz(0)+1) EQ 11 then sn = '('+obj_class(v0)+')' $ else sn = '' endif else begin sn = '('+strupcase(strtrim(stname(0),2))+')' endelse v = '' end 16: v = '' else: v = string(v0) endcase endelse if keyword_set(short) then return, a1 + '('+v+')' a1 = a1 + v if n_elements(a0) GT 0 then return, [a0, a1] else return, a1 end ; END INCLUDE pro dxhelp, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, level=level0, all=all, $ _EXTRA=extra @dxcommon.pro dxlreset if n_elements(level0) EQ 0 then level0=dblevel level = floor(level0(0)) ;; Print the current debugging levels dxplevel, level=level, current=keyword_set(all) ;; Two different behaviors, depending on whether parameters are passed. if keyword_set(all) then begin ;; ALL was set... we extract the names of the variables from the ;; procedure itself. vars = routine_names(variables=level) if n_elements(vars) EQ 1 then $ if vars(0) EQ '' then return for i = 0L, n_elements(vars)-1 do begin ;; Retrieve the variable's value, but make sure it is not ;; undefined name = vars(i) val = 0 if name EQ '' then name = '' sz = size(routine_names(vars(i), fetch=level)) dummy = temporary(val) if sz(sz(0)+1) NE 0 then val = routine_names(vars(i), fetch=level) print, dxhelpform(name, val, _EXTRA=extra), format='(A)' endfor endif else begin ;; ALL was not set, so we examine individual arguments if n_params() EQ 0 then return thislev = routine_names(/level) for i = 0L, n_params()-1 do begin ;; First, extract the parameter name using ROUTINE_NAMES magic name = '' ii = strtrim(i,2) cmd = 'name = routine_names(x'+ii+',arg_name=thislev-1)' if execute(cmd) NE 1 then goto, NEXT_PARM if n_elements(name) LT 1 then goto, NEXT_PARM name0 = name(0) name = name0 if name0 EQ '' then begin ;; The value might be a quoted string... see if it is! cmd = 'val = x'+ii if execute(cmd) NE 1 then goto, NEXT_PARM sz = size(val) if sz(sz(0)+1) EQ 7 then begin ;; It was a string! name0 = val goto, GET_VAL endif name = '' val = 0 endif else begin GET_VAL: ;; Retrieve the value, again guarding against undefined values sz = size(routine_names(name0, fetch=level)) val = 0 dummy = temporary(val) if sz(sz(0)+1) NE 0 then val = routine_names(name0, fetch=level) endelse ;; Print it print, dxhelpform(name, val, _EXTRA=extra), format='(A)' NEXT_PARM: endfor endelse end