streqvcmp.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /**
  2. * \file streqvcmp.c
  3. *
  4. * String Equivalence Comparison
  5. *
  6. * These routines allow any character to be mapped to any other
  7. * character before comparison. In processing long option names,
  8. * the characters "-", "_" and "^" all need to be equivalent
  9. * (because they are treated so by different development environments).
  10. *
  11. * @addtogroup autoopts
  12. * @{
  13. */
  14. /*
  15. * This file is part of AutoOpts, a companion to AutoGen.
  16. * AutoOpts is free software.
  17. * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved
  18. *
  19. * AutoOpts is available under any one of two licenses. The license
  20. * in use must be one of these two and the choice is under the control
  21. * of the user of the license.
  22. *
  23. * The GNU Lesser General Public License, version 3 or later
  24. * See the files "COPYING.lgplv3" and "COPYING.gplv3"
  25. *
  26. * The Modified Berkeley Software Distribution License
  27. * See the file "COPYING.mbsd"
  28. *
  29. * These files have the following sha256 sums:
  30. *
  31. * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
  32. * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
  33. * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
  34. *
  35. * This array is designed for mapping upper and lower case letter
  36. * together for a case independent comparison. The mappings are
  37. * based upon ascii character sequences.
  38. */
  39. static unsigned char charmap[] = {
  40. NUL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, '\a',
  41. '\b', '\t', NL, '\v', '\f', '\r', 0x0E, 0x0F,
  42. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  43. 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
  44. ' ', '!', '"', '#', '$', '%', '&', '\'',
  45. '(', ')', '*', '+', ',', '-', '.', '/',
  46. '0', '1', '2', '3', '4', '5', '6', '7',
  47. '8', '9', ':', ';', '<', '=', '>', '?',
  48. '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
  49. 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
  50. 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
  51. 'x', 'y', 'z', '[', '\\', ']', '^', '_',
  52. '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
  53. 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
  54. 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
  55. 'x', 'y', 'z', '{', '|', '}', '~', 0x7f,
  56. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  57. 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
  58. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  59. 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
  60. 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
  61. 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
  62. 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
  63. 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
  64. 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
  65. 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
  66. 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
  67. 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
  68. 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
  69. 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
  70. 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
  71. 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
  72. };
  73. /*=export_func strneqvcmp
  74. *
  75. * what: compare two strings with an equivalence mapping
  76. *
  77. * arg: + char const * + str1 + first string +
  78. * arg: + char const * + str2 + second string +
  79. * arg: + int + ct + compare length +
  80. *
  81. * ret_type: int
  82. * ret_desc: the difference between two differing characters
  83. *
  84. * doc:
  85. *
  86. * Using a character mapping, two strings are compared for "equivalence".
  87. * Each input character is mapped to a comparison character and the
  88. * mapped-to characters are compared for the two NUL terminated input strings.
  89. * The comparison is limited to @code{ct} bytes.
  90. * This function name is mapped to option_strneqvcmp so as to not conflict
  91. * with the POSIX name space.
  92. *
  93. * err: none checked. Caller responsible for seg faults.
  94. =*/
  95. int
  96. strneqvcmp(char const * s1, char const * s2, int ct)
  97. {
  98. for (; ct > 0; --ct) {
  99. unsigned char u1 = (unsigned char) *s1++;
  100. unsigned char u2 = (unsigned char) *s2++;
  101. int dif;
  102. if (u1 == u2) {
  103. if (u1 == NUL)
  104. return 0;
  105. continue;
  106. }
  107. dif = charmap[ u1 ] - charmap[ u2 ];
  108. if (dif != 0)
  109. return dif;
  110. if (u1 == NUL)
  111. return 0;
  112. }
  113. return 0;
  114. }
  115. /*=export_func streqvcmp
  116. *
  117. * what: compare two strings with an equivalence mapping
  118. *
  119. * arg: + char const * + str1 + first string +
  120. * arg: + char const * + str2 + second string +
  121. *
  122. * ret_type: int
  123. * ret_desc: the difference between two differing characters
  124. *
  125. * doc:
  126. *
  127. * Using a character mapping, two strings are compared for "equivalence".
  128. * Each input character is mapped to a comparison character and the
  129. * mapped-to characters are compared for the two NUL terminated input strings.
  130. * This function name is mapped to option_streqvcmp so as to not conflict
  131. * with the POSIX name space.
  132. *
  133. * err: none checked. Caller responsible for seg faults.
  134. =*/
  135. int
  136. streqvcmp(char const * s1, char const * s2)
  137. {
  138. for (;;) {
  139. unsigned char u1 = (unsigned char) *s1++;
  140. unsigned char u2 = (unsigned char) *s2++;
  141. int dif;
  142. if (u1 == u2) {
  143. if (u1 == NUL)
  144. return 0;
  145. continue;
  146. }
  147. dif = charmap[ u1 ] - charmap[ u2 ];
  148. if (dif != 0)
  149. return dif;
  150. if (u1 == NUL)
  151. return 0;
  152. }
  153. }
  154. /*=export_func streqvmap
  155. *
  156. * what: Set the character mappings for the streqv functions
  157. *
  158. * arg: + char + from + Input character +
  159. * arg: + char + to + Mapped-to character +
  160. * arg: + int + ct + compare length +
  161. *
  162. * doc:
  163. *
  164. * Set the character mapping. If the count (@code{ct}) is set to zero, then
  165. * the map is cleared by setting all entries in the map to their index
  166. * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}"
  167. * character. If @code{ct} is greater than 1, then @code{From} and @code{To}
  168. * are incremented and the process repeated until @code{ct} entries have been
  169. * set. For example,
  170. * @example
  171. * streqvmap('a', 'A', 26);
  172. * @end example
  173. * @noindent
  174. * will alter the mapping so that all English lower case letters
  175. * will map to upper case.
  176. *
  177. * This function name is mapped to option_streqvmap so as to not conflict
  178. * with the POSIX name space.
  179. *
  180. * err: none.
  181. =*/
  182. void
  183. streqvmap(char from, char to, int ct)
  184. {
  185. if (ct == 0) {
  186. ct = sizeof(charmap) - 1;
  187. do {
  188. charmap[ct] = (unsigned char)ct;
  189. } while (--ct >= 0);
  190. }
  191. else {
  192. unsigned int i_to = (int)to & 0xFF;
  193. unsigned int i_from = (int)from & 0xFF;
  194. do {
  195. charmap[i_from] = (unsigned char)i_to;
  196. i_from++;
  197. i_to++;
  198. if ((i_from >= sizeof(charmap)) || (i_to >= sizeof(charmap)))
  199. break;
  200. } while (--ct > 0);
  201. }
  202. }
  203. /*=export_func strequate
  204. *
  205. * what: map a list of characters to the same value
  206. *
  207. * arg: + char const * + ch_list + characters to equivalence +
  208. *
  209. * doc:
  210. *
  211. * Each character in the input string get mapped to the first character
  212. * in the string.
  213. * This function name is mapped to option_strequate so as to not conflict
  214. * with the POSIX name space.
  215. *
  216. * err: none.
  217. =*/
  218. void
  219. strequate(char const * s)
  220. {
  221. if ((s != NULL) && (*s != NUL)) {
  222. unsigned char equiv = (unsigned char)*s;
  223. while (*s != NUL)
  224. charmap[(unsigned char)*(s++)] = equiv;
  225. }
  226. }
  227. /*=export_func strtransform
  228. *
  229. * what: convert a string into its mapped-to value
  230. *
  231. * arg: + char * + dest + output string +
  232. * arg: + char const * + src + input string +
  233. *
  234. * doc:
  235. *
  236. * Each character in the input string is mapped and the mapped-to
  237. * character is put into the output.
  238. * This function name is mapped to option_strtransform so as to not conflict
  239. * with the POSIX name space.
  240. *
  241. * The source and destination may be the same.
  242. *
  243. * err: none.
  244. =*/
  245. void
  246. strtransform(char * d, char const * s)
  247. {
  248. do {
  249. *(d++) = (char)charmap[(unsigned char)*s];
  250. } while (*(s++) != NUL);
  251. }
  252. /** @}
  253. *
  254. * Local Variables:
  255. * mode: C
  256. * c-file-style: "stroustrup"
  257. * indent-tabs-mode: nil
  258. * End:
  259. * end of autoopts/streqvcmp.c */