Research portable Memory game | Исследовать портируемую игру Память
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

240 lines
7.9KB

  1. utstring: dynamic string macros for C
  2. =====================================
  3. Troy D. Hanson <tdh@tkhanson.net>
  4. v2.3.0, February 2021
  5. Here's a link back to the https://github.com/troydhanson/uthash[GitHub project page].
  6. Introduction
  7. ------------
  8. A set of basic dynamic string macros for C programs are included with
  9. uthash in `utstring.h`. To use these in your own C program, just copy
  10. `utstring.h` into your source directory and use it in your programs.
  11. #include "utstring.h"
  12. The dynamic string supports operations such as inserting data, concatenation,
  13. getting the length and content, substring search, and clear. It's ok to put
  14. binary data into a utstring too. The string <<operations,operations>> are
  15. listed below.
  16. Some utstring operations are implemented as functions rather than macros.
  17. Download
  18. ~~~~~~~~
  19. To download the `utstring.h` header file,
  20. follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file,
  21. then look in the src/ sub-directory.
  22. BSD licensed
  23. ~~~~~~~~~~~~
  24. This software is made available under the
  25. link:license.html[revised BSD license].
  26. It is free and open source.
  27. Platforms
  28. ~~~~~~~~~
  29. The 'utstring' macros have been tested on:
  30. * Linux,
  31. * Windows, using Visual Studio 2008 and Visual Studio 2010
  32. Usage
  33. -----
  34. Declaration
  35. ~~~~~~~~~~~
  36. The dynamic string itself has the data type `UT_string`. It is declared like,
  37. UT_string *str;
  38. New and free
  39. ~~~~~~~~~~~~
  40. The next step is to create the string using `utstring_new`. Later when you're
  41. done with it, `utstring_free` will free it and all its content.
  42. Manipulation
  43. ~~~~~~~~~~~~
  44. The `utstring_printf` or `utstring_bincpy` operations insert (copy) data into
  45. the string. To concatenate one utstring to another, use `utstring_concat`. To
  46. clear the content of the string, use `utstring_clear`. The length of the string
  47. is available from `utstring_len`, and its content from `utstring_body`. This
  48. evaluates to a `char*`. The buffer it points to is always null-terminated.
  49. So, it can be used directly with external functions that expect a string.
  50. This automatic null terminator is not counted in the length of the string.
  51. Samples
  52. ~~~~~~~
  53. These examples show how to use utstring.
  54. .Sample 1
  55. -------------------------------------------------------------------------------
  56. #include <stdio.h>
  57. #include "utstring.h"
  58. int main() {
  59. UT_string *s;
  60. utstring_new(s);
  61. utstring_printf(s, "hello world!" );
  62. printf("%s\n", utstring_body(s));
  63. utstring_free(s);
  64. return 0;
  65. }
  66. -------------------------------------------------------------------------------
  67. The next example demonstrates that `utstring_printf` 'appends' to the string.
  68. It also shows concatenation.
  69. .Sample 2
  70. -------------------------------------------------------------------------------
  71. #include <stdio.h>
  72. #include "utstring.h"
  73. int main() {
  74. UT_string *s, *t;
  75. utstring_new(s);
  76. utstring_new(t);
  77. utstring_printf(s, "hello " );
  78. utstring_printf(s, "world " );
  79. utstring_printf(t, "hi " );
  80. utstring_printf(t, "there " );
  81. utstring_concat(s, t);
  82. printf("length: %u\n", utstring_len(s));
  83. printf("%s\n", utstring_body(s));
  84. utstring_free(s);
  85. utstring_free(t);
  86. return 0;
  87. }
  88. -------------------------------------------------------------------------------
  89. The next example shows how binary data can be inserted into the string. It also
  90. clears the string and prints new data into it.
  91. .Sample 3
  92. -------------------------------------------------------------------------------
  93. #include <stdio.h>
  94. #include "utstring.h"
  95. int main() {
  96. UT_string *s;
  97. char binary[] = "\xff\xff";
  98. utstring_new(s);
  99. utstring_bincpy(s, binary, sizeof(binary));
  100. printf("length is %u\n", utstring_len(s));
  101. utstring_clear(s);
  102. utstring_printf(s,"number %d", 10);
  103. printf("%s\n", utstring_body(s));
  104. utstring_free(s);
  105. return 0;
  106. }
  107. -------------------------------------------------------------------------------
  108. [[operations]]
  109. Reference
  110. ---------
  111. These are the utstring operations.
  112. Operations
  113. ~~~~~~~~~~
  114. [width="100%",cols="50<m,40<",grid="none",options="none"]
  115. |===============================================================================
  116. | utstring_new(s) | allocate a new utstring
  117. | utstring_renew(s) | allocate a new utstring (if s is `NULL`) otherwise clears it
  118. | utstring_free(s) | free an allocated utstring
  119. | utstring_init(s) | init a utstring (non-alloc)
  120. | utstring_done(s) | dispose of a utstring (non-alloc)
  121. | utstring_printf(s,fmt,...) | printf into a utstring (appends)
  122. | utstring_bincpy(s,bin,len) | insert binary data of length len (appends)
  123. | utstring_concat(dst,src) | concatenate src utstring to end of dst utstring
  124. | utstring_clear(s) | clear the content of s (setting its length to 0)
  125. | utstring_len(s) | obtain the length of s as an unsigned integer
  126. | utstring_body(s) | get `char*` to body of s (buffer is always null-terminated)
  127. | utstring_find(s,pos,str,len) | forward search from pos for a substring
  128. | utstring_findR(s,pos,str,len) | reverse search from pos for a substring
  129. |===============================================================================
  130. New/free vs. init/done
  131. ~~~~~~~~~~~~~~~~~~~~~~
  132. Use `utstring_new` and `utstring_free` to allocate a new string or free it. If
  133. the UT_string is statically allocated, use `utstring_init` and `utstring_done`
  134. to initialize or free its internal memory.
  135. Substring search
  136. ~~~~~~~~~~~~~~~~
  137. Use `utstring_find` and `utstring_findR` to search for a substring in a utstring.
  138. It comes in forward and reverse varieties. The reverse search scans from the end of
  139. the string backward. These take a position to start searching from, measured from 0
  140. (the start of the utstring). A negative position is counted from the end of
  141. the string, so, -1 is the last position. Note that in the reverse search, the
  142. initial position anchors to the 'end' of the substring being searched for;
  143. e.g., the 't' in 'cat'. The return value always refers to the offset where the
  144. substring 'starts' in the utstring. When no substring match is found, -1 is
  145. returned.
  146. For example if a utstring called `s` contains:
  147. ABC ABCDAB ABCDABCDABDE
  148. Then these forward and reverse substring searches for `ABC` produce these results:
  149. utstring_find( s, -9, "ABC", 3 ) = 15
  150. utstring_find( s, 3, "ABC", 3 ) = 4
  151. utstring_find( s, 16, "ABC", 3 ) = -1
  152. utstring_findR( s, -9, "ABC", 3 ) = 11
  153. utstring_findR( s, 12, "ABC", 3 ) = 4
  154. utstring_findR( s, 2, "ABC", 3 ) = 0
  155. "Multiple use" substring search
  156. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  157. The preceding examples show "single use" versions of substring matching, where
  158. the internal Knuth-Morris-Pratt (KMP) table is internally built and then freed
  159. after the search. If your program needs to run many searches for a given
  160. substring, it is more efficient to save the KMP table and reuse it.
  161. To reuse the KMP table, build it manually and then pass it into the internal
  162. search functions. The functions involved are:
  163. _utstring_BuildTable (build the KMP table for a forward search)
  164. _utstring_BuildTableR (build the KMP table for a reverse search)
  165. _utstring_find (forward search using a prebuilt KMP table)
  166. _utstring_findR (reverse search using a prebuilt KMP table)
  167. This is an example of building a forward KMP table for the substring "ABC", and
  168. then using it in a search:
  169. long *KPM_TABLE, offset;
  170. KPM_TABLE = (long *)malloc( sizeof(long) * (strlen("ABC")) + 1));
  171. _utstring_BuildTable("ABC", 3, KPM_TABLE);
  172. offset = _utstring_find(utstring_body(s), utstring_len(s), "ABC", 3, KPM_TABLE );
  173. free(KPM_TABLE);
  174. Note that the internal `_utstring_find` has the length of the UT_string as its
  175. second argument, rather than the start position. You can emulate the position
  176. parameter by adding to the string start address and subtracting from its length.
  177. Notes
  178. ~~~~~
  179. 1. To override the default out-of-memory handling behavior (which calls `exit(-1)`),
  180. override the `utstring_oom()` macro before including `utstring.h`.
  181. For example,
  182. #define utstring_oom() do { longjmp(error_handling_location); } while (0)
  183. ...
  184. #include "utstring.h"
  185. // vim: set nowrap syntax=asciidoc: