home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / pstrings / part01 / strings.h < prev    next >
Encoding:
Text File  |  1991-08-07  |  7.3 KB  |  397 lines

  1. {
  2. *
  3. * String handling package in Pascal (ISO Level 1).
  4. *
  5. *   This package of procedures and functions implements unbounded
  6. * Strings of Characters. 
  7. *
  8. * N.B. All string variables MUST be initialised via initS(s).
  9. *      Assignment MUST be via assignS(dest, src).
  10. *      If desired, storage may be reclaimed via finalS(s).
  11. *  i.e.
  12. *         var s,t: String;
  13. *             . . .
  14. *       initS(s); initS(t);
  15. *          . . .
  16. *       assignS(t, concatS(mkS('Join this string '), mkS('to this')));
  17. *       assignS(s, t);
  18. *          . . .
  19. *       finalS(s); finalS(t);
  20. *
  21. * Additionally, string by-value parameters must be initialised by calling
  22. * initvalparamS(s).
  23. * * e.g.
  24. *
  25. *    procedure p(s:String);
  26. *     begin writelnS(output, concatS(s, concatS(s,s)))
  27. *     end;
  28. *
  29. * MUST be written as:
  30. *
  31. *    procedure p(s:String);
  32. *     begin initvalparamS(s);
  33. *           writelnS(output, concatS(s, concatS(s,s)))
  34. *     end;
  35. * (This is because the package performs incremental garbage collection
  36. *  on unassigned strings, but extant by-value references cannot be
  37. *  detected.)
  38. *
  39. *
  40. *
  41. * Implementation Issues:
  42. *
  43. * The representation is a header record containing a
  44. * length field, a reference count, and a packed array [1..slength]
  45. * of Char, followed by zero or more `tail' chunks - also
  46. * containing a packed array [1..slength] of Char.
  47. * The empty string is represented by nil.  Beware of
  48. * s1 := s2   this copies pointers (!) not the strings themselves.
  49. * `:=' between strings should not be used; it cannot be banned
  50. * because types inherit assignment in Pascal.
  51. * The procedure     assignS(dest, source) 
  52. * should be used to copy strings, it uses the reference count to
  53. * avoid copying.  Only if updateS is used will the string
  54. * actually be copied (if the ref count is > 1).
  55. *
  56. *   All the routines end with a capital S.
  57. *
  58. * Ian Cottam, University of Manchester,  NOV.85. revised MAR.86 and DEC.86.
  59. *                                        revised MAR.88 - better names,
  60. *                     plus use of initvalparamS.
  61. }
  62.  
  63. { -- string chunk length - any length > 0 will work }
  64. const slength = 16;
  65.  
  66. type
  67.  
  68.   String = ^ stringrec;
  69.  
  70.  
  71.   Nat0 = 0 .. maxint;
  72.  
  73.   Nat1 = 1 .. maxint;
  74.    
  75.  
  76.   stringtail = ^ tailrec;
  77.  
  78.   stringrec = record
  79.     LEN:  Nat1; { -- Note: no 0 as nil represents '' }
  80.     REFS: Nat0; { -- How many refs are there to this string }
  81.                 { -- N.B. only = 0 when string generated by a function }
  82.     HEAD: packed array [1..slength] of Char;
  83.     TAIL: stringtail
  84.       end;
  85.  
  86.   tailrec   = record
  87.         MORE: packed array [1..slength] of Char;
  88.         REST: stringtail
  89.           end;
  90.  
  91.  
  92.  { -- Result of compare - internal function to ADT }
  93.  StrCmpResult = (lt, eq, gt);
  94.  
  95.  { -- type for sequencing thru strings - internal to ADT at the moment}
  96.  CharOfString = record 
  97.                    POS: 1..slength;
  98.                   case KIND: Boolean of
  99.              true:  (HD: String);
  100.              false: (TL: stringtail)
  101.                 end;
  102.  
  103.  
  104. {************ function and procedure headings **************}
  105.  
  106. { --   ...   in Alphabetical order   ...           }
  107.  
  108.  
  109.  
  110. procedure assignS(var lhs: String; rhs: String);
  111. {
  112. * lhs := rhs 
  113. }
  114. external;
  115.  
  116.  
  117.  
  118. { ***** AUXILIARY FUNCTION ***** }
  119. function compare(left, right:String):StrCmpResult; 
  120. {
  121. * String comparison - used in the impl. of eqS, neS, ltS, etc.
  122. }
  123. external;
  124.  
  125.  
  126. function concatS(s1, s2: String):String;
  127. {
  128. * Returns s1 + s2
  129. * Concatenates s1 and s2.
  130. }
  131. external;
  132.  
  133.  
  134.  
  135. function CtoS(c: Char):String;
  136. {
  137. * Converts a character into a string of length 1
  138. }
  139. external;
  140.  
  141.  
  142.  
  143. procedure disposeS(var s: String);
  144. {
  145. * reclaims the storage associated with the string s
  146. }
  147. external;
  148.  
  149.  
  150.  
  151. function emptyS: String;
  152. {
  153. * Returns the empty or null string ''
  154. }
  155. external;
  156.  
  157.  
  158.  
  159. function eqS(left,right: String):Boolean;
  160. {
  161. * left = right
  162. }
  163. external;
  164.  
  165.  
  166. procedure finalS(var s: String);
  167. {
  168. * same as disposeS but possibly better name
  169. * reclaims the storage associated with the string s
  170. }
  171. external;
  172.  
  173.  
  174.  
  175. { ***** AUXILIARY FUNCTION ***** }
  176. procedure first(var c:CharOfString; var s: String);
  177. {
  178. * c initialised to point to the first char of s
  179. *
  180. * precondition
  181. *     s <> ''
  182. }
  183. external;
  184.  
  185.  
  186.  
  187. function geS(left,right: String):Boolean;
  188. {
  189. * left >= right
  190. }
  191. external;
  192.  
  193.  
  194.  
  195. function getsubS(s: String; frompos, topos: Nat0):String;
  196. {
  197. * Returns s[frompos..topos]
  198. * Extracts a substring of s.
  199. *  returns ''  if frompos..topos not in range.
  200. }
  201. external;
  202.  
  203.  
  204.  
  205. function gtS(left,right: String):Boolean;
  206. {
  207. * left > right
  208. }
  209. external;
  210.  
  211.  
  212.  
  213. function indexS(s: String; i: Nat1):Char;
  214. {
  215. * Returns s[i]
  216. *
  217. * precondition:
  218. *     i <= lengthS(s)
  219. }
  220. external;
  221.  
  222.  
  223.  
  224. procedure initS(var s: String);
  225. {
  226. * Initialises s to be the empty or null string ''
  227. * Same as newS, but possibly less confusing name.
  228. }
  229. external;
  230.  
  231.  
  232.  
  233. procedure initvalparamS(var s: String);
  234. {
  235. * Initialises s, which should be a value parameter, to be
  236. * safely useable within the current procedure.
  237. }
  238. external;
  239.  
  240.  
  241.  
  242. function leS(left,right: String):Boolean;
  243. {
  244. * left <= right
  245. }
  246. external;
  247.  
  248.  
  249.  
  250. function lengthS(s: String):Nat0;
  251. {
  252. * Returns the dynamic length of a string
  253. }
  254. external;
  255.  
  256.  
  257.  
  258. function ltS(left,right: String):Boolean;
  259. {
  260. * left < right
  261. }
  262. external;
  263.  
  264.  
  265.  
  266. function matchS(s, pat: String):Nat0;
  267. {
  268. * Returns position of pat in s or 0 if not present.
  269. * Empty strings are not considered present!
  270. }
  271. external;
  272.  
  273.  
  274.  
  275. { ***** AUXILIARY FUNCTION ***** }
  276. function mk(var static: packed array [lo..hi:Integer] of Char;
  277.             limit: Integer):String;
  278. {
  279. * Converts a static Pascal string into a (dynamic) String.
  280. * From lo to limit rather than hi.
  281. * This internal procedure may be made generally available
  282. * should there be a demand.
  283. }
  284. external;
  285.  
  286.  
  287. function mkS(static: packed array [lo..hi:Integer] of Char):String;
  288. {
  289. * Converts a static Pascal string into a (dynamic) String.
  290. }
  291. external;
  292.  
  293.  
  294.  
  295. procedure mkStaticS(s: String; var p: packed array[lo..hi:Integer] of Char);
  296. {
  297. * Converts a dynamic string into a static string.
  298. * p is null padded if necessary.
  299. * Info will be lost if lengthS(s) > hi-lo+1.
  300. }
  301. external;
  302.  
  303.  
  304.  
  305. function neS(left,right: String):Boolean;
  306. {
  307. * left <> right
  308. }
  309. external;
  310.  
  311.  
  312.  
  313. procedure newS(var s: String);
  314. {
  315. * Initialises s to be the empty or null string ''
  316. }
  317. external;
  318.  
  319.  
  320.  
  321. { ***** AUXILIARY FUNCTION ***** }
  322. procedure next(var c: CharOfString; var ch: Char);
  323. {
  324. * c is advanced to point to next char in its string and current char
  325. * returned in ch
  326. *
  327. * precondition
  328. *     c initialised by call to first and not at end of string
  329. }
  330. external;
  331.  
  332.  
  333.  
  334. procedure readS(var f: Text; var s: String);
  335. {
  336. * Reads a string from text file f; eoln terminating.  The input is
  337. * left pointing to the beginning of the next line, if any.
  338. *
  339. * precondition:
  340. *    f open for reading & not eof(f)
  341. }
  342. external;
  343.  
  344.  
  345.  
  346.  
  347. procedure readtS(var f: Text; var s: String; function stop(c:Char):Boolean);
  348. {
  349. * Reads a string from text file f; eoln or stop(c) returning true
  350. * (whichever occurs first) terminating.  In either case,
  351. * input is left positioned at the terminator.
  352. *
  353. * precondition:
  354. *    f open for reading & not eof(f)
  355. }
  356. external;
  357.  
  358.  
  359.  
  360. function repS(s: String; n: Nat0):String;
  361. {
  362. * Returns s * n
  363. * Replicates s, n times.
  364. }
  365. external;
  366.  
  367.  
  368.  
  369. procedure updateS(var s: String; i: Nat1; c:Char);
  370. {
  371. * Updates the string s at position  i  with the char c.
  372. * if i > lengthS(s), s is first space filled upto i-1.
  373. }
  374. external;
  375.  
  376.  
  377.  
  378. procedure writeS(var f: Text; s: String);
  379. {
  380. * Write the dynamic string s to file f
  381. *
  382. * precondition:
  383. *    f open for writing    
  384. }
  385. external;
  386.  
  387.  
  388.  
  389. procedure writelnS(var f: Text; s: String);
  390. {
  391. * Write the dynamic string s to file f followed by an eoln marker
  392. *
  393. * precondition:
  394. *    f open for writing    
  395. }
  396. external;
  397.