home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / fortran / library / library / libry3.doc < prev    next >
Text File  |  1989-11-10  |  17KB  |  398 lines

  1. .pa
  2.                         STRING AND BUFFER MANIPULATION
  3.  
  4. The purpose of these procedures is that FORTRAN is rather ill suited to string
  5. and  buffer  manipulation.   Most of the operations can be done in FORTRAN but
  6. are extremely slow in comparison.  Also there is the annoying practice of some
  7. compilers  (e.g.  HP's FTN7X) to use fixed length character variables.  All of
  8. these routines were written in assembler.
  9.  
  10.  
  11.               QUICK LIST OF STRING AND BUFFER MANIPULATION
  12.  
  13. CSET..... set all the characters in a string
  14. DEC0DE... decode an array of reals contained in a character string
  15. FOLD..... case fold a character (a-z folds to A-Z)
  16. FOLDS.... case fold a character string (a-z folds to A-Z)
  17. IAND..... logical and
  18. IOR...... logical or
  19. IXOR..... logical exclusive or
  20. ILB...... left byte
  21. IRB...... right byte
  22. ISERCH... search for a character in a string
  23. MATCH.... check two character strings for a match
  24. MOVEC.... move one character string into another
  25. MOVEI.... move one integer array into another
  26. NBUFC1... determine the nominal length of a character string
  27. SWAPC.... swap two character strings
  28. SWAPI.... swap two integer arrays
  29. SORTC.... sort a group of character strings
  30. SORTCI... sort a group of indexed character strings
  31. SORTD.... sort an array of double precision reals
  32. SORTDI... sort an array of indexed double precision reals
  33. SORTI.... sort an array of integers
  34. SORTII... sort an array of indexed integers
  35. SORTR.... sort an array of reals
  36. SORTRI... sort an array of indexed reals
  37. .pa
  38. NAME:     CSET
  39. PURPOSE:  set all the characters in a string equal to a specific
  40.           character (such as blanks)
  41. TYPE:     subroutine (far external)
  42. SYNTAX:   CALL CSET(CBUF,NBUF,' ')
  43. INPUT:    a CHARACTER*1 variable (here ' ')
  44.           NBUF (INTEGER*2) number of characters in the target string
  45. OUTPUT:   CBUF (CHARACTER*1 CBUF(NBUF) or CHARACTER*80 CBUF, NBUF=80)
  46.  
  47.  
  48. NAME:     DEC0DE (note the "0" (zero), do not use an "O" (oh))
  49. PURPOSE:  decode an array of reals contained in a character string
  50. TYPE:     subroutine (far external)
  51. SYNTAX:   CALL DEC0DE(CBUF,NBUF,NCOL,R,N,IER)
  52. INPUT:    CBUF (any character string like '123 34.E4 5*0 100')
  53.           NBUF (INTEGER*2) the number of characters in CBUF
  54.           N (INTEGER*2) number of elements in R
  55. NOTE:     if you set N to a negative number, then DEC0DE will return in its
  56.           place the +number of reals actually decoded (of course, don't
  57.           use a constant like "-3" for this!)
  58. OUTPUT:   NCOL (INTEGER*2) the column where decoding stopped
  59.           R (REAL*4) an array (may be only 1 element)
  60.           IER (INTEGER*2) error return indicator (IER=0 is normal)
  61. USE:      In case you haven't noticed, some misguided persons at DEC and
  62.           Microsoft forgot to include the capability of free-format
  63.           reads from a character string (some people call character
  64.           strings "internal files" - why, is a mystery to me). Of
  65.           course, this is the most OBVIOUS reason for reading something
  66.           from a character string... perhaps that's why they left it
  67.           out. Well, DEC0DE is just the fix.
  68.  
  69.           DEC0DE will return an error if the syntax is incorrect or if
  70.           the string is empty. You must have at least one number in the
  71.           string. Missing numbers at the trailing end of a string will
  72.           be set to zero (viz. if you try to read 6 numbers and there
  73.           are only 3, the last 3 will come back as zero).
  74.  
  75.           Some examples of free format reals are given below. Note that
  76.           you can use the "*" to repeat numbers. Commas are optional.
  77.  
  78.                100 1.234 .0000123,45E4, 3*53.123 5*-7 -12.345E-05
  79.  
  80.           DEC0DE is written in assembler and is actually faster than
  81.           Microsoft's or HP's equivalent.  HP's FORTRAN will actually
  82.           perform this operation.
  83.  
  84.           When I want to read integers from a character string I first
  85.           read reals, then apply the "NINT" function as below
  86.  
  87.                CALL DEC0DE(CBUF,6,NCOL,R,1,IER)
  88.                IF(IER.NE.0) GO TO 999
  89.                I=NINT(R)
  90.  
  91.           The NINT function performs the real>integer conversion that is
  92.           what you probably want: (nearest integer) rather than the INT
  93.           function (truncate to integer).
  94.  
  95.  
  96. NAME:     FOLD
  97. PURPOSE:  case fold a character (a-z folds to A-Z)
  98. TYPE:     CHARACTER*1 function (far external)
  99. SYNTAX:   C2=FOLD(C1)
  100. INPUT:    C1 (CHARACTER*1)
  101. OUTPUT:   C2 (CHARACTER*1)
  102.  
  103.  
  104. NAME:     FOLDS
  105. PURPOSE:  case fold a character string (a-z folds to A-Z)
  106. TYPE:     subroutine (far external)
  107. SYNTAX:   CALL FOLDS(CBUF,NBUF)
  108. INPUT:    CBUF (CHARACTER*1 CBUF(NBUF) or CHARACTER*80 CBUF, NBUF=80)
  109.           NBUF (INTEGER*2) number of characters in the string
  110. OUTPUT:   CBUF
  111.  
  112.  
  113. NAME:     ISERCH
  114. PURPOSE:  search for a character in a string
  115. TYPE:     INTEGER*2 function (far external)
  116. SYNTAX:   K=ISERCH('?','are you kidding?',NBUF)
  117. INPUT:    a CHARACTER*1 variable (here '?')
  118.           CBUF (CHARACTER*1 CBUF(NBUF) or CHARACTER*80 CBUF, NBUF=80)
  119.           NBUF (INTEGER*2) number of characters in the string
  120. OUTPUT:   K (INTEGER*2)
  121. NOTE:     0<=K<=NBUF (if found, I will be first occurrence, if not
  122.           found, K=0)
  123.  
  124.  
  125. NAME:     IAND/IOR/IXOR
  126. PURPOSE:  logical functions
  127. TYPE:     INTEGER*2 function (far external)
  128. SYNTAX:   I=IAND(J,K)  I=IOR(J,K)  I=IXOR(J,K)
  129. INPUT:    J,K INTEGER*2 variables
  130. OUTPUT:   I (INTEGER*2)
  131.  
  132.  
  133. NAME:     ILB/IRB
  134. PURPOSE:  integer>integer/character
  135. TYPE:     INTEGER*2 function (far external)
  136. SYNTAX:   I=ILB(J)  I=IRB(J)
  137. INPUT:    J INTEGER*2 character
  138. OUTPUT:   I (INTEGER*2)
  139. NOTE:     I=ILB(J) is the same as I=J/256
  140.           I=IRB(J) is the same as I=MOD(J,256)
  141.  
  142.  
  143. NAME:     MATCH
  144. PURPOSE:  check two character strings for a match
  145. TYPE:     LOGICAL*2 function (far external)
  146. SYNTAX:   IF(MATCH(CBUF,'STOP',4)) GO TO 999
  147. INPUT:    two character strings (may be CHARACTER*1 CBUF1(NBUF),
  148.           CBUF2(NBUF) or CHARACTER*4 CBUF1,CBUF2)
  149.           NBUF (INTEGER*2) number of characters in the strings
  150. OUTPUT:   .true./.false.
  151. NOTE:     the strings need not have the same length as long as they are
  152.           both at least NBUF in length (here NBUF=4)
  153.  
  154.           One annoying thing about FORTRAN is that it won't compare the
  155.           first 4 characters of a string read in as 4A1 with a string
  156.           of length 4 like 'STOP'. MATCH solves this problem.
  157.  
  158.  
  159. NAME:     MOVEC
  160. PURPOSE:  move one character string into another
  161. TYPE:     subroutine (far external)
  162. SYNTAX:   CALL MOVEC(CBUF1,CBUF2,NBUF) or CALL MOVEC(CBUF,'STOP',4)
  163. INPUT:    CBUF2 a character string (may be CHARACTER*1 CBUF2(NBUF) or
  164.           CHARACTER*4 CBUF2)
  165.           NBUF (INTEGER*2) number of characters in the strings
  166. OUTPUT:   CBUF1 a character string (may be CHARACTER*1 CBUF1(NBUF) or
  167.           CHARACTER*4 CBUF1)
  168. NOTE:     the strings need not have the same length as long as they are
  169.           both at least NBUF in length (here NBUF=4)
  170.  
  171.           One annoying thing about FORTRAN is that it won't equivalence
  172.           first 4 characters of a 4A1 string to a string of length 4
  173.           like 'STOP'. MOVEC solves this problem. It's also much faster.
  174.  
  175.  
  176. NAME:     MOVEI
  177. PURPOSE:  move one integer array into another
  178. TYPE:     subroutine (far external)
  179. SYNTAX:   CALL MOVEI(IBUF1,IBUF2,NBUF)
  180. INPUT:    IBUF2 (INTEGER*2) an array
  181.           NBUF (INTEGER*2) number of elements in the arrays
  182. OUTPUT:   IBUF1 (INTEGER*2) an array
  183. NOTE:     the strings need not have the same length as long as they are
  184.           both at least NBUF in length
  185.  
  186.           This is about seventeen times as fast as a FORTRAN "DO LOOP".
  187.  
  188.  
  189. NAME:     NBUFC1
  190. PURPOSE:  determine the nominal length of a character string excluding
  191.           trailing blanks
  192. TYPE:     INTEGER*2 function (far external)
  193. SYNTAX:   IF(NBUFC1(CBUF,80).EQ.0) STOP   or
  194.           L=NBUFC1(CBUF,NBUF)
  195. INPUT:    CBUF a character string (may be CHARACTER*1 CBUF(NBUF) or
  196.           CHARACTER*4 CBUF)
  197.           NBUF (INTEGER*2) total number of characters in the string
  198. OUTPUT:   L (INTEGER*2) nominal length of string
  199.  
  200.  
  201. NAME:     SWAPC
  202. PURPOSE:  swap two character strings
  203. TYPE:     subroutine (far external)
  204. SYNTAX:   CALL SWAPC(CBUF1,CBUF2,NBUF)
  205. INPUT:    CBUF1 and CBUF2 character strings (may be CHARACTER*1
  206.           CBUF1(NBUF),CBUF2(NBUF) or CHARACTER*4 CBUF1,CBUF2)
  207.           NBUF (INTEGER*2) number of characters in the strings
  208. OUTPUT:   CBUF1,CBUF2
  209. NOTE:     the strings need not have the same length as long as they are
  210.           both at least NBUF in length
  211.  
  212.  
  213. NAME:     SWAPI
  214. PURPOSE:  swap two integer arrays
  215. TYPE:     subroutine (far external)
  216. SYNTAX:   CALL SWAPI(IBUF1,IBUF2,NBUF)
  217. INPUT:    IBUF1,IBUF2 (INTEGER*2) an arrays
  218.           NBUF (INTEGER*2) number of elements in the arrays
  219. OUTPUT:   IBUF1,IBUF2
  220. NOTE:     the arrays need not have the same length as long as they are
  221.           both at least NBUF in length
  222.  
  223.  
  224. NAME:     SORTC
  225. PURPOSE:  sort a group of character strings
  226. TYPE:     subroutine (far external)
  227. SYNTAX:   CALL SORTC(GROUP,L,N,ASCEND)
  228. INPUT:    GROUP a group of character strings (may be CHARACTER*1
  229.           GROUP(L,N) or CHARACTER*64 GROUP(N) if L=64)
  230.           L (INTEGER*2) length of the strings
  231.           N (INTEGER*2) number of strings in group
  232.           ASCEND (LOGICAL*2) .true. for ascending order, .false. for
  233.           descending order
  234. OUTPUT:   GROUP
  235. NOTE:     A modification of the shell sort is used.
  236.  
  237.           This operation isn't even possible in FORTRAN because you
  238.           can't pass the length of a character variable as a formal
  239.           parameter.
  240.  
  241. WARNING:  Be careful that GROUP does not cross a segment boundary!
  242.           That is, GROUP can not contain more than 65356 bytes nor
  243.           be part of a data group that spans a segment boundary. See
  244.           the comments in the section on vector emulation for more
  245.           details on segment boundaries.
  246.  
  247.  
  248. NAME:     SORTCI
  249. PURPOSE:  sort a group of indexed character strings
  250. TYPE:     subroutine (far external)
  251. SYNTAX:   CALL SORTCI(GROUP,L,INDEX,N,ASCEND)
  252. INPUT:    GROUP a group of character strings (may be CHARACTER*1
  253.           GROUP(L,N) or CHARACTER*64 GROUP(N) if L=64)
  254.           L (INTEGER*2) length of the strings
  255.           INDEX (INTEGER*2) some index like 1,2,3,4,5...
  256.           N (INTEGER*2) number of strings in group
  257.           ASCEND (LOGICAL*2) .true. for ascending order, .false. for
  258.           descending order
  259. OUTPUT:   GROUP, INDEX (if, for example, you set INDEX to 1,2,3,4,5...
  260.           upon return from SORTCI you can tell what the change was from
  261.           the original order - INDEX will come back as something like
  262.           13,2,35,27,3,18,...)
  263. NOTE:     A modification of the shell sort is used.
  264.  
  265.           This operation isn't even possible in FORTRAN because you
  266.           can't pass the length of a character variable as a formal
  267.           parameter.
  268.  
  269. WARNING:  Be careful that GROUP and INDEX do not cross segment
  270.           boundaries. That is, GROUP can not contain more than 65356
  271.           bytes and INDEX can not contain mode than 32768 elements nor
  272.           be part of a data group that spans a segment boundary. See
  273.           the comments in the section on vector emulation for more
  274.           details on segment boundaries.
  275.  
  276.  
  277. NAME:     SORTD
  278. PURPOSE:  sort an array of double precision reals
  279. TYPE:     subroutine (far external)
  280. SYNTAX:   CALL SORTD(D,N,ASCEND)
  281. INPUT:    D (REAL*8) array
  282.           N (INTEGER*2) number of elements in D
  283.           ASCEND (LOGICAL*2) .true. for ascending order, .false. for
  284.           descending order
  285. OUTPUT:   D
  286. NOTE:     A modification of the shell sort is used.
  287.  
  288. WARNING:  Be careful that D does not cross a segment boundary!
  289.           That is, D can not contain more than 8192 elements nor
  290.           be part of a data group that spans a segment boundary. See
  291.           the comments in the section on vector emulation for more
  292.           details on segment boundaries.
  293.  
  294.  
  295. NAME:     SORTDI
  296. PURPOSE:  sort an array of indexed double precision reals
  297. TYPE:     subroutine (far external)
  298. SYNTAX:   CALL SORTDI(D,INDEX,N,ASCEND)
  299. INPUT:    D (REAL*8) array
  300.           INDEX (INTEGER*2) some index like 1,2,3,4,5...
  301.           N (INTEGER*2) number of elements in D
  302.           ASCEND (LOGICAL*2) .true. for ascending order, .false. for
  303.           descending order
  304. OUTPUT:   D, INDEX (if, for example, you set INDEX to 1,2,3,4,5...
  305.           upon return from SORTDI you can tell what the change was from
  306.           the original order - INDEX will come back as something like
  307.           13,2,35,27,3,18,...)
  308. NOTE:     A modification of the shell sort is used.
  309.  
  310. WARNING:  Be careful that D and INDEX do not cross segment
  311.           boundaries. That is, D can not contain more than 8192
  312.           bytes and INDEX can not contain mode than 32766 elements nor
  313.           be part of a data group that spans a segment boundary. See
  314.           the comments in the section on vector emulation for more
  315.           details on segment boundaries.
  316.  
  317.  
  318. NAME:     SORTI
  319. PURPOSE:  sort an array of integers
  320. TYPE:     subroutine (far external)
  321. SYNTAX:   CALL SORTI(K,N,ASCEND)
  322. INPUT:    K (INTEGER*2) array
  323.           N (INTEGER*2) number of elements in K
  324.           ASCEND (LOGICAL*2) .true. for ascending order, .false. for
  325.           descending order
  326. OUTPUT:   K
  327. NOTE:     A modification of the shell sort is used.
  328.  
  329. WARNING:  Be careful that K does not cross a segment boundary!
  330.           That is, K can not contain more than 32768 elements nor
  331.           be part of a data group that spans a segment boundary. See
  332.           the comments in the section on vector emulation for more
  333.           details on segment boundaries.
  334.  
  335.  
  336. NAME:     SORTII
  337. PURPOSE:  sort an array of indexed integers
  338. TYPE:     subroutine (far external)
  339. SYNTAX:   CALL SORTII(K,INDEX,N,ASCEND)
  340. INPUT:    K (INTEGER*2) array
  341.           INDEX (INTEGER*2) some index like 1,2,3,4,5...
  342.           N (INTEGER*2) number of elements in K
  343.           ASCEND (LOGICAL*2) .true. for ascending order, .false. for
  344.           descending order
  345. OUTPUT:   K, INDEX (if, for example, you set INDEX to 1,2,3,4,5...
  346.           upon return from SORTII you can tell what the change was from
  347.           the original order - INDEX will come back as something like
  348.           13,2,35,27,3,18,...)
  349. NOTE:     A modification of the shell sort is used.
  350.  
  351. WARNING:  Be careful that K and INDEX do not cross segment
  352.           boundaries. That is, K can not contain more than 32768
  353.           bytes and INDEX can not contain mode than 32766 elements nor
  354.           be part of a data group that spans a segment boundary. See
  355.           the comments in the section on vector emulation for more
  356.           details on segment boundaries.
  357.  
  358.  
  359. NAME:     SORTR
  360. PURPOSE:  sort an array of reals
  361. TYPE:     subroutine (far external)
  362. SYNTAX:   CALL SORTR(R,N,ASCEND)
  363. INPUT:    R (REAL*4) array
  364.           N (INTEGER*2) number of elements in R
  365.           ASCEND (LOGICAL*2) .true. for ascending order, .false. for
  366.           descending order
  367. OUTPUT:   R
  368. NOTE:     A modification of the shell sort is used.
  369.  
  370. WARNING:  Be careful that R does not cross a segment boundary!
  371.           That is, R can not contain more than 16384 elements nor
  372.           be part of a data group that spans a segment boundary. See
  373.           the comments in the section on vector emulation for more
  374.           details on segment boundaries.
  375.  
  376.  
  377. NAME:     SORTRI
  378. PURPOSE:  sort an array of indexed reals
  379. TYPE:     subroutine (far external)
  380. SYNTAX:   CALL SORTRI(R,INDEX,N,ASCEND)
  381. INPUT:    R (REAL*4) array
  382.           INDEX (INTEGER*2) some index like 1,2,3,4,5...
  383.           N (INTEGER*2) number of elements in R
  384.           ASCEND (LOGICAL*2) .true. for ascending order, .false. for
  385.           descending order
  386. OUTPUT:   R, INDEX (if, for example, you set INDEX to 1,2,3,4,5...
  387.           upon return from SORTRI you can tell what the change was from
  388.           the original order - INDEX will come back as something like
  389.           13,2,35,27,3,18,...)
  390. NOTE:     A modification of the shell sort is used.
  391.  
  392. WARNING:  Be careful that R and INDEX do not cross segment
  393.           boundaries. That is, R can not contain more than 16384
  394.           bytes and INDEX can not contain mode than 32766 elements nor
  395.           be part of a data group that spans a segment boundary. See
  396.           the comments in the section on vector emulation for more
  397.           details on segment boundaries.
  398.