zOs/REXX/FMTF

/* copy fmtF   begin **************************************************/
fmtFCsvAll: procedure expose m.
parse arg fSep
    if fSep = '' then
        fSep = ','
    if \ inO(i) then
        return
    f = oFlds(i)
    li = ''
    do fx=1 to m.f.0
        li = li',' substr(m.f.fx, 2)
        end
    call out substr(li, 3)
    do until \ inO(i)
        li = ''
        do fx=1 to m.f.0
            if m.f.fx = '' then do
                li = li',' m.i
                end
            else do
                fld = substr(m.f.fx, 2)
                li = li',' m.i.fld
                end
            end
        call out substr(li, 3)
        end
    return
endProcedure fmtFCsvAll

fmtFAdd: procedure expose m.
parse arg m
    fx = m.m.0
    do ax=2 to arg()
        fx = fx + 1
        parse value arg(ax) with m.m.fx.fld m.m.fx.fmt m.m.fx.tit
        end
    m.m.0 = fx
    return m
endProcedure fmtFAdd

fmtFAddFlds: procedure expose m.
parse arg m, st
    fx = m.m.0
    do sx=1 to m.st.0
        fx = fx + 1
        parse value m.st.sx with m.m.fx.fld m.m.fx.fmt m.m.fx.tit
        end
    m.m.0 = fx
    return m
endProcedure fmtFAddFlds

fmtF: procedure expose m.
parse arg m, st
    if arg() >= 3 then
        mid = arg(3)
    else
        mid = ' '
    li = ''
    do fx=1 to m.m.0
        f = st || m.m.fx.fld
        li = li || mid || fmtS(m.f, m.m.fx.fmt)
        end
    return substr(li, 1 + length(mid))
endProcedure fmtF

fmtFTab: procedure expose m.
parse arg m, rdr, wiTi
    if m == '' then
        m = 'FMTF.F'
    return fmtFWriteSt(fmtFReset('FMTF.F'), j2Buf(rdr)'.BUF', wiTi)
endProcedure fmtFTab

fmtFReset: procedure expose m.
parse arg m
    m.m.0 = 0
    return m
endProcedure fmtFReset

fmtFWriteSt: procedure expose m.  ?????????
parse arg m, st, wiTi
    if m.st.0 < 1 then
        return 0
    if m.m.0 < 1 then
        call fmtFAddFlds m, oFlds(m.st.1)
    call fmtFDetect m, st
    if wiTi \== 0 then
        call out fmtFTitle(m)
    do sx=1 to m.st.0
        call out fmtF(m, m.st.sx)
        end
    return st.0
fmtFWriteSt

fmtFTitle: procedure expose m.
parse arg m
    if arg() >= 2 then
        mid = arg(2)
    else
        mid = ' '
    li = ''
    do fx=1 to m.m.0
        if m.m.fx.tit \= '' then
            t = m.m.fx.tit
        else if m.m.fx.fld = '' then
            t = '='
        else
            t = substr(m.m.fx.fld, 1+abbrev(m.m.fx.fld, '.'))
        li = li || mid || fmtS(t, m.m.fx.fmt)
        end
    return substr(li, 1 + length(mid))

    res = ''
    fs = m.form.FLDS
    do ix=1 to m.fs.0
        res = res fmtS(m.fs.ix, m.form.ix)
        end
    return substr(res, 2)
endProcedure fmtFldTitle


fmtFldTitle: procedure expose m.
parse arg form
    res = ''
    fs = m.form.FLDS
    do ix=1 to m.fs.0
        res = res fmtS(m.fs.ix, m.form.ix)
        end
    return substr(res, 2)
endProcedure fmtFldTitle

fmtFld: procedure expose m.
parse arg form, st
    res = ''
    fs = m.form.FLDS
    do ix=1 to m.fs.0
        f = m.fs.ix
        res = res fmt(m.st.f, m.form.ix)
        end
    return substr(res, 2)
endProcedure fmtData

