home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / pgmutl / val_link.arc / STRING.C < prev    next >
Text File  |  1989-02-18  |  19KB  |  485 lines

  1. /*                                 STRING.C                                */
  2.  
  3. /*+-------------------------------------------------------------------------+
  4.   |                                                                         |
  5.   |                        allocate_string                                  |
  6.   |                                                                         |
  7.   +-------------------------------------------------------------------------+*/
  8. string_ptr allocate_string(pool_descriptor_ptr pool, bit_16 len)
  9. BeginDeclarations
  10. string_ptr                             temp;
  11. #define Temp                           (*temp)
  12. EndDeclarations
  13. BeginCode
  14.  temp = StringPtr(allocate_memory(pool, Bit_32(sizeof(string_type))+
  15.                                         Bit_32(len)));
  16.  Temp.max_length = len;
  17.  Temp.length     = 0;
  18.  Temp.text[0]    = '\000';
  19.  return(temp);
  20. EndCode
  21. #undef Temp
  22.  
  23. /*+-------------------------------------------------------------------------+
  24.   |                                                                         |
  25.   |                         compare_string                                  |
  26.   |                                                                         |
  27.   +-------------------------------------------------------------------------+*/
  28. int compare_string(string_ptr left, string_ptr right)
  29. BeginDeclarations
  30. bit_16                                 left_len;
  31. bit_16                                 right_len;
  32. EndDeclarations
  33. BeginCode
  34.  left_len  = Length(left);
  35.  right_len = Length(right);
  36.  If (left_len IsZero) AndIf (right_len IsZero)
  37.   Then
  38.    return(0);
  39.   EndIf;
  40.  If left_len LessThan right_len
  41.   Then
  42.    return(-1);
  43.   EndIf;
  44.  If left_len GreaterThan right_len
  45.   Then
  46.    return(1);
  47.   EndIf;
  48.  return(far_compare(String(left), String(right), left_len));
  49. EndCode
  50.  
  51. /*+-------------------------------------------------------------------------+
  52.   |                                                                         |
  53.   |                         compare_short_string                            |
  54.   |                                                                         |
  55.   +-------------------------------------------------------------------------+*/
  56. int compare_short_string(string_ptr left, string_ptr right)
  57. BeginDeclarations
  58. bit_16                                 left_len;
  59. EndDeclarations
  60. BeginCode
  61.  left_len = Length(left);
  62.  If left_len IsZero
  63.   Then
  64.    return(0);
  65.   EndIf;
  66.  return(far_compare(String(left), String(right), left_len));
  67. EndCode
  68.  
  69. /*+-------------------------------------------------------------------------+
  70.   |                                                                         |
  71.   |                         concat_string                                   |
  72.   |                                                                         |
  73.   +-------------------------------------------------------------------------+*/
  74. string_ptr concat_string(string_ptr dest, string_ptr source)
  75. BeginDeclarations
  76. bit_16                                 temp;
  77. EndDeclarations
  78. BeginCode
  79.  If (Length(source) + Length(dest)) Exceeds MaxLength(dest)
  80.   Then
  81.    linker_error(8,"Destination string to small (%u bytes) to hold "
  82.                   "concatination of:\n"
  83.                   "\t\"%Fs\" (%u bytes) and\n"
  84.                   "\t\"%Fs\" (%u bytes)\n",
  85.                   MaxLength(dest),
  86.                   String(dest), Length(dest),
  87.                   String(source), Length(dest));
  88.   EndIf;
  89.  temp = Length(source);
  90.  far_move(Addr(String(dest)[Length(dest)]), String(source), temp + 1);
  91.  Length(dest) += temp;
  92.  return(dest);
  93. EndCode
  94.  
  95. /*+-------------------------------------------------------------------------+
  96.   |                                                                         |
  97.   |                         concat_char_to_string                           |
  98.   |                                                                         |
  99.   +-------------------------------------------------------------------------+*/
  100. string_ptr concat_char_to_string(string_ptr dest, byte c)
  101. BeginDeclarations
  102. EndDeclarations
  103. BeginCode
  104.  If (Length(dest) + 1) Exceeds MaxLength(dest)
  105.   Then
  106.    linker_error(8,"Destination string to small (%u bytes) to add \"%c\" "
  107.                   "to string:\n"
  108.                   "\t\"%Fs\" (%u bytes)\n",
  109.                   MaxLength(dest), c,
  110.                   String(dest), Length(dest));
  111.   EndIf;
  112.  String(dest)[Length(dest)++] = c;
  113.  String(dest)[Length(dest)]   = '\000';
  114.  return(dest);
  115. EndCode
  116.  
  117. /*+-------------------------------------------------------------------------+
  118.   |                                                                         |
  119.   |                         copy_string                                     |
  120.   |                                                                         |
  121.   +-------------------------------------------------------------------------+*/
  122. string_ptr copy_string (string_ptr dest, string_ptr source)
  123. BeginDeclarations
  124. EndDeclarations
  125. BeginCode
  126.  If Length(source) Exceeds MaxLength(dest)
  127.   Then
  128.    linker_error(8,"Destination string to small (%u bytes) to hold:\n"
  129.                   "\t\"%Fs\" (%u bytes)\n",
  130.                   MaxLength(dest),
  131.                   String(source), Length(dest));
  132.   EndIf;
  133.  Length(dest) = Length(source);
  134.  far_move(String(dest), String(source), Length(source)+1);
  135.  return(dest);
  136. EndCode
  137.  
  138. /*+-------------------------------------------------------------------------+
  139.   |                                                                         |
  140.   |                            cut_string                                   |
  141.   |                                                                         |
  142.   +-------------------------------------------------------------------------+*/
  143. string_ptr cut_string(string_ptr s, bit_16 at, bit_16 len)
  144. BeginDeclarations
  145. bit_16                                 length_to_right;
  146. bit_16                                 string_length;
  147. EndDeclarations
  148. BeginCode
  149.  string_length = Length(s);
  150.  If string_length NotGreaterThan at
  151.   Then
  152.    return(s);
  153.   EndIf;
  154.  If string_length LessThan (at + len)
  155.   Then
  156.    len = string_length - at;
  157.   EndIf;
  158.  Length(s)       -= len;
  159.  length_to_right  = string_length - (at+len);
  160.  far_move(Addr(String(s)[at]), Addr(String(s)[at+len]), length_to_right+1);
  161.  return(s);
  162. EndCode
  163.  
  164. /*+-------------------------------------------------------------------------+
  165.   |                                                                         |
  166.   |                            duplicate_string                             |
  167.   |                                                                         |
  168.   +-------------------------------------------------------------------------+*/
  169. string_ptr duplicate_string(pool_descriptor_ptr pool, string_ptr s)
  170. BeginDeclarations
  171. string_ptr                             temp;
  172. #define Temp                           (*temp)
  173. EndDeclarations
  174. BeginCode
  175.  temp = StringPtr(allocate_memory(pool,
  176.                                   Bit_32(sizeof(string_type))+
  177.                                   Bit_32(Length(s))));
  178.  Temp.max_length = Length(s);
  179.  copy_string(temp, s);
  180.  return(temp);
  181. EndCode
  182. #undef Temp
  183.  
  184. /*+-------------------------------------------------------------------------+
  185.   |                                                                         |
  186.   |                           edit_number_string                            |
  187.   |                                                                         |
  188.   +-------------------------------------------------------------------------+*/
  189. string_ptr edit_number_string(string_ptr s, char_ptr format, ...)
  190. BeginDeclarations
  191. va_list                                argptr;
  192. bit_16                                 i;
  193. EndDeclarations
  194. BeginCode
  195.  va_start(argptr,format);
  196.  vsprintf((char_ptr) temp_near_string, format, argptr);
  197.  copy_string(s, string(temp_near_string));
  198.  i = Length(s);
  199.  While i Exceeds 3
  200.   BeginWhile
  201.    i -= 3;
  202.    paste_string(s, i, comma_string);
  203.   EndWhile;
  204.  return(s);
  205. EndCode
  206.  
  207. /*+-------------------------------------------------------------------------+
  208.   |                                                                         |
  209.   |                           index_string                                  |
  210.   |                                                                         |
  211.   +-------------------------------------------------------------------------+*/
  212. bit_16 index_string(string_ptr s, bit_16 from, string_ptr pattern)
  213. BeginDeclarations
  214. bit_16                                 i;
  215. bit_16                                 iteration_count;
  216. byte_ptr                               left;
  217. bit_16                                 len;
  218. byte_ptr                               pat;
  219. bit_16                                 pattern_length;
  220. EndDeclarations
  221. BeginCode
  222.  pattern_length = Length(pattern);
  223.  pat            = String(pattern);
  224.  len            = Length(s);
  225.  If (len - from) LessThan pattern_length
  226.   Then
  227.    return(0xFFFF);
  228.   EndIf;
  229.  iteration_count = len - pattern_length + 1;
  230.  left  = Addr(String(s)[from]);
  231.  For i=from; i LessThan iteration_count; i++
  232.   BeginFor
  233.    If far_compare(left++, pat, pattern_length) IsZero
  234.     Then
  235.      return(i);
  236.     EndIf;
  237.   EndFor;
  238.  return(0xFFFF);
  239. EndCode
  240.  
  241. /*+-------------------------------------------------------------------------+
  242.   |                                                                         |
  243.   |                       lowercase_string                                  |
  244.   |                                                                         |
  245.   +-------------------------------------------------------------------------+*/
  246. string_ptr lowercase_string(string_ptr s)
  247. BeginDeclarations
  248. EndDeclarations
  249. BeginCode
  250.  far_to_lower(String(s), Length(s));
  251.  return(s);
  252. EndCode
  253.  
  254. /*+-------------------------------------------------------------------------+
  255.   |                                                                         |
  256.   |                      make_constant_string                               |
  257.   |                                                                         |
  258.   +-------------------------------------------------------------------------+*/
  259. string_ptr make_constant_string(pool_descriptor_ptr pool, byte *s)
  260. BeginDeclarations
  261. bit_16                                 len;
  262. string_ptr                             temp;
  263. EndDeclarations
  264. BeginCode
  265.  len  = strlen(CharPtr(s));
  266.  temp = StringPtr(allocate_memory(pool, 
  267.                                   Bit_32(sizeof(string_type))+Bit_32(len)));
  268.  Length(temp)    =
  269.  MaxLength(temp) = len++;
  270.  far_move(String(temp), BytePtr(s), len);
  271.  return(temp);
  272. EndCode
  273.  
  274. /*+-------------------------------------------------------------------------+
  275.   |                                                                         |
  276.   |                             match_pattern                               |
  277.   |                                                                         |
  278.   +-------------------------------------------------------------------------+*/
  279. bit_16 match_pattern(string_ptr pattern, string_ptr s)
  280. BeginDeclarations
  281. bit_16                                 i;
  282. bit_16                                 n_searches;
  283. byte_ptr                               source;
  284. EndDeclarations
  285. BeginCode
  286.  If FirstCharIn(pattern) Is '*'
  287.   Then
  288.    cut_string(pattern, 0, 1);
  289.    If LastCharIn(pattern) Is '*'
  290.     Then /* We must perform exhaustive search */
  291.      cut_string(pattern, 0, Length(pattern)-1);
  292.      If Length(pattern) Exceeds Length(s)
  293.       Then
  294.        return(False);
  295.       EndIf;
  296.      n_searches = Length(s) - Length(pattern) + 1;
  297.      source = String(s);
  298.      For i=0; i<n_searches; i++
  299.       BeginFor
  300.        If far_match(String(pattern), source++, Length(pattern))
  301.         Then
  302.          return(True);
  303.         EndIf;
  304.       EndFor;
  305.     Else /* We must match only the tail */
  306.      If Length(pattern) Exceeds Length(s)
  307.       Then
  308.        return(False);
  309.       Else
  310.        return(far_match(String(pattern),
  311.                         BytePtr(Addr(String(s)[Length(s)-Length(pattern)])),
  312.                         Length(pattern)));
  313.       EndIf;
  314.     EndIf;
  315.   Else /* We must match only the front */
  316.    return(far_match(String(pattern), String(s), Length(pattern)));
  317.   EndIf;
  318.  return(False);
  319. EndCode
  320.  
  321. /*+-------------------------------------------------------------------------+
  322.   |                                                                         |
  323.   |                             near_string                                 |
  324.   |                                                                         |
  325.   +-------------------------------------------------------------------------+*/
  326. byte *near_string(string_ptr s)
  327. BeginDeclarations
  328. EndDeclarations
  329. BeginCode
  330.  far_move(temp_near_string, String(s), Length(s)+1);
  331.  return(temp_near_string);
  332. EndCode
  333.  
  334. /*+-------------------------------------------------------------------------+
  335.   |                                                                         |
  336.   |                            paste_string                                 |
  337.   |                                                                         |
  338.   +-------------------------------------------------------------------------+*/
  339. string_ptr paste_string(string_ptr dest, bit_16 at, string_ptr s)
  340. BeginDeclarations
  341. bit_16                                 length_inserted_string;
  342. bit_16                                 length_string_to_right;
  343. bit_16                                 length_string;
  344. EndDeclarations
  345. BeginCode
  346.  length_string          = Length(dest);
  347.  length_inserted_string = Length(s);
  348.  If (length_string + length_inserted_string) Exceeds MaxLength(dest)
  349.   Then
  350.    linker_error(8,"Destination string too small (%u bytes) to insert:\n"
  351.                   "\t\"%Fs\" (%u bytes) into\n"
  352.                   "\t\"%Fs\" (%u bytes)\n",
  353.                   MaxLength(dest),
  354.                   s, length_inserted_string,
  355.                   String(dest), length_string);
  356.   EndIf;
  357.  If length_inserted_string IsZero
  358.   Then
  359.    return(dest);
  360.   EndIf;
  361.  If at Exceeds length_string
  362.   Then
  363.    at = length_string;
  364.   EndIf;
  365.  length_string_to_right = length_string - at;
  366.  far_move_left(Addr(String(dest)[at+length_inserted_string]),
  367.                Addr(String(dest)[at]),
  368.                length_string_to_right+1);
  369.  far_move(Addr(String(dest)[at]), String(s), length_inserted_string);
  370.  Length(dest) += length_inserted_string;
  371.  return(dest);
  372. EndCode
  373.  
  374. /*+-------------------------------------------------------------------------+
  375.   |                                                                         |
  376.   |                         reverse_index_string                            |
  377.   |                                                                         |
  378.   +-------------------------------------------------------------------------+*/
  379. bit_16 reverse_index_string(string_ptr s, bit_16 from, string_ptr pattern)
  380. BeginDeclarations
  381. bit_16                                 i;
  382. bit_16                                 iteration_count;
  383. bit_16                                 len;
  384. byte_ptr                               right;
  385. byte_ptr                               pat;
  386. bit_16                                 pattern_length;
  387. EndDeclarations
  388. BeginCode
  389.  pattern_length = Length(pattern);
  390.  len            = Length(s);
  391.  pat            = String(pattern);
  392.  If len LessThan pattern_length
  393.   Then
  394.    return(0xFFFF);
  395.   EndIf;
  396.  If from Exceeds (len - pattern_length)
  397.   Then
  398.    from = len - pattern_length;
  399.   EndIf;
  400.  iteration_count = from + 1;
  401.  right = Addr(String(s)[from]);
  402.  For i=0; i LessThan iteration_count; i++, from--
  403.   BeginFor
  404.    If far_compare(right--, pat, pattern_length) IsZero
  405.     Then
  406.      return(from);
  407.     EndIf;
  408.   EndFor;
  409.  return(0xFFFF);
  410. EndCode
  411.  
  412. /*+-------------------------------------------------------------------------+
  413.   |                                                                         |
  414.   |                               string                                    |
  415.   |                                                                         |
  416.   +-------------------------------------------------------------------------+*/
  417. string_ptr string(byte_ptr s)
  418. BeginDeclarations
  419. bit_16                                 len;
  420. EndDeclarations
  421. BeginCode
  422.  len  = far_index(s, 0);
  423.  If len Exceeds MaxLength(temp_string)
  424.   Then
  425.    linker_error(8,"Destination string too small (%u bytes) to hold:\n"
  426.                   "\t\"%s\" (%u bytes)\n",
  427.                   MaxLength(temp_string),
  428.                   s, len);
  429.   EndIf;
  430.  far_move(String(temp_string), s, len+1);
  431.  Length(temp_string) = len;
  432.  return(temp_string);
  433. EndCode
  434.  
  435. /*+-------------------------------------------------------------------------+
  436.   |                                                                         |
  437.   |                               substr                                    |
  438.   |                                                                         |
  439.   +-------------------------------------------------------------------------+*/
  440. string_ptr substr(string_ptr s, bit_16 at, bit_16 len)
  441. BeginDeclarations
  442. bit_16                                 string_length;
  443. EndDeclarations
  444. BeginCode
  445.  string_length = Length(s);
  446.  If string_length IsZero
  447.   Then
  448.    return(null_string);
  449.   EndIf;
  450.  If at NotLessThan string_length
  451.   Then
  452.    at = string_length - 1;
  453.   EndIf;
  454.  If len Exceeds Bit_16(string_length - at)
  455.   Then
  456.    len = string_length - at;
  457.   EndIf;
  458.  If len Exceeds MaxLength(temp_string)
  459.   Then
  460.    linker_error(8,"Destination string too small in SUBSTR operation\n");
  461.   EndIf;
  462.  far_move(String(temp_string), Addr(String(s)[at]), len+1);
  463.  Length(temp_string) = len;
  464.  return(temp_string);
  465. EndCode
  466.  
  467. /*+-------------------------------------------------------------------------+
  468.   |                                                                         |
  469.   |                            trunc_string                                 |
  470.   |                                                                         |
  471.   +-------------------------------------------------------------------------+*/
  472. string_ptr trunc_string(string_ptr s, bit_16 at)
  473. BeginDeclarations
  474. EndDeclarations
  475. BeginCode
  476.  If Length(s) NotGreaterThan at+1
  477.   Then
  478.    return(s);
  479.   EndIf;
  480.  Length(s)     = at;
  481.  String(s)[at] = '\000';
  482.  return(s);
  483. EndCode
  484.  
  485.