| 1 | /* Create documentation for functions */
 | 
|---|
| 2 |  call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
 | 
|---|
| 3 |  call SysLoadFuncs
 | 
|---|
| 4 | 
 | 
|---|
| 5 | docInfo.=''
 | 
|---|
| 6 | 
 | 
|---|
| 7 | theDir=ARG(1)
 | 
|---|
| 8 | 
 | 
|---|
| 9 | IF theDir="" THEN theDir=STRIP(DIRECTORY())
 | 
|---|
| 10 | 
 | 
|---|
| 11 | docdir="r:\temp"
 | 
|---|
| 12 | 
 | 
|---|
| 13 | SAY "Base directory: "theDir
 | 
|---|
| 14 | SAY
 | 
|---|
| 15 | 
 | 
|---|
| 16 | 
 | 
|---|
| 17 | SAY "Checking C files..."
 | 
|---|
| 18 | rc=SysFileTree(theDir"\*.c", "files.", "FSO")
 | 
|---|
| 19 | 
 | 
|---|
| 20 | numLines=0
 | 
|---|
| 21 | index=0 /* This index holds the number of found descriptions */
 | 
|---|
| 22 | DO a= 1 to files.0
 | 
|---|
| 23 |         drop contents
 | 
|---|
| 24 |         contents.=''
 | 
|---|
| 25 |         /* Count and read in lines of file */
 | 
|---|
| 26 |         DO WHILE LINES(files.a)
 | 
|---|
| 27 |                 numLines=numLines+1
 | 
|---|
| 28 |                 contents.numlines=LINEIN(files.a)
 | 
|---|
| 29 |         END
 | 
|---|
| 30 |         contents.0=numLines
 | 
|---|
| 31 |         call STREAM files.a, "C","close"
 | 
|---|
| 32 | 
 | 
|---|
| 33 |         /* Now parse each source file */
 | 
|---|
| 34 |         exposeList='files. theLine numLines index docinfo. contents.'
 | 
|---|
| 35 |         call parseFile a
 | 
|---|
| 36 | END
 | 
|---|
| 37 | 
 | 
|---|
| 38 | 
 | 
|---|
| 39 | IF files.0\=0 THEN DO
 | 
|---|
| 40 |         result._C=files.0
 | 
|---|
| 41 |         result._CLines=numLines
 | 
|---|
| 42 | END
 | 
|---|
| 43 | ELSE DO
 | 
|---|
| 44 |         result._C=0
 | 
|---|
| 45 |         result._CLines=0
 | 
|---|
| 46 | END
 | 
|---|
| 47 | 
 | 
|---|
| 48 | 
 | 
|---|
| 49 | 
 | 
|---|
| 50 | SAY ""
 | 
|---|
| 51 | SAY result._Clines||" lines in "||result._c||" C files"
 | 
|---|
| 52 | 
 | 
|---|
| 53 | /*
 | 
|---|
| 54 | DO a= 1 to index
 | 
|---|
| 55 |         SAY ''
 | 
|---|
| 56 |         SAY a||': '
 | 
|---|
| 57 |         SAY 'Function: 'docinfo.a.function
 | 
|---|
| 58 |         SAY 'Line: 'docinfo.a.line
 | 
|---|
| 59 |         SAY'Desc: 'docinfo.a.desc
 | 
|---|
| 60 |         SAY ''
 | 
|---|
| 61 |         SAY 'File: 'docinfo.a.file
 | 
|---|
| 62 | END
 | 
|---|
| 63 | */
 | 
|---|
| 64 | 
 | 
|---|
| 65 | /*create docs */
 | 
|---|
| 66 | ipf=docdir||'\doc.ipf'            /* The IPF file        */
 | 
|---|
| 67 | res=200                             /* The initial res id */
 | 
|---|
| 68 | leftWidth="30%"
 | 
|---|
| 69 | syntaxres=1                      /* Res id for syntax table. To be added to base. E.G. 201 */
 | 
|---|
| 70 | remarksres=2
 | 
|---|
| 71 | returnsres=3
 | 
|---|
| 72 | exampleres=4
 | 
|---|
| 73 | overrideres=5
 | 
|---|
| 74 | usageres=6
 | 
|---|
| 75 | paramsres=10
 | 
|---|
| 76 | 
 | 
|---|
| 77 | 'type NUL > 'ipf
 | 
|---|
| 78 | 
 | 
|---|
| 79 | /* Write IPF header */
 | 
|---|
| 80 | call writeIpfHeader ipf
 | 
|---|
| 81 | 
 | 
|---|
| 82 | /* Sort the function names in the array a. */
 | 
|---|
| 83 | a.=''
 | 
|---|
| 84 | DO b= 1 to index
 | 
|---|
| 85 |         a.b=STRIP(WORD(docinfo.b.function,2))
 | 
|---|
| 86 | END
 | 
|---|
| 87 | a.0=index
 | 
|---|
| 88 | call qqsort 1, index
 | 
|---|
| 89 | 
 | 
|---|
| 90 | /* Build a stem with the right order of indexes so in the document the functions are ordered */
 | 
|---|
| 91 | indStem.=''
 | 
|---|
| 92 | DO b=1 to index
 | 
|---|
| 93 |         DO c=1 to index
 | 
|---|
| 94 |                 if STRIP(WORD(docinfo.c.function,2))=a.b THEN DO
 | 
|---|
| 95 |                 indStem.b=c
 | 
|---|
| 96 |                 LEAVE
 | 
|---|
| 97 |                 END
 | 
|---|
| 98 |         END
 | 
|---|
| 99 | END
 | 
|---|
| 100 | 
 | 