fmtFldSquash: procedure expose m.
parse arg newFo, class, src
    fs = oFlds(class)
    do fx = 1 to m.fs.0
        fd = m.fs.fx
        lMi = 9e9
        lMa = 0
        rMi = 9e9
        rMa = 0
        len = 0
        do sx = 1 to m.src.0
            x = verify(m.src.sx.fd, ' ', 'n')
            if x < 1 then
                iterate
            lMi = min(lMi, x)
            lMa = max(lMa, x)
            x = length(strip(m.src.sx.fd, 't'))
            rMi = min(rMi, x)
            rMa = max(rMa, x)
            end
        if rMa = 0  then
            m.newFo.fx = 'w1,1'len
        else
            m.newFo.fx = 'w'lMi',' || (rMa+1-lMi)
        end
    m.newFo.0 = m.fs.0
    m.newFo.flds = fs
    return newFo
endProcedure fmtFldSquash

fmtFDetect: procedure expose m.
parse arg m, st
    do fx=1 to m.m.0
        if m.m.fx.fmt = '' then
            m.m.fx.fmt = fmtFDetect1(st, m.m.fx.fld)
        end
    return m
endProcedure fmtDetect

fmtFDetect1: procedure expose m.
parse arg st, suf
    aMa = -1
    aCnt = 0
    aDiv = 0
    nCnt = 0
    nMi = ''
    nMa = ''
    nDi = -1
    nBe = -1
    nAf = -1
    eMi = ''
    eMa = ''
    do sx=1 to m.st.0
        f = m.st.sx || suf
        v = m.f
        aMa = max(aMa, length(v))
        if \ dataType(v, 'n') then do
            aCnt = aCnt + 1
            if length(v) > 100 then
                aDiv = 99
            else if aDiv <=3 then
                if aDiv.v \== 1 then do
                    aDiv.v = 1
                    aDiv = aDiv + 1
                    end
            iterate
            end
        nCnt = nCnt + 1
        if nMi == '' then
            nMi = v
        else
            nMi = min(nMi, v)
        if nMa == '' then
            nMa = v
        else
            nMa = max(nMa, v)
        parse upper var v man 'E' exp
        if exp \== '' then do
            en = substr(format(v, 2, 2, 9, 0), 7)
            if en = '' then
                en = exp
            if eMi == '' then
                eMi = en
            else
                eMi = min(eMi, en)
            if eMa == '' then
                eMa = en
            else
                eMa = max(eMa, en)
            end
        parse upper var man be '.' af
        nBe = max(nBe, length(be))
        nAf = max(nAf, length(af))
        nDi = max(nDi, length(be || af))
        end
/*  say 'suf' suf aCnt 'a len' aMa 'div' aDiv
    say '   ' nCnt 'n' nMi'-'nMa 'be' nBe 'af' nAf,
            'di' nDi 'ex' eMi'-'eMa */
    if nCnt = 0 | aDiv > 3 then
        newFo = 'l'max(0, aMa)
    else if eMi \== '' then do
        f1  = substr(format(nMa, 2, 2, 9, 0), 7)
        if f1 \= '' then
            eMa = max(eMa, f1)
        newFo = 'e' || (1+(eMi < 0)) || '.' || (max(0, nDi-1))'.' ,
            || max(length(eMa+0), length(eMi+0))
        end
    else if nAf > 0 then
        newFo ='f'nBe'.'nAf
    else
        newFo ='f'nBe'.0'
/*  say '   ' newFo  */
   return newFo
endProcedure fmtFDetect1

fmtFldRW: procedure expose m.
parse arg fo
    ty = oGetClassPara(m.j.in)
    call assert 'oFlds(ty) == m.fo.flds', 'fo different flds than class'
    call out fmtFldTitle(fo)
    do while in(ii)
        call out fmtFld(fo, ii)
        end
    return
endProcedure fmtClassRW

fmtFldSquashRW: procedure expose m.
parse arg in, opCl
    if in = '' then
        in = m.j.in
    if opCl == 'opCl' then
        call jOpen in, 'r'
    ty = oGetClassPara(in)
    flds = oFlds(ty)
    st = 'FMT.CLASSAD'
    do ix=1 while jRead(in, st'.'ix)
        end
    m.st.0 = ix - 1
    fo = fmtFldSquash(sqFo, ty, st)
    call out fmtFldTitle(fo)
    do ix = 1 to m.st.0
        call out fmtFld(fo, st'.'ix)
        end
    if opCl == 'opCl' then
        call jClose in
    return
endProcedure fmtFldSquashRW
/* copy fmtF  end  * **************************************************/