melder_str32.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #ifndef _melder_str32_h_
  2. #define _melder_str32_h_
  3. /* melder_str32.h
  4. *
  5. * Copyright (C) 1992-2018 Paul Boersma
  6. *
  7. * This code is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * This code is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. * See the GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. inline static integer str16len (conststring16 string) noexcept {
  21. const char16 *p = & string [0];
  22. while (*p != u'\0') ++ p;
  23. return p - string;
  24. }
  25. inline static mutablestring16 str16cpy (mutablestring16 target, conststring16 source) noexcept {
  26. char16 *p = & target [0];
  27. while (* source != u'\0') * p ++ = * source ++;
  28. *p = u'\0';
  29. return target;
  30. }
  31. inline static integer str32len (conststring32 string) noexcept {
  32. const char32 *p = & string [0];
  33. while (*p != U'\0') ++ p;
  34. return p - string;
  35. }
  36. inline static mutablestring32 str32cpy (mutablestring32 target, conststring32 source) noexcept {
  37. char32 *p = & target [0];
  38. while (* source != U'\0') * p ++ = * source ++;
  39. *p = U'\0';
  40. return target;
  41. }
  42. inline static mutablestring32 str32cat (mutablestring32 target, conststring32 source) noexcept {
  43. char32 *p = & target [0];
  44. while (*p != U'\0') ++ p;
  45. while (* source != U'\0') * p ++ = * source ++;
  46. *p = U'\0';
  47. return target;
  48. }
  49. inline static char32 * stp32cpy (mutablestring32 target, conststring32 source) noexcept {
  50. char32 *p = & target [0];
  51. while (* source != U'\0') * p ++ = * source ++;
  52. *p = U'\0';
  53. return p;
  54. }
  55. inline static mutablestring32 str32ncpy (mutablestring32 target, conststring32 source, integer n) noexcept {
  56. char32 *p = & target [0];
  57. for (; n > 0 && *source != U'\0'; -- n) * p ++ = * source ++;
  58. for (; n > 0; -- n) * p ++ = U'\0';
  59. return target;
  60. }
  61. inline static int str32cmp (conststring32 string1, conststring32 string2) noexcept {
  62. for (;; ++ string1, ++ string2) {
  63. int32 diff = (int32) *string1 - (int32) *string2;
  64. if (diff) return (int) diff;
  65. if (*string1 == U'\0') return 0;
  66. }
  67. }
  68. inline static int str32cmp_caseInsensitive (conststring32 string1, conststring32 string2) noexcept {
  69. for (;; ++ string1, ++ string2) {
  70. int32 diff = (int32) Melder_toLowerCase (*string1) - (int32) Melder_toLowerCase (*string2);
  71. if (diff) return (int) diff;
  72. if (*string1 == U'\0') return 0;
  73. }
  74. }
  75. inline static int str32cmp_optionallyCaseSensitive (conststring32 string1, conststring32 string2, bool caseSensitive) noexcept {
  76. return caseSensitive ? str32cmp (string1, string2) : str32cmp_caseInsensitive (string1, string2);
  77. }
  78. inline static int str32ncmp (conststring32 string1, conststring32 string2, integer n) noexcept {
  79. for (; n > 0; -- n, ++ string1, ++ string2) {
  80. int32 diff = (int32) *string1 - (int32) *string2;
  81. if (diff) return (int) diff;
  82. if (*string1 == U'\0') return 0;
  83. }
  84. return 0;
  85. }
  86. inline static int str32ncmp_caseInsensitive (conststring32 string1, conststring32 string2, integer n) noexcept {
  87. for (; n > 0; -- n, ++ string1, ++ string2) {
  88. int32 diff = (int32) Melder_toLowerCase (*string1) - (int32) Melder_toLowerCase (*string2);
  89. if (diff) return (int) diff;
  90. if (*string1 == U'\0') return 0;
  91. }
  92. return 0;
  93. }
  94. inline static int str32ncmp_optionallyCaseSensitive (conststring32 string1, conststring32 string2, integer n, bool caseSensitive) noexcept {
  95. return caseSensitive ? str32ncmp (string1, string2, n) : str32ncmp_caseInsensitive (string1, string2, n);
  96. }
  97. int Melder_cmp (conststring32 string1, conststring32 string2); // regards null string as empty string
  98. int Melder_cmp_caseInsensitive (conststring32 string1, conststring32 string2);
  99. int Melder_ncmp (conststring32 string1, conststring32 string2, integer n);
  100. int Melder_ncmp_caseInsensitive (conststring32 string1, conststring32 string2, integer n);
  101. #define str32equ ! str32cmp
  102. #define str32nequ ! str32ncmp
  103. #define Melder_equ ! Melder_cmp
  104. #define str32equ_caseInsensitive ! str32cmp_caseInsensitive
  105. #define str32nequ_caseInsensitive ! str32ncmp_caseInsensitive
  106. #define Melder_equ_caseInsensitive ! Melder_cmp_caseInsensitive
  107. #define str32equ_optionallyCaseSensitive ! str32cmp_optionallyCaseSensitive
  108. #define str32nequ_optionallyCaseSensitive ! str32ncmp_optionallyCaseSensitive
  109. bool Melder_equ_firstCharacterCaseInsensitive (conststring32 string1, conststring32 string2);
  110. #define Melder_nequ ! Melder_ncmp
  111. #define Melder_nequ_caseInsensitive ! Melder_ncmp_caseInsensitive
  112. inline static char32 * str32chr (conststring32 string, char32 kar) noexcept {
  113. for (; *string != kar; ++ string) {
  114. if (*string == U'\0')
  115. return nullptr;
  116. }
  117. return (char32 *) string;
  118. }
  119. inline static char32 * str32chr_caseInsensitive (conststring32 string, char32 kar) noexcept {
  120. kar = Melder_toLowerCase (kar);
  121. for (; Melder_toLowerCase (*string) != kar; ++ string) {
  122. if (*string == U'\0')
  123. return nullptr;
  124. }
  125. return (char32 *) string;
  126. }
  127. inline static char32 * str32rchr (conststring32 string, char32 kar) noexcept {
  128. char32 *result = nullptr;
  129. for (; *string != U'\0'; ++ string) {
  130. if (*string == kar) result = (char32 *) string;
  131. }
  132. return result;
  133. }
  134. inline static char32 * str32rchr_caseInsensitive (conststring32 string, char32 kar) noexcept {
  135. kar = Melder_toLowerCase (kar);
  136. char32 *result = nullptr;
  137. for (; *string != U'\0'; ++ string) {
  138. if (Melder_toLowerCase (*string) == kar) result = (char32 *) string;
  139. }
  140. return result;
  141. }
  142. inline static char32 * str32str (conststring32 string, conststring32 find) noexcept {
  143. integer length = str32len (find);
  144. if (length == 0) return (char32 *) string;
  145. char32 firstCharacter = * find ++; // optimization
  146. do {
  147. char32 kar;
  148. do {
  149. kar = * string ++;
  150. if (kar == U'\0') return nullptr;
  151. } while (kar != firstCharacter);
  152. } while (str32ncmp (string, find, length - 1));
  153. return (char32 *) (string - 1);
  154. }
  155. inline static char32 * str32str_caseInsensitive (conststring32 string, conststring32 find) noexcept {
  156. integer length = str32len (find);
  157. if (length == 0) return (char32 *) string;
  158. char32 firstCharacter = Melder_toLowerCase (* find ++); // optimization
  159. do {
  160. char32 kar;
  161. do {
  162. kar = Melder_toLowerCase (* string ++);
  163. if (kar == U'\0') return nullptr;
  164. } while (kar != firstCharacter);
  165. } while (str32ncmp_caseInsensitive (string, find, length - 1));
  166. return (char32 *) (string - 1);
  167. }
  168. inline static char32 * str32str_optionallyCaseSensitive (conststring32 string, conststring32 find, bool caseSensitive) noexcept {
  169. return caseSensitive ? str32str (string, find) : str32str_caseInsensitive (string, find);
  170. }
  171. inline static integer str32spn (conststring32 string1, conststring32 string2) noexcept {
  172. const char32 *p = & string1 [0];
  173. char32 kar1, kar2;
  174. cont:
  175. kar1 = * p ++;
  176. for (const char32 *q = & string2 [0]; (kar2 = * q ++) != U'\0';)
  177. if (kar2 == kar1)
  178. goto cont;
  179. return p - 1 - string1;
  180. }
  181. /* End of file melder_str32.h */
  182. #endif