|---|
| 101 | /* Write function reference */
 | 
|---|
| 102 | call writeIpfFunctionRef ipf
 | 
|---|
| 103 | 
 | 
|---|
| 104 | /* Footer */
 | 
|---|
| 105 | call writeIpfFooter ipf
 | 
|---|
| 106 | 
 | 
|---|
| 107 | call STREAM ipf, "C","close"
 | 
|---|
| 108 | 
 | 
|---|
| 109 | /* Compile the document */
 | 
|---|
| 110 | 'ipfc -i 'ipf
 | 
|---|
| 111 | 
 | 
|---|
| 112 | exit
 | 
|---|
| 113 | 
 | 
|---|
| 114 | /**************** Procedures *********************************/
 | 
|---|
| 115 | 
 | 
|---|
| 116 | writeIpfFunctionRef:
 | 
|---|
| 117 | 
 | 
|---|
| 118 |         res=res+100
 | 
|---|
| 119 |         call lineout ipf, ":h1 res="||res||".Function reference"
 | 
|---|
| 120 |         call lineout ipf, ""
 | 
|---|
| 121 | 
 | 
|---|
| 122 |         /* Write the function descriptions. The syntax pane is always written. The others only if
 | 
|---|
| 123 |             sufficient information is available. */
 | 
|---|
| 124 |         DO b=1 to index
 | 
|---|
| 125 |                 a=indStem.b
 | 
|---|
| 126 |                 res=res+100
 | 
|---|
| 127 |                 call writeIpfFunction                 /* Write header for this function desc panel */
 | 
|---|
| 128 |                 call writeIpfFuncLinks               /* Add links to left pane (Syntax, remarks...) */
 | 
|---|
| 129 |                 call writeIpfFuncSyntax             /* Write Syntax pane */
 | 
|---|
| 130 |                 call writeIpfFuncReturns            /* Write return pane (lower right) */
 | 
|---|
| 131 |                 call writeIpfFuncRemarks          /* Write remarks pane */
 | 
|---|
| 132 |                 call writeIpfFuncParams            /* Write a pane for every known parameter */
 | 
|---|
| 133 |                 call writeIpfFuncOverride           /* Write a panel for the override information */
 | 
|---|
| 134 |                 call writeIpfFuncUsage              /* Write a panel for the Usage information */
 | 
|---|
| 135 |         END
 | 
|---|
| 136 | return
 | 
|---|
| 137 | 
 | 
|---|
| 138 | /*********************/
 | 
|---|
| 139 | writeIpfFunction:
 | 
|---|
| 140 |                 /* Write the header of the function panel */
 | 
|---|
| 141 |                 call lineout ipf, ".*************** "||getFunctionName(docinfo.a.function)||"() *****************"
 | 
|---|
| 142 |                 call lineout ipf, ":h2 res="||res
 | 
|---|
| 143 |                 call lineout ipf, "width="leftWidth
 | 
|---|
| 144 |                 call lineout ipf, "."||getFunctionName2(docinfo.a.function, docinfo.a.isSom)          /* Function name */
 | 
|---|
| 145 |                 call lineout ipf, ":link reftype=hd res="res+syntaxres               /* Syntax will be opened initialy */
 | 
|---|
| 146 |                 call lineout ipf, "auto dependent group=2."
 | 
|---|
| 147 |                 call lineout ipf, ":p."
 | 
|---|
| 148 | return
 | 
|---|
| 149 | 
 | 
|---|
| 150 | /*********************************/
 | 
|---|
| 151 | /* Write the links in the left panel for   */
 | 
|---|
| 152 | /* this function.                                  */
 | 
|---|
| 153 | /*********************************/
 | 
|---|
| 154 | writeIpfFuncLinks:
 | 
|---|
| 155 |                 call lineout ipf, ":link reftype=hd res="||res+syntaxres||" dependent.Syntax:elink."
 | 
|---|
| 156 |                 call lineout ipf, ".br"
 | 
|---|
| 157 |                 if docinfo.a.numparams ><0 THEN DO
 | 
|---|
| 158 |                         call lineout ipf, ":link reftype=hd res="||res+paramsres||" dependent.Parameters:elink."
 | 
|---|
| 159 |                         call lineout ipf, ".br"
 | 
|---|
| 160 |                 END
 | 
|---|
| 161 |                 IF docinfo.a.returns >< "" THEN DO
 | 
|---|
| 162 |                         call lineout ipf, ":link reftype=hd res="||res+returnsres||" dependent.Returns:elink."
 | 
|---|
| 163 |                         call lineout ipf, ".br"
 | 
|---|
| 164 |                 END 
 | 
|---|
| 165 |                 IF docinfo.a.remarks >< "" THEN DO
 | 
|---|
| 166 |                         call lineout ipf, ":link reftype=hd res="||res+remarksres||" dependent.Remarks:elink."
 | 
|---|
| 167 |                         call lineout ipf, ".br"
 | 
|---|
| 168 |                 END
 | 
|---|
| 169 |                 IF docinfo.a.override><"" THEN DO
 | 
|---|
| 170 |                         call lineout ipf, ":link reftype=hd res="||res+overrideres||" dependent.How to override:elink."
 | 
|---|
| 171 |                         call lineout ipf, ".br"
 | 
|---|
| 172 |                 END
 | 
|---|
| 173 |                 IF docinfo.a.usage><"" THEN DO
 | 
|---|
| 174 |                         call lineout ipf, ":link reftype=hd res="||res+usageres||" dependent.Usage:elink."
 | 
|---|
| 175 |                         call lineout ipf, ".br"
 | 
|---|
| 176 |                 END
 | 
|---|
| 177 |                 IF docinfo.index.example >< "" THEN DO
 | 
|---|
| 178 |                         call lineout ipf, ":link reftype=hd res="||res+exampleres||" dependent.Example:elink."
 | 
|---|
| 179 |                         call lineout ipf, ".br"
 | 
|---|
| 180 |                 END
 | 
|---|
| 181 | return
 | 
|---|
| 182 | 
 | 
|---|
| 183 | /*********************************/
 | 
|---|
| 184 | /* Write the panel for the return value */
 | 
|---|
| 185 | /*********************************/
 | 
|---|
| 186 | writeIpfFuncReturns:
 | 
|---|
| 187 |         if docinfo.a.returns="" THEN return
 | 
|---|
| 188 | 
 | 
|---|
| 189 |         call lineout ipf, ":h2 res="||res+returnsres
 | 
|---|
| 190 |         call lineout ipf, "x=30%"
 | 
|---|
| 191 |         call lineout ipf, "width=70% height=35%"
 | 
|---|
| 192 |         call lineout ipf, "group=3"
 | 
|---|
| 193 |         call lineout ipf, "hide"
 | 
|---|
| 194 |         call lineout ipf, "."||getFunctionName2(docinfo.a.function, docinfo.a.isSom)||" Return value - "||WORD(docinfo.a.returns, 2)
 | 
|---|
| 195 |         call lineout ipf, ":p."
 | 
|---|
| 196 |         call lineout ipf, ":hp2."||WORD(docinfo.a.returns, 2)||":ehp2. ("||WORD(docinfo.a.returns, 1)||") - returns"
 | 
|---|
| 197 |         call lineout ipf, ":p."
 | 
|---|
| 198 |         call lineout ipf, wrapString(SUBWORD(docinfo.a.returns, 3))
 | 
|---|
| 199 | return
 | 
|---|
| 200 | 
 | 
|---|
| 201 | /*****************/
 | 
|---|
| 202 | writeIpfFuncOverride:
 | 
|---|
| 203 |         if docinfo.a.override="" THEN return
 | 
|---|
| 204 | 
 | 
|---|
| 205 |         call lineout ipf, ":h2 res="||res+overrideres
 | 
|---|
| 206 |         call lineout ipf, "x=30%"
 | 
|---|
| 207 |         call lineout ipf, "width=70%"
 | 
|---|
| 208 |         call lineout ipf, "group=2"
 | 
|---|
| 209 |         call lineout ipf, "hide"
 | 
|---|
| 210 |         call lineout ipf, "."||getFunctionName2(docinfo.a.function, docinfo.a.isSom)||" - How to override"
 | 
|---|
| 211 |         call lineout ipf, ":p."
 | 
|---|
| 212 |         call lineout ipf, wrapString(docinfo.a.override)
 | 
|---|
| 213 | 
 | 
|---|
| 214 | return
 | 
|---|
| 215 | 
 | 
|---|
| 216 | /*****************/
 | 
|---|
| 217 | writeIpfFuncUsage:
 | 
|---|
| 218 |         if docinfo.a.usage="" THEN return
 | 
|---|
| 219 | 
 | 
|---|
| 220 |         call lineout ipf, ":h2 res="||res+usageres
 | 
|---|
| 221 |         call lineout ipf, "x=30%"
 | 
|---|
| 222 |         call lineout ipf, "width=70%"
 | 
|---|
| 223 |         call lineout ipf, "group=2"
 | 
|---|
| 224 |         call lineout ipf, "hide"
 | 
|---|
| 225 |         call lineout ipf, "."||getFunctionName2(docinfo.a.function, docinfo.a.isSom)||" - Usage"
 | 
|---|
| 226 |         call lineout ipf, ":p."
 | 
|---|
| 227 |         call lineout ipf, wrapString(docinfo.a.usage)
 | 
|---|
| 228 | 
 | 
|---|
| 229 | return
 | 
|---|
| 230 | 
 | 
|---|
| 231 | /*****************/
 | 
|---|
| 232 | writeIpfFuncParams:
 | 
|---|
| 233 |         if docinfo.a.numparams=0 THEN return   /* No params given */
 | 
|---|
| 234 | 
 | 
|---|
| 235 |         /* Write big parameter panel */
 | 
|---|
| 236 |         call lineout ipf, ":h2 res="||res+paramsres
 | 
|---|
| 237 |         call lineout ipf, "x=30%"
 | 
|---|
| 238 |         call lineout ipf, "width=70%"
 | 
|---|
| 239 |         call lineout ipf, "group=2"
 | 
|---|
| 240 |         call lineout ipf, "hide"
 | 
|---|
| 241 |         call lineout ipf, "."||getFunctionName2(docinfo.a.function, docinfo.a.isSom)||" - Parameters"
 | 
|---|
| 242 |         call lineout ipf, ":p."
 | 
|---|
| 243 |         DO parms = 1 to docinfo.a.numparams
 | 
|---|
| 244 |                 pindex='param'||parms
 | 
|---|
| 245 |                 call lineout ipf, ":hp2."||WORD(docinfo.a.pindex, 2)||":ehp2. ("||WORD(docinfo.a.pindex, 1)||") - "||WORD(docinfo.a.pindex, 3)
 | 
|---|
| 246 |                 call lineout ipf, ":p."
 | 
|---|
| 247 |                 call lineout ipf, ":lm margin=5."
 | 
|---|
| 248 |                 call lineout ipf, wrapString(SUBWORD(docinfo.a.pindex, 4))
 | 
|---|
| 249 |                 call lineout ipf, ":lm margin=1."
 | 
|---|
| 250 |                 call lineout ipf, ":p."
 | 
|---|
| 251 |         END
 | 
|---|
| 252 |         call lineout ipf, ""          /* Space to make source readable */
 | 
|---|
| 253 | 
 | 
|---|
| 254 |         /* Write small panel (lower right) for every parameter */
 | 
|---|
| 255 |         DO parms = 1 to docinfo.a.numparams
 | 
|---|
| 256 |                 pindex='param'||parms
 | 
|---|
| 257 |                 call lineout ipf, ":h2 res="||res+paramsres+parms
 | 
|---|
| 258 |                 call lineout ipf, "x=30%"
 | 
|---|
| 259 |                 call lineout ipf, "width=70% height=35%"
 | 
|---|
| 260 |                 call lineout ipf, "group=3"
 | 
|---|
| 261 |                 call lineout ipf, "hide"
 | 
|---|
| 262 |                 call lineout ipf, "."||getFunctionName2(docinfo.a.function, docinfo.a.isSom)||" Parameter - "||WORD(docinfo.a.pindex, 2)
 | 
|---|
| 263 |                 call lineout ipf, ":p."
 | 
|---|
| 264 |                 call lineout ipf, ":hp2."||WORD(docinfo.a.pindex, 2)||":ehp2. ("||WORD(docinfo.a.pindex, 1)||") - "||WORD(docinfo.a.pindex, 3)
 | 
|---|
| 265 |                 call lineout ipf, ":p."
 | 
|---|
| 266 |                 call lineout ipf, wrapString(SUBWORD(docinfo.a.pindex, 4))
 | 
|---|
| 267 |         END
 | 
|---|
| 268 | return
 | 
|---|
| 269 | 
 | 
|---|
| 270 | /*****************************/
 | 
|---|
| 271 | /* Write the Remarks panel          */
 | 
|---|
| 272 | /*****************************/
 | 
|---|
| 273 | writeIpfFuncRemarks:
 | 
|---|
| 274 |         if docinfo.a.remarks="" THEN return
 | 
|---|
| 275 | 
 | 
|---|
| 276 |         call lineout ipf, ":h2 res="||res+remarksres
 | 
|---|
| 277 |         call lineout ipf, "x=30%"
 | 
|---|
| 278 |         call lineout ipf, "width=70%"
 | 
|---|
| 279 |         call lineout ipf, "group=2"
 | 
|---|
| 280 |         call lineout ipf, "hide"
 | 
|---|
| 281 |         call lineout ipf, "."||getFunctionName2(docinfo.a.function, docinfo.a.isSom)||" - Remarks"
 | 
|---|
| 282 |         call lineout ipf, ":p."
 | 
|---|
| 283 |         call lineout ipf, wrapString(docinfo.a.remarks)
 | 
|---|
| 284 | 
 | 
|---|
| 285 | return
 | 
|---|
| 286 | 
 | 
|---|
| 287 | /*****************/
 | 
|---|
| 288 | writeIpfFuncSyntax:
 | 
|---|
| 289 |                 call lineout ipf, ""
 | 
|---|
| 290 |                 call lineout ipf, ":h2 res="||res+syntaxres
 | 
|---|
| 291 |                 call lineout ipf, "x=30%"
 | 
|---|
| 292 |                 call lineout ipf, "width=70%"
 | 
|---|
| 293 |                 call lineout ipf, "group=2"
 | 
|---|
| 294 |                 call lineout ipf, "hide"
 | 
|---|
| 295 |                 call lineout ipf, "."||getFunctionName2(docinfo.a.function, docinfo.a.isSom)||" - Syntax"
 | 
|---|
| 296 |                 call lineout ipf, ":p."
 | 
|---|
| 297 |                 call lineout ipf, wrapString(docinfo.a.desc)
 | 
|---|
| 298 |                 call lineout ipf, ":nt."
 | 
|---|
| 299 |                 call lineout ipf, "This function can be found in the source file :hp2."||FILESPEC("name", docinfo.a.file) ||":ehp2.."
 | 
|---|
| 300 |                 call lineout ipf, ":ent."
 | 
|---|
| 301 |                 call lineout ipf, ":xmp."
 | 
|---|
| 302 |                 call lineout ipf, ""
 | 
|---|
| 303 |                 call lineout ipf, ":parml compact tsize=25 break=none."
 | 
|---|
| 304 |         /* Check if parameters are given. If yes print them and provide a link in the syntax panel */
 | 
|---|
| 305 |                 allParams=''
 | 
|---|
| 306 |                 IF docinfo.a.numparams >< 0 THEN DO
 | 
|---|
| 307 |                 DO parms = 1 to docinfo.a.numparams
 | 
|---|
| 308 |                         pindex='param'||parms
 | 
|---|
| 309 |                         allParams=allParams||":pt."||WORD(docinfo.a.pindex, 1)||":pd.:link reftype=hd res="||res+paramsres+parms||" dependent."WORD(docinfo.a.pindex, 2 )":elink.;"
 | 
|---|
| 310 |                 END
 | 
|---|
| 311 |                 END
 | 
|---|
| 312 |         /* Check if return info is given. If yes provide a link on syntax panel */
 | 
|---|
| 313 |                 IF docinfo.a.returns >< "" THEN DO
 | 
|---|
| 314 |                         allParams=allParams||":pt."||WORD(docinfo.a.returns, 1)||":pd.:link reftype=hd res="||res+returnsres||" dependent."WORD(docinfo.a.returns, 2 )":elink.;"
 | 
|---|
| 315 |                         theString=WORD(docinfo.a.returns,2)||" = "||removeTypesFromFunc(SUBWORD(docinfo.a.function,2))||';'
 | 
|---|
| 316 |                 END /* docinfo.a.returns */
 | 
|---|
| 317 |                 ELSE
 | 
|---|
| 318 |                         theString=removeTypesFromFunc(SUBWORD(docinfo.a.function,2))||';'
 | 
|---|
| 319 |                 call lineout ipf, allParams
 | 
|---|
| 320 |                 call lineout ipf, ":eparml."
 | 
|---|
| 321 |                 thePos=1
 | 
|---|
| 322 |                 tabPos=1
 | 
|---|
| 323 |         /* Split function in lines */
 | 
|---|
| 324 |                 DO WHILE thePos >< 0
 | 
|---|
| 325 |                         theString=STRIP(SUBSTR(theString, thePos))
 | 
|---|
| 326 |                         thePos=POS(',' , theString)
 | 
|---|
| 327 |                         if thePos >< 0 THEN DO
 | 
|---|
| 328 |                                 if tabPos=1 then DO
 | 
|---|
| 329 |                                         call lineout ipf, LEFT(theString, thePos)
 | 
|---|
| 330 |                                         tabPos=POS('(' , theString)
 | 
|---|
| 331 |                                 END
 | 
|---|
| 332 |                                 ELSE
 | 
|---|
| 333 |                                         call lineout ipf, COPIES(' ',tabPos)||LEFT(theString, thePos)
 | 
|---|
| 334 |                                 thePos=thePos+1
 | 
|---|
| 335 |                         END
 | 
|---|
| 336 |                         ELSE
 | 
|---|
| 337 |                                 call lineout ipf, COPIES(' ',tabPos)||theString
 | 
|---|
| 338 |                 END
 | 
|---|
| 339 |                 call lineout ipf, ":exmp."
 | 
|---|
| 340 |                 call lineout ipf, ""
 | 
|---|
| 341 | return
 | 
|---|
| 342 | 
 | 
|---|
| 343 | /***************************/
 | 
|---|
| 344 | removeTypesFromFunc: procedure
 | 
|---|
| 345 |         theString=SPACE(ARG(1))
 | 
|---|
| 346 | 
 | 
|---|
| 347 |         /* Make sure there's always a space after '(' and ',' */
 | 
|---|
| 348 |         thePos=POS('(', theString)
 | 
|---|
| 349 |         theString=INSERT(' ', theString, thePos)
 | 
|---|
| 350 |         thePos2=POS(' ' , theString, thePos+3)
 | 
|---|
| 351 |         /* Remove '*' in front of somSelf if any */
 | 
|---|
| 352 |         tmpString=STRIP(subStr(theString, thePos2))     
 | 
|---|
| 353 |         IF LEFT(tmpString, 1)='*' THEN
 | 
|---|
| 354 |                 tmpString=RIGHT(tmpString, LENGTH(tmpString)-1)
 | 
|---|
| 355 |         theString=LEFT(theString, thePos)||STRIP(tmpString)
 | 
|---|
| 356 |         thePos=POS(',' , theString)
 | 
|---|
| 357 |         DO while thePos >< 0
 | 
|---|
| 358 |                 theString=INSERT(' ', theString, thePos)
 | 
|---|
| 359 |                 thePos2=POS(' ' , theString, thePos+3)
 | 
|---|
| 360 |                 theString=LEFT(theString, thePos)||STRIP(subStr(theString, thePos2))
 | 
|---|
| 361 |                 thePos=POS(',', theString, thePos+1)
 | 
|---|
| 362 |         END
 | 
|---|
| 363 | 
 | 
|---|
| 364 | return theString
 | 
|---|
| 365 | 
 | 
|---|
| 366 | /***************************/
 | 
|---|
| 367 | writeIpfHeader: procedure expose res
 | 
|---|
| 368 | ipf=ARG(1)
 | 
|---|
| 369 |         call lineout ipf, ":userdoc."
 | 
|---|
| 370 |         call lineout ipf, ""
 | 
|---|
| 371 |         call lineout ipf, ":docprof."
 | 
|---|
| 372 |         call lineout ipf, ""
 | 
|---|
| 373 |         call lineout ipf, ":title.Function reference"
 | 
|---|
| 374 |         call lineout ipf, ""
 | 
|---|
| 375 |         call lineout ipf, ":h1 res=100.Introduction"
 | 
|---|
| 376 |         call lineout ipf, ":p."
 | 
|---|
| 377 |         call lineout ipf, "To be written..."
 | 
|---|
| 378 | return
 | 
|---|
| 379 | 
 | 
|---|
| 380 | writeIpfFooter:
 | 
|---|
| 381 |         /* Footer */
 | 
|---|
| 382 |         call lineout ARG(1), ":euserdoc."
 | 
|---|
| 383 | return
 | 
|---|
| 384 | 
 | 
|---|
| 385 | /**************************/
 | 
|---|
| 386 | 
 | 
|---|
| 387 | /*******************************/
 | 
|---|
| 388 | /* Strip the parameter list from the   */
 | 
|---|
| 389 | /* function and return only the name */
 | 
|---|
| 390 | /*                                                 */
 | 
|---|
| 391 | /* During file parsing the whole        */
 | 
|---|
| 392 | /* function declaration was read in   */
 | 
|---|
| 393 | /*******************************/
 | 
|---|
| 394 | getFunctionName: procedure
 | 
|---|
| 395 |         func=ARG(1)
 | 
|---|
| 396 |         thePos=POS('(', func)
 | 
|---|
| 397 |         func=LEFT(func,thePos-1)
 | 
|---|
| 398 |         
 | 
|---|
| 399 | return WORD(func,WORDS(func))
 | 
|---|
| 400 | 
 | 
|---|
| 401 | /*******************************/
 | 
|---|
| 402 | /* Strip the parameter list from the   */
 | 
|---|
| 403 | /* function and return only the name */
 | 
|---|
| 404 | /*                                                 */
 | 
|---|
| 405 | /* During file parsing the whole        */
 | 
|---|
| 406 | /* function declaration was read in   */
 | 
|---|
| 407 | /*******************************/
 | 
|---|
| 408 | getFunctionName2: procedure
 | 
|---|
| 409 |         func=ARG(1)
 | 
|---|
| 410 |         thePos=POS('(', func)
 | 
|---|
| 411 |         func=LEFT(func,thePos-1)
 | 
|---|
| 412 |         func=WORD(func,WORDS(func))
 | 
|---|
| 413 |         IF ARG(2)="YES" THEN    
 | 
|---|
| 414 |                 return RIGHT(func, LENGTH(func)-1)
 | 
|---|
| 415 |         ELSE
 | 
|---|
| 416 |                 return func
 | 
|---|
| 417 | 
 | 
|---|
| 418 | /***************************************************************/
 | 
|---|
| 419 | 
 | 
|---|
| 420 | /*******************************/
 | 
|---|
| 421 | /* Parse the contents of the source  */
 | 
|---|
| 422 | /* file. This means finding comments  */
 | 
|---|
| 423 | /* containing function descriptions.    */
 | 
|---|
| 424 | /*******************************/
 | 
|---|
| 425 | parseFile: procedure expose (exposelist)
 | 
|---|
| 426 | 
 | 
|---|
| 427 | a=ARG(1)
 | 
|---|
| 428 |         curline=0
 | 
|---|
| 429 |         DO while curline <= contents.0
 | 
|---|
| 430 |                 curline=curline+1
 | 
|---|
| 431 |                 tempLine=STRIP(contents.curline)
 | 
|---|
| 432 |                 if LENGTH(templine)<5 then iterate
 | 
|---|
| 433 | 
 | 
|---|
| 434 |                 if LEFT(tempLine, 4)="/*!*" then do
 | 
|---|
| 435 |                         /* Comment with function description found. Now parse it. */
 | 
|---|
| 436 |                         call parseComment a
 | 
|---|
| 437 |                 END
 | 
|---|
| 438 |         END
 | 
|---|
| 439 | return
 | 
|---|
| 440 | 
 | 
|---|
| 441 | /*******************************/
 | 
|---|
| 442 | /* Parse the whole comment block   */
 | 
|---|
| 443 | /* with information                         */
 | 
|---|
| 444 | /*******************************/
 | 
|---|
| 445 | parseComment: 
 | 
|---|
| 446 |         index=index+1
 | 
|---|
| 447 |         docinfo.index.file=STRIP(files.a)
 | 
|---|
| 448 |         docinfo.index.remarks=""
 | 
|---|
| 449 |         docinfo.index.returns=""
 | 
|---|
| 450 |         docinfo.index.example=""
 | 
|---|
| 451 |         docinfo.index.numparams=0
 | 
|---|
| 452 |         docinfo.index.override=""
 | 
|---|
| 453 |         docinfo.index.usage=""
 | 
|---|
| 454 |         DO WHILE curline<=contents.0
 | 
|---|
| 455 |                 curline=curline+1
 | 
|---|
| 456 |                 theLine=STRIP(contents.curline)
 | 
|---|
| 457 |                 IF POS("@@",theLine) ><0 THEN call parseEntry   /* Found a parameter */
 | 
|---|
| 458 | 
 | 
|---|
| 459 |                 IF LEFT(STRIP(theLine), 5)="/*!!*" THEN DO
 | 
|---|
| 460 |                         /* End of comment. Get function name. */
 | 
|---|
| 461 |                         docinfo.index.line=curline+1                    /* Line of function */
 | 
|---|
| 462 |                         docinfo.index.function=getCompleteFunction()
 | 
|---|
| 463 |                         return
 | 
|---|
| 464 |                 END
 | 
|---|
| 465 |         END
 | 
|---|
| 466 | return
 | 
|---|
| 467 | 
 | 
|---|
| 468 | /********************************/
 | 
|---|
| 469 | /* Read lines until a '{' is found.          */
 | 
|---|
| 470 | /* This means reading in a function    */
 | 
|---|
| 471 | /* declaration.                                 */
 | 
|---|
| 472 | /*                                                   */
 | 
|---|
| 473 | /*                                                   */
 | 
|---|
| 474 | /*                                                   */
 | 
|---|
| 475 | /********************************/
 | 
|---|
| 476 | 
 | 
|---|
| 477 | getCompleteFunction:
 | 
|---|
| 478 |         theLine= ""             
 | 
|---|
| 479 |         DO WHILE curline<=contents.0
 | 
|---|
| 480 |                 curLine=curLine+1
 | 
|---|
| 481 |                 theLine=theLine||STRIP(contents.curline)
 | 
|---|
| 482 |                 IF POS("{",theLine) ><0 THEN LEAVE
 | 
|---|
| 483 |         END
 | 
|---|
| 484 |         theLine=STRIP(TRANSLATE(theLine,' ','{'))
 | 
|---|
| 485 |         /* Ok, at this point we have the whole function declaration including the parameters */
 | 
|---|
| 486 |         /* Check if we have a SOM function */
 | 
|---|
| 487 |         IF POS("SOMLINK", theLine) >< 0 THEN DO
 | 
|---|
| 488 |                 /* Mark as a SOM function */
 | 
|---|
| 489 |                 docinfo.index.isSom="YES"
 | 
|---|
| 490 |                 /* Strip SOMLINK and SOM_Scope and the prefix */
 | 
|---|
| 491 |                 thePos=POS('_', SUBWORD(theLine, 4))
 | 
|---|
| 492 |                 theLine=WORD(theLine, 2)||" "||substr(SUBWORD(theLine,4), thePos)
 | 
|---|
| 493 |                 
 | 
|---|
| 494 |         END
 | 
|---|
| 495 | return theLine
 | 
|---|
| 496 | 
 | 
|---|
| 497 | /*******************************/
 | 
|---|
| 498 | /* Parse entries starting with @@ in  */
 | 
|---|
| 499 | /* comment block.                          */
 | 
|---|
| 500 | /*******************************/
 | 
|---|
| 501 | parseEntry:
 | 
|---|
| 502 |         entry=stripCommentChars(theLine)
 | 
|---|
| 503 |         SELECT
 | 
|---|
| 504 |         WHEN entry="@@DESC" THEN DO
 | 
|---|
| 505 |                 /* Description */
 | 
|---|
| 506 |                 docinfo.index.desc=readEntryContents()
 | 
|---|
| 507 |         END
 | 
|---|
| 508 |         WHEN entry="@@REMARKS" THEN DO
 | 
|---|
| 509 |                 /* Remarks */
 | 
|---|
| 510 |                 docinfo.index.remarks=readEntryContents()
 | 
|---|
| 511 |         END
 | 
|---|
| 512 |         WHEN entry="@@RETURNS" THEN DO
 | 
|---|
| 513 |                 /* Return value */
 | 
|---|
| 514 |                 docinfo.index.returns=readEntryContents()
 | 
|---|
| 515 |         END
 | 
|---|
| 516 |         WHEN entry="@@EXAMPLE" THEN DO
 | 
|---|
| 517 |                 /* Example */
 | 
|---|
| 518 |                 docinfo.index.example=readEntryContents()
 | 
|---|
| 519 |         END
 | 
|---|
| 520 |         WHEN entry="@@OVERRIDE" THEN DO
 | 
|---|
| 521 |                 /* Override of a SOM method */
 | 
|---|
| 522 |                 docinfo.index.override=readEntryContents()
 | 
|---|
| 523 |         END
 | 
|---|
| 524 |         WHEN entry="@@USAGE" THEN DO
 | 
|---|
| 525 |                 /* Usage of a SOM method */
 | 
|---|
| 526 |                 docinfo.index.usage=readEntryContents()
 | 
|---|
| 527 |         END
 | 
|---|
| 528 |         WHEN LEFT(entry, 7)="@@PARAM" THEN DO
 | 
|---|
| 529 |                 docinfo.index.numparams=docinfo.index.numparams+1
 | 
|---|
| 530 |                 parm='param'||docinfo.index.numparams
 | 
|---|
| 531 |                 docinfo.index.parm=readEntryContents()
 | 
|---|
| 532 |         END
 | 
|---|
| 533 |         OTHERWISE
 | 
|---|
| 534 |                 NOP
 | 
|---|
| 535 |         END
 | 
|---|
| 536 | return ""
 | 
|---|
| 537 | 
 | 
|---|
| 538 | /************************************/
 | 
|---|
| 539 | /* Read the text associated with a known */
 | 
|---|
| 540 | /* entry.                                               */
 | 
|---|
| 541 | /* Reading takes place until another entry */
 | 
|---|
| 542 | /* is found or the comment ends.              */
 | 
|---|
| 543 | /************************************/
 | 
|---|
| 544 | readEntryContents:
 | 
|---|
| 545 |         theEntry=""
 | 
|---|
| 546 |         DO WHILE curline<=contents.0
 | 
|---|
| 547 |                 curLine=curLine+1
 | 
|---|
| 548 |                 theLine=STRIP(contents.curline)
 | 
|---|
| 549 |                 IF POS("@@",theLine) ><0 THEN DO
 | 
|---|
| 550 |                         curline=curline-1
 | 
|---|
| 551 |                         return theEntry
 | 
|---|
| 552 |                 END
 | 
|---|
| 553 |                 IF LEFT(STRIP(theLine), 5)="/*!!*" THEN return theEntry
 | 
|---|
| 554 |                                         /* SAY '!!'||stripCommentChars(theLine)||'!!' */
 | 
|---|
| 555 | 
 | 
|---|
| 556 |                 if TRANSLATE(stripCommentChars(theLine))=":P." THEN DO
 | 
|---|
| 557 |                         theEntry=theEntry||stripCommentChars(theLine)
 | 
|---|
| 558 |                 END
 | 
|---|
| 559 |                 ELSE DO
 | 
|---|
| 560 |                         IF LENGTH(theEntry)>3 THEN DO
 | 
|---|
| 561 |                                 IF TRANSLATE(RIGHT(theEntry,3))=":P." THEN
 | 
|---|
| 562 |                                         theEntry=theEntry||stripCommentChars(theLine)
 | 
|---|
| 563 |                                 ELSE
 | 
|---|
| 564 |                                         theEntry=theEntry||' '||stripCommentChars(theLine)
 | 
|---|
| 565 |                         END
 | 
|---|
| 566 |                         ELSE DO
 | 
|---|
| 567 |                                 theEntry=theEntry||' '||stripCommentChars(theLine)
 | 
|---|
| 568 |                         END
 | 
|---|
| 569 | 
 | 
|---|
| 570 |                 END
 | 
|---|
| 571 |                 theEntry=STRIP(theEntry)
 | 
|---|
| 572 | /*SAY '%%'||theEntry||'%%'*/
 | 
|---|
| 573 |         END
 | 
|---|
| 574 | return theEntry
 | 
|---|
| 575 | 
 | 
|---|
| 576 | /********************************/
 | 
|---|
| 577 | /* Remove starting and ending           */
 | 
|---|
| 578 | /* comment chars from arg.               */
 | 
|---|
| 579 | /********************************/
 | 
|---|
| 580 | stripCommentChars:
 | 
|---|
| 581 |         theString=STRIP(SUBSTR(ARG(1),3))
 | 
|---|
| 582 | return STRIP(LEFT(theString, LENGTH(theString)-2))
 | 
|---|
| 583 | 
 | 
|---|
| 584 | 
 | 
|---|
| 585 | /********************************/
 | 
|---|
| 586 | /* Wrap a string over several lines by  */
 | 
|---|
| 587 | /* inserting '0d'x'0a'x.                        */
 | 
|---|
| 588 | /********************************/
 | 
|---|
| 589 | wrapString:
 | 
|---|
| 590 | 
 | 
|---|
| 591 | inString=ARG(1)
 | 
|---|
| 592 | numLines=TRUNC(LENGTH(inString)/80)
 | 
|---|
| 593 | DO widx = 1 to numlines
 | 
|---|
| 594 |         thePos=POS(' ',inString ,widx*80)
 | 
|---|
| 595 |         if thePos=0 THEN return inString
 | 
|---|
| 596 |         inString=INSERT('0d'x'0a'x, inString, thePos)
 | 
|---|
| 597 | END
 | 
|---|
| 598 | return inString 
 | 
|---|
| 599 | 
 | 
|---|
| 600 |  
 | 
|---|
| 601 |     
 | 
|---|
| 602 | 
 | 
|---|
| 603 | 
 | 
|---|
| 604 | 
 | 
|---|
| 605 |   
 | 
|---|
| 606 |  /* ------------------------------------------------------------------ */
 | 
|---|
| 607 | /*  Author: Ruediger Wilke */
 | 
|---|
| 608 |  /* function: quick sort routine                                       */
 | 
|---|
| 609 |  /*                                                                    */
 | 
|---|
| 610 |  /* call:     QuickSort first_element, last_element                    */
 | 
|---|
| 611 |  /*                                                                    */
 | 
|---|
| 612 |  /* returns:  nothing                                                  */
 | 
|---|
| 613 |  /*                                                                    */
 | 
|---|
| 614 |  /* notes:    You must save the elements to sort in the stem "a."      */
 | 
|---|
| 615 |  /*           a.0 must contain the number of elements in the stem.     */
 | 
|---|
| 616 |  /*                                                                    */
 | 
|---|
| 617 |  /*                                                                    */
 | 
|---|
| 618 |  qqsort: procedure expose a.
 | 
|---|
| 619 |  
 | 
|---|
| 620 |    arg lf, re
 | 
|---|
| 621 |  
 | 
|---|
| 622 |    if re -lf < 9 then
 | 
|---|
| 623 |      do lf = lf to re -1
 | 
|---|
| 624 |  
 | 
|---|
| 625 |        m = lf
 | 
|---|
| 626 |  
 | 
|---|
| 627 |        do j = lf +1 to re
 | 
|---|
| 628 |          if a.j << a.m then                                   /* v2.80 */
 | 
|---|
| 629 |            m = j
 | 
|---|
| 630 |        end /* j = lf +1 to re */
 | 
|---|
| 631 |  
 | 
|---|
| 632 |        t = a.m; a.m = a.lf; a.lf = t
 | 
|---|
| 633 |  
 | 
|---|
| 634 |      end /* lf = lf to re -1 */
 | 
|---|
| 635 |      else
 | 
|---|
| 636 |      do
 | 
|---|
| 637 |        i = lf
 | 
|---|
| 638 |        j = re
 | 
|---|
| 639 |        k = (lf + re)%2
 | 
|---|
| 640 |        t = a.k
 | 
|---|
| 641 |  
 | 
|---|
| 642 |        do until i > j
 | 
|---|
| 643 |  
 | 
|---|
| 644 |          do while a.i << t                                    /* v2.80 */
 | 
|---|
| 645 |            i = i + 1
 | 
|---|
| 646 |          end /* while a.i << t */
 | 
|---|
| 647 |  
 | 
|---|
| 648 |          do while a.j >> t                                    /* v2.80 */
 | 
|---|
| 649 |            j = j - 1
 | 
|---|
| 650 |          end /* while a.j >> t */
 | 
|---|
| 651 |  
 | 
|---|
| 652 |          if i <= j then
 | 
|---|
| 653 |          do
 | 
|---|
| 654 |            xchg = a.i
 | 
|---|
| 655 |            a.i = a.j
 | 
|---|
| 656 |            a.j = xchg
 | 
|---|
| 657 |            i = i + 1
 | 
|---|
| 658 |            j = j - 1
 | 
|---|
| 659 |          end /* if i <= j then */
 | 
|---|
| 660 |  
 | 
|---|
| 661 |        end /* until i > j */
 | 
|---|
| 662 |  
 | 
|---|
| 663 |        call qqsort lf, j
 | 
|---|
| 664 |        call qqsort i, re
 | 
|---|
| 665 |      end /* else */
 | 
|---|
| 666 |  
 | 
|---|
| 667 |  return
 | 
|---|
| 668 |  
 | 
|---|
| 669 |  
 | 
|---|
| 670 |    
 | 
|---|
| 671 | 
 | 
|---|
| 672 | 
 | 
|---|