ustr(3)

๐Ÿ“ฆ
version 1.0.4 ยท 2 versions
, in debian bookworm, ubuntu jammy, ubuntu noble

๐Ÿฆ‹ ustr(3) โ€” Ustr String Library, bestie ๐Ÿฆ‹

Okay so welcome to ustr(3), aka the Ustr String Library page. This part is the big roll call of functions, and every signature below is literally the lineup. No skipping, no โ€œtl;drโ€ โ€” the whole squad is here. ๐Ÿ’…

โœจ NAME โœจ

ustr โ€” ustr string library functions. Thatโ€™s the name, and itโ€™s giving โ€œuseful string library functionsโ€ in the most direct way possible. ๐ŸŽ€

โœจ SYNOPSIS โœจ

Hereโ€™s the whole guest list, exactly as written. Do not come for me about the line wraps โ€” theyโ€™re canon. ๐Ÿ˜ญ

  #include "ustr.h"

  struct Ustr *USTR(void *);
  struct Ustrp *USTRP(void *);
  struct Ustr *USTR1(symbol, const char[]);
  struct Ustr *USTR2(symbol, symbol, const char[]);
  struct Ustr *USTR4(symbol, symbol, symbol, symbol, const char[]);
  struct Ustr *USTR1_CHK(symbol, const char[]);
  struct Ustr *USTR2_CHK(symbol, symbol, const char[]);
  struct Ustr *USTR4_CHK(symbol, symbol, symbol, symbol, const char[]);
  struct Ustr *USTRP1(symbol, const char[]);
  struct Ustr *USTRP2(symbol, symbol, const char[]);
  struct Ustrp *USTRP4(symbol, symbol, symbol, symbol, const char[]);
  struct Ustr *USTRP1_CHK(symbol, const char[]);
  struct Ustr *USTRP2_CHK(symbol, symbol, const char[]);
  struct Ustrp *USTRP4_CHK(symbol, symbol, symbol, symbol, const char[]);

  size_t USTR_SIZE_FIXED(size_t);
  struct Ustr *ustr_init_fixed(void *, size_t, int, size_t);
  struct Ustr *USTR_SC_INIT_AUTO(char[], int, size_t);
  struct Ustr *USTR_SC_INIT_AUTO_OSTR(char[], int, size_t);

  int ustr_assert_valid(Ustr *);
  int ustr_assert_valid_subustr(Ustr *, size_t,  size_t);
  int USTR_CNTL_MALLOC_CHECK_BEG(int);
  int USTR_CNTL_MALLOC_CHECK_LVL(void);
  int USTR_CNTL_MALLOC_CHECK_MEM(void *);
  int USTR_CNTL_MALLOC_CHECK_MEM_SZ(void *, size_t);
  int USTR_CNTL_MALLOC_CHECK_MEM_MINSZ(void *, size_t);
  int USTR_CNTL_MALLOC_CHECK_MEM_USTR(Ustr *);
  int USTR_CNTL_MALLOC_CHECK_MEM_USTRP(Ustrp *);
  int USTR_CNTL_MALLOC_CHECK_END(void);
  int USTR_CNTL_MALLOC_CHECK_ADD(int);
  int USTR_CNTL_MALLOC_CHECK_DEL(int);

  size_t  ustr_init_size(size_t, size_t, int, size_t);
  struct Ustr *ustr_init_alloc(void *, size_t, size_t, size_t, int, int,
                               size_t);
  struct Ustr *ustr_dupx_empty(size_t, size_t, int, int);
  struct Ustr *ustr_dup_empty(void);
  struct Ustr *ustr_dupx_undef(size_t, size_t, int, int, size_t);
  struct Ustr *ustr_dup_undef(size_t);
  struct Ustr *ustr_dup(const struct Ustr *);
  struct Ustr *ustr_dupx(size_t, size_t, int, int, const struct Ustr *);
  struct Ustr *ustr_sc_dup(struct Ustr **);
  struct Ustr *ustr_sc_dupx(size_t, size_t, int, int, struct Ustr **);
  struct Ustr *ustr_dup_buf(const void *, size_t);
  struct Ustr *ustr_dupx_buf(size_t, size_t, int, int, const void *, size_t);
  struct Ustr *ustr_dup_cstr(const char *);
  struct Ustr *ustr_dupx_cstr(size_t, size_t, int, int, const char *);
  struct Ustr *USTR_DUP_OSTR(const char []);
  struct Ustr *USTR_DUP_OBJ(...);
  struct Ustr *ustr_dup_subustr(const struct Ustr *, size_t, size_t);
  struct Ustr *ustr_dupx_subustr(size_t, size_t, int, int, const struct Ustr *,
                                 size_t, size_t);
  struct Ustr *ustr_dup_rep_chr(char, size_t);
  struct Ustr *ustr_dupx_rep_chr(size_t, size_t, int, int, char, size_t);
  struct Ustr *ustr_sc_vjoin(const struct Ustr *, const struct Ustr *, const
                             struct Ustr *, va_list);
  struct Ustr *ustr_sc_join(const struct Ustr *, const struct Ustr *, const
                            struct Ustr *, ...);
  struct Ustr *ustr_sc_vjoinx(size_t, size_t, int, int, const struct Ustr *,
                              const struct Ustr *, const struct Ustr *,
                              va_list);
  struct Ustr *ustr_sc_joinx(size_t, size_t, int, int, const struct Ustr *,
                             const struct Ustr *, const struct Ustr *, ...);
  struct Ustr *ustr_sc_vconcat(const struct Ustr *, va_list);
  struct Ustr *ustr_sc_concat(const struct Ustr *, ...);
  struct Ustr *ustr_sc_vconcatx(size_t, size_t, int, int, const struct Ustr *,
                                va_list);
  struct Ustr *ustr_sc_concatx(size_t, size_t, int, int, const struct Ustr *,
                               ...);

  void  ustr_free(struct Ustr *);
  void  ustrp_free(struct Ustr_pool *, struct Ustrp *);
  void  ustr_sc_free(struct Ustr **);
  void  ustr_sc_free2(struct Ustr **, struct Ustr *);
  void  ustr_sc_free_shared(struct Ustr **);
  int  ustr_del(struct Ustr **, size_t);
  int  ustr_del_subustr(struct Ustr **, size_t,  size_t);
  void  ustr_sc_del(struct Ustr **);

  int ustr_add_undef(struct Ustr **, size_t);
  int ustr_add_buf(struct Ustr **, const void *, size_t);
  int  ustr_add_cstr(struct Ustr **, const char *);
  int  USTR_ADD_OSTR(struct Ustr **, const char []);
  int  USTR_ADD_OBJ(struct Ustr **, ...);
  int  ustr_add(struct Ustr **, const struct Ustr *);
  int  ustr_add_subustr(struct Ustr **, const struct Ustr *, size_t, size_t);
  int  ustr_add_rep_chr(struct Ustr **, char, size_t);

  int  ustr_set_undef(struct Ustr **,  size_t);
  int ustr_set_empty(struct Ustr **);
  int ustr_set_buf(struct Ustr **,  const void *, size_t);
  int ustr_set_cstr(struct Ustr **, const char *);
  int USTR_SET_OSTR(struct Ustr **, const char []);
  int USTR_SET_OBJ(struct Ustr **, ...);
  int ustr_set(struct Ustr **, const struct Ustr *);
  int ustr_set_subustr(struct Ustr **, const struct Ustr *, size_t, size_t);
  int ustr_set_rep_chr(struct Ustr **, char, size_t);

  int ustr_ins_undef(struct Ustr **, size_t, size_t);
  int ustr_ins_buf(struct Ustr **, size_t, const void *, size_t);
  int  ustr_ins_cstr(struct Ustr **, size_t, const char *);
  int  USTR_INS_OSTR(struct Ustr **, size_t, const char []);
  int  USTR_INS_OBJ(struct Ustr **, size_t, ...);
  int  ustr_ins(struct Ustr **, size_t, const struct Ustr *);
  int  ustr_ins_subustr(struct Ustr **, size_t, const struct Ustr *, size_t,
                        size_t);
  int  ustr_ins_rep_chr(struct Ustr **, size_t, char, size_t);

  int  ustr_add_vfmt_lim(struct Ustr **, size_t, const char *, va_list);
  int  ustr_add_vfmt(struct Ustr **, const char *, va_list);
  int  ustr_add_fmt_lim(struct Ustr **, size_t, const char *, ...);
  int  ustr_add_fmt(struct Ustr **, const char *, ...);
  struct Ustr *ustr_dup_vfmt_lim(size_t, const char *, va_list);
  struct Ustr *ustr_dup_vfmt(size_t, const char *, va_list);
  struct Ustr *ustr_dup_fmt_lim(size_t, const char *, ...);
  struct Ustr *ustr_dup_fmt(const char *, ...);
  struct Ustr *ustr_dupx_fmt_lim(size_t, size_t, int, int, size_t, const char
                                 *, ...);
  struct Ustr *ustr_dupx_fmt(size_t, size_t, int, int, const char *, ...);
  int  ustr_set_vfmt_lim(struct Ustr **, size_t, const char *, va_list);
  int  ustr_set_vfmt(struct Ustr **, const char *, va_list);
  int  ustr_set_fmt_lim(struct Ustr **, size_t, const char *, ...);
  int  ustr_set_fmt(struct Ustr **, const char *, ...);
  int  ustr_ins_vfmt_lim(struct Ustr **, size_t, size_t, const char *,
                         va_list);
  int  ustr_ins_vfmt(struct Ustr **, size_t, const char *, va_list);
  int  ustr_ins_fmt_lim(struct Ustr **, size_t, size_t, const char *, ...);
  int  ustr_ins_fmt(struct Ustr **, size_t, const char *, ...);
  int  ustr_sub_vfmt_lim(struct Ustr **, size_t, size_t, const char *,
                         va_list);
  int  ustr_sub_vfmt(struct Ustr **, size_t, const char *, va_list);
  int  ustr_sub_fmt_lim(struct Ustr **, size_t, size_t, const char *, ...);
  int  ustr_sub_fmt(struct Ustr **, size_t, const char *, ...);
  int  ustr_sc_sub_vfmt_lim(struct Ustr **, size_t, size_t, size_t, const char
                            *, va_list);
  int  ustr_sc_sub_vfmt(struct Ustr **, size_t, size_t, const char *, va_list);
  int  ustr_sc_sub_fmt_lim(struct Ustr **, size_t, size_t, size_t, const char
                           *, ...);
  int  ustr_sc_sub_fmt(struct Ustr **, size_t, size_t, const char *, ...);

  size_t  ustr_len(const struct Ustr *);
  const char *ustr_cstr(const struct Ustr *);
  char *ustr_wstr(struct Ustr *);
  int ustr_alloc(const struct Ustr *);
  int ustr_exact(const struct Ustr *);
  int  ustr_sized(const struct Ustr *);
  int ustr_ro(const struct Ustr *);
  int  ustr_fixed(const struct Ustr *);
  int  ustr_enomem(const struct Ustr *);
  int  ustr_shared(const struct Ustr *);
  int  ustr_limited(const struct Ustr *);
  int  ustr_owner(const struct Ustr *);
  size_t  ustr_size(const struct Ustr *);
  size_t  ustr_size_alloc(const struct Ustr *);
  size_t  ustr_size_overhead(const struct Ustr *);
  void  ustr_conf(const struct Ustr *, size_t *, size_t *, int *, size_t *,
                  size_t *);

  int  ustr_setf_enomem_err(struct Ustr *);
  int  ustr_setf_enomem_clr(struct Ustr *);
  int  ustr_setf_share(struct Ustr *);
  int  ustr_setf_owner(struct Ustr *);

  int  ustr_cmp_buf(const struct Ustr *, const void *, size_t);
  int  ustr_cmp(const struct Ustr *, const struct Ustr *);
  int  ustr_cmp_subustr(const struct Ustr *, const struct Ustr *, size_t,
                        size_t);
  int  ustr_cmp_cstr(const struct Ustr *, const char *);
  int  ustr_cmp_fast_buf(const struct Ustr *, const void *, size_t);
  int  ustr_cmp_fast(const struct Ustr *, const struct Ustr *);
  int  ustr_cmp_fast_subustr(const struct Ustr *, const struct Ustr *, size_t,
                             size_t);
  int  ustr_cmp_fast_cstr(const struct Ustr *, const char *);
  int  ustr_cmp_case_buf(const struct Ustr *, const void *, size_t);
  int  ustr_cmp_case(const struct Ustr *, const struct Ustr *);
  int  ustr_cmp_case_subustr(const struct Ustr *, const struct Ustr *, size_t,
                             size_t);
  int  ustr_cmp_case_cstr(const struct Ustr *, const char *);
  int  ustr_cmp_eq(const struct Ustr *, const struct Ustr *);
  int  ustr_cmp_buf_eq(const struct Ustr *, const void *, size_t);
  int  ustr_cmp_subustr_eq(const struct Ustr *, const struct Ustr *, size_t,
                           size_t);
  int  ustr_cmp_cstr_eq(const struct Ustr *, const char *);
  int  ustr_cmp_case_eq(const struct Ustr *, const struct Ustr *);
  int  ustr_cmp_case_buf_eq(const struct Ustr *, const void *, size_t);
  int  ustr_cmp_case_subustr_eq(const struct Ustr *, const struct Ustr *,
                                size_t, size_t);
  int  ustr_cmp_case_cstr_eq(const struct Ustr *, const char *);
  int  ustr_cmp_prefix_eq(const struct Ustr *, const struct Ustr *);
  int  ustr_cmp_prefix_buf_eq(const struct Ustr *, const void *, size_t);
  int  ustr_cmp_prefix_cstr_eq(const struct Ustr *, const char *);
  int  ustr_cmp_prefix_subustr_eq(const struct Ustr *, const struct Ustr *,
                                  size_t, size_t);
  int  ustr_cmp_case_prefix_eq(const struct Ustr *, const struct Ustr *);
  int  ustr_cmp_case_prefix_buf_eq(const struct Ustr *, const void *, size_t);
  int  ustr_cmp_case_prefix_cstr_eq(const struct Ustr *, const char *);
  int  ustr_cmp_case_prefix_subustr_eq(const struct Ustr *, const struct Ustr
                                       *, size_t, size_t);
  int  ustr_cmp_suffix_eq(const struct Ustr *, const struct Ustr *);
  int  ustr_cmp_suffix_buf_eq(const struct Ustr *, const void *, size_t);
  int  ustr_cmp_suffix_cstr_eq(const struct Ustr *, const char *);
  int  ustr_cmp_suffix_subustr_eq(const struct Ustr *, const struct Ustr *,
                                  size_t, size_t);
  int  ustr_cmp_case_suffix_eq(const struct Ustr *, const struct Ustr *);
  int  ustr_cmp_case_suffix_buf_eq(const struct Ustr *, const void *, size_t);
  int  ustr_cmp_case_suffix_cstr_eq(const struct Ustr *, const char *);
  int  ustr_cmp_case_suffix_subustr_eq(const struct Ustr *, const struct Ustr
                                       *, size_t, size_t);
  size_t  ustr_srch_chr_fwd(const struct Ustr *, size_t, char);
  size_t  ustr_srch_chr_rev(const struct Ustr *, size_t, char);
  size_t  ustr_srch_buf_fwd(const struct Ustr *, size_t, const void *, size_t);
  size_t  ustr_srch_buf_rev(const struct Ustr *, size_t, const void *, size_t);
  size_t  ustr_srch_fwd(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_srch_rev(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_srch_cstr_fwd(const struct Ustr *, size_t, const char *);
  size_t  ustr_srch_cstr_rev(const struct Ustr *, size_t, const char *);
  size_t  ustr_srch_subustr_fwd(const struct Ustr *, size_t, const struct Ustr
                                *, size_t, size_t);
  size_t  ustr_srch_subustr_rev(const struct Ustr *,  size_t, const struct Ustr
                                *, size_t, size_t);
  size_t  ustr_srch_case_chr_fwd(const struct Ustr *, size_t, char);
  size_t  ustr_srch_case_chr_rev(const struct Ustr *, size_t, char);
  size_t  ustr_srch_case_buf_fwd(const struct Ustr *, size_t, const void *,
                                 size_t);
  size_t  ustr_srch_case_buf_rev(const struct Ustr *, size_t, const void *,
                                 size_t);
  size_t  ustr_srch_case_fwd(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_srch_case_rev(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_srch_case_cstr_fwd(const struct Ustr *, size_t, const char *);
  size_t  ustr_srch_case_cstr_rev(const struct Ustr *, size_t, const char *);
  size_t  ustr_srch_case_subustr_fwd(const struct Ustr *, size_t, const struct
                                     Ustr *, size_t, size_t);
  size_t  ustr_srch_case_subustr_rev(const struct Ustr *,  size_t, const struct
                                     Ustr *, size_t, size_t);

  size_t  ustr_spn_chr_fwd(const struct Ustr *, size_t, char);
  size_t  ustr_spn_chr_rev(const struct Ustr *, size_t, char);
  size_t  ustr_spn_chrs_fwd(const struct Ustr *, size_t, const char *, size_t);
  size_t  ustr_spn_chrs_rev(const struct Ustr *, size_t, const char *, size_t);
  size_t  ustr_spn_fwd(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_spn_rev(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_spn_cstr_fwd(const struct Ustr *, size_t, const char *);
  size_t  ustr_spn_cstr_rev(const struct Ustr *, size_t, const char *);
  size_t  ustr_cspn_chr_fwd(const struct Ustr *, size_t, char);
  size_t  ustr_cspn_chr_rev(const struct Ustr *, size_t, char);
  size_t  ustr_cspn_chrs_fwd(const struct Ustr *, size_t, const char *,
                             size_t);
  size_t  ustr_cspn_chrs_rev(const struct Ustr *, size_t, const char *,
                             size_t);
  size_t  ustr_cspn_fwd(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_cspn_rev(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_cspn_cstr_fwd(const struct Ustr *, size_t, const char *);
  size_t  ustr_cspn_cstr_rev(const struct Ustr *, size_t, const char *);
  size_t  ustr_utf8_spn_chrs_fwd(const struct Ustr *, size_t, const char *,
                                 size_t);
  size_t  ustr_utf8_spn_chrs_rev(const struct Ustr *, size_t, const char *,
                                 size_t);
  size_t  ustr_utf8_spn_fwd(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_utf8_spn_rev(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_utf8_spn_cstr_fwd(const struct Ustr *, size_t, const char *);
  size_t  ustr_utf8_spn_cstr_rev(const struct Ustr *, size_t, const char *);
  size_t  ustr_utf8_cspn_chrs_fwd(const struct Ustr *, size_t, const char *,
                                  size_t);
  size_t  ustr_utf8_cspn_chrs_rev(const struct Ustr *, size_t, const char *,
                                  size_t);
  size_t  ustr_utf8_cspn_fwd(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_utf8_cspn_rev(const struct Ustr *, size_t, const struct Ustr *);
  size_t  ustr_utf8_cspn_cstr_fwd(const struct Ustr *, size_t, const char *);
  size_t  ustr_utf8_cspn_cstr_rev(const struct Ustr *, size_t, const char *);

  int  ustr_io_get(struct Ustr **, FILE *, size_t, size_t *);
  int  ustr_io_getfile(struct Ustr **, FILE *);
  int  ustr_io_getfilename(struct Ustr **, const char *);
  int  ustr_io_getdelim(struct Ustr **, FILE *, char);
  int  ustr_io_getline(struct Ustr **, FILE *);
  int ustr_io_put(struct Ustr **, FILE *, size_t);
  int  ustr_io_putline(struct Ustr **, FILE *, size_t);
  int  ustr_io_putfile(struct Ustr **, FILE *);
  int  ustr_io_putfileline(struct Ustr **, FILE *);
  int  ustr_io_putfilename(struct Ustr **, const char *, const char *);

  int  ustr_sub_undef(struct Ustr **, size_t, size_t);
  int  ustr_sub_buf(struct Ustr **, size_t, const void *, size_t);
  int  ustr_sub_cstr(struct Ustr **, size_t, const char *);
  int  USTR_SUB_OSTR(struct Ustr **, size_t, const char []);
  int  USTR_SUB_OBJ(struct Ustr **, size_t, ...);
  int  ustr_sub(struct Ustr **, size_t, const struct Ustr *);
  int  ustr_sub_subustr(struct Ustr **, size_t, const struct Ustr *, size_t,
                        size_t);
  int  ustr_sc_sub_undef(struct Ustr **, size_t, size_t, size_t);
  int  ustr_sc_sub_buf(struct Ustr **, size_t , size_t , const void *, size_t
                       );
  int  ustr_sc_sub_cstr(struct Ustr **, size_t, size_t, const char *);
  int  ustr_sc_sub(struct Ustr **, size_t, size_t, const struct Ustr *);
  int  ustr_sc_sub_subustr(struct Ustr **, size_t, size_t, const struct Ustr *,
                           size_t, size_t);
  int  USTR_SC_SUB_OSTR(struct Ustr **, size_t, size_t, const char []);
  int  USTR_SC_SUB_OBJ(struct Ustr **, size_t, size_t, ...);
  size_t  ustr_replace_buf(struct Ustr **, const void *, size_t, const void *,
                           size_t, size_t);
  size_t  ustr_replace_cstr(struct Ustr **, const char *, const char *,
                            size_t);
  int  ustr_replace(struct Ustr **, const struct Ustr *, const struct Ustr *,
                    size_t);
  size_t ustr_replace_rep_chr(struct Ustr **ps1, char, size_t, char, size_t
                              nlen, size_t lim);

  struct Ustr *ustr_split_buf(const struct Ustr *, size_t *, const void *,
                              size_t, struct Ustr *, unsigned int);
  struct Ustr *ustr_split(const struct Ustr *, size_t *, const struct Ustr *,
                          struct Ustr *, unsigned int);
  struct Ustr *ustr_split_cstr(const struct Ustr *, size_t *, const char *,
                               struct Ustr *, unsigned int);
  struct Ustr *ustr_split_spn_chrs(const struct Ustr *, size_t *, const char *,
                                   size_t, struct Ustr *, unsigned int);
  struct Ustr *ustr_split_spn_cstr(const struct Ustr *, size_t *, const char *,
                                   struct Ustr *, unsigned int);
  struct Ustr *ustr_split_spn(const struct Ustr *, size_t *, const struct Ustr
                              *, struct Ustr *, unsigned int);

  int  ustr_utf8_valid(const struct Ustr *);
  size_t  ustr_utf8_len(const struct Ustr *);
  ssize_t  ustr_utf8_width(const struct Ustr *);
  size_t  ustr_utf8_chars2bytes(const struct Ustr *, size_t, size_t, size_t *);
  size_t  ustr_utf8_bytes2chars(const struct Ustr *, size_t, size_t, size_t *);
  int ustr_sc_utf8_reverse(struct Ustr **);

  uintmax_t  ustr_parse_uintmaxx(const struct Ustr *, size_t, unsigned int,
                                 uintmax_t, uintmax_t, const char *, size_t *,
                                 unsigned int *);
  uintmax_t  ustr_parse_uintmax(const struct Ustr *, size_t, unsigned int,
                                size_t *, unsigned int *);
  intmax_t  ustr_parse_intmax(const struct Ustr *, size_t, unsigned int, size_t
                              *, unsigned int *);
  unsigned long  ustr_parse_ulongx(const struct Ustr *,  size_t,  unsigned int,
                                   unsigned long,  unsigned long, const char *,
                                   size_t *, unsigned int *);
  unsigned long  ustr_parse_ulong(const struct Ustr *, size_t, unsigned int,
                                  size_t *, unsigned int *);
  long  ustr_parse_long(const struct Ustr *, size_t, unsigned int, size_t *,
                        unsigned int *);
  unsigned int  ustr_parse_uint(const struct Ustr *, size_t, unsigned int,
                                size_t *, unsigned int *);
  int  ustr_parse_int(const struct Ustr *, size_t, unsigned int, size_t *,
                      unsigned int *);
  unsigned short  ustr_parse_ushort(const struct Ustr *, size_t, unsigned int,
                                    size_t *, unsigned int *);
  short  ustr_parse_short(const struct Ustr *, size_t, unsigned int, size_t *,
                          unsigned int *);

  int  ustr_sc_ensure_owner(struct Ustr **);
  char *ustr_sc_wstr(struct Ustr **);
  char *ustr_sc_export_subustr(const struct Ustr *, size_t, size_t, void
                               *(*)(size_t));
  char *ustr_sc_export(const struct Ustr *, void *(*)(size_t));
  char *ustrp_sc_export_subustrp(struct Ustr_pool *, const struct Ustr *,
                                 size_t, size_t, void *(*)(size_t));
  char *ustrp_sc_export(struct Ustr_pool *, const struct Ustr *, void
                        *(*)(size_t));
  int  ustr_sc_reverse(struct Ustr **);
  int  ustr_sc_tolower(struct Ustr **);
  int  ustr_sc_toupper(struct Ustr **);
  int  ustr_sc_ltrim_chrs(struct Ustr **, const char *, size_t);
  int  ustr_sc_ltrim(struct Ustr **, const struct Ustr *);
  int  ustr_sc_ltrim_cstr(struct Ustr **, const char *);
  int  ustr_sc_rtrim_chrs(struct Ustr **, const char *, size_t);
  int  ustr_sc_rtrim(struct Ustr **, const struct Ustr *);
  int  ustr_sc_rtrim_cstr(struct Ustr **, const char *);
  int  ustr_sc_trim_chrs(struct Ustr **, const char *, size_t);
  int  ustr_sc_trim(struct Ustr **, const struct Ustr *);
  int  ustr_sc_trim_cstr(struct Ustr **, const char *);

  int  ustr_add_b_uint16(struct Ustr **, uint_least16_t);
  int  ustr_add_b_uint32(struct Ustr **, uint_least32_t);
  int  ustr_add_b_uint64(struct Ustr **, uint_least64_t);

  uint_least16_t  ustr_parse_b_uint16(const struct Ustr *, size_t);
  uint_least32_t  ustr_parse_b_uint32(const struct Ustr *, size_t);
  uint_least64_t  ustr_parse_b_uint64(const struct Ustr *, size_t);

  int ustr_realloc(struct Ustr **, size_t);
  int  ustr_cntl_opt(int, ...);

  struct Ustr_pool *ustr_pool_ll_make(void);
  struct Ustr_pool *ustr_pool_make_subpool(struct Ustr_pool *);
  void ustr_pool_free(struct Ustr_pool *);
  void ustr_pool_clear(struct Ustr_pool *);

๐Ÿ’– DESCRIPTION ๐Ÿ’–

okay so here's the super-simple overview, bestie: you can use ustr_dup_cstr() to convert a C-style string into a Ustr, and ustr_cstr() to convert it right back. You can also use USTR1() to create constant/read-only strings, and USTR_SC_INIT_AUTO() to create strings that use stack space up to a certain amount. โœจ

The way this library gets used is kind of its own thing ngl: by default, it has an average overhead of only 55% over strdup(), for strings in the range of 0 to 20 bytes. Or, to put it another way, it only uses 8 bytes to store a 2 byte string where strdup() uses 3. ๐Ÿ’…

๐Ÿฆ‹ Creating read-only Ustr functions ๐Ÿฆ‹

okay bestie, this whole batch is about making Ustr strings that live in read-only memory โ€” like, they're literally just constant data with a tiny header vibe. no allocation, no drama ๐Ÿ’…


USTR()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Pointer to Ustr data
  • Type[1]: void *

Explanation: this macro function is normally used with the empty string "". ๐ŸŽ€

Note: there is basically just a simple cast behind the macro. that's it, that's the whole tea โ˜•


USTRP()

  • Returns: Ustrp string
  • Type: struct Ustrp *
  • Parameter[1]: Pointer to Ustrp data
  • Type[1]: void *

Explanation: this macro function is normally used with the empty string "". same energy as USTR(), just the Ustrp flavor โœจ

Note: there is basically just a simple cast behind the macro. again. iconic of it honestly.


USTR1()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Data for Ustr string
  • Type[2]: const char[]

Explanation: this macro function simplifies the creation of read-only Ustr string's. and it's normally used like...

USTR1(\x4, "abcd")

...it is worth pointing out that running with debugging turned on (USTR_CONF_USE_ASSERT) will complain if the length isn't encoded correctly, as in...

USTR1(\x3, "abcd")

...here ustr_assert_valid() will fail, which is called before most functions do anything in debugging mode. note also that extra debugging (USTR_CONF_USE_EOS_MARK) will still catch cases like...

USTR1(\x3, "abc\0d")

...at least using debugging is esp. important if you are putting UTF-8 characters into the strings. ๐Ÿงš

Note: having ustr_ro() return true means that the Ustr cannot be written to without be reallocated into allocation space ... not that ustr_add() etc. will fail. ๐Ÿ”ฅ

there is now USTR1_CHK() which performs a compile time check so you can never have an invalid ustr. we love a safety net bestie ๐Ÿซถ


USTR2()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded 2nd byte of number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Encoded 1st byte of number of the length of Ustr string
  • Type[2]: symbol
  • Parameter[3]: Data for Ustr string
  • Type[3]: const char[]

Explanation: this function works in the same way as USTR1() but takes two length bytes, so the read-only string can be up to 65,535 (2**16 - 1) bytes in length. big string energy ๐Ÿ’–


USTR4()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded 4th byte of number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Encoded 3rd byte of number of the length of Ustr string
  • Type[2]: symbol
  • Parameter[3]: Encoded 2nd byte of number of the length of Ustr string
  • Type[3]: symbol
  • Parameter[4]: Encoded 1st byte of number of the length of Ustr string
  • Type[4]: symbol
  • Parameter[5]: Data for Ustr string
  • Type[5]: const char[]

Explanation: this function works in the same way as USTR1() but takes four length bytes, so the read-only string can be up to 2**32 - 1 bytes in length. absolute unit of a string, no cap ๐Ÿ˜ญ


USTR1_CHK()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Data for Ustr string
  • Type[2]: const char[]

Explanation: this function works in the same way as USTR1() but it does a check against the length of (Parameter[2]) using sizeof() - 1. ๐ŸŽ€

Note: if the check fails the returned Ustr * will be "", so you can check ustr_len() to see if you screwed something up. bestie check your work fr ๐Ÿ’€


USTR2_CHK()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded 2nd byte of number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Encoded 1st byte of number of the length of Ustr string
  • Type[2]: symbol
  • Parameter[3]: Data for Ustr string
  • Type[3]: const char[]

Explanation: this function works in the same way as USTR2() but it does a check against the length of (Parameter[2]) using sizeof() - 1. ๐ŸŒธ

Note: if the check fails the returned Ustr * will be "". yep, empty string, that's the tell ๐Ÿซถ


USTR4_CHK()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded 4th byte of number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Encoded 3rd byte of number of the length of Ustr string
  • Type[2]: symbol
  • Parameter[3]: Encoded 2nd byte of number of the length of Ustr string
  • Type[3]: symbol
  • Parameter[4]: Encoded 1st byte of number of the length of Ustr string
  • Type[4]: symbol
  • Parameter[5]: Data for Ustr string
  • Type[5]: const char[]

Explanation: this function works in the same way as USTR4() but it does a check against the length of (Parameter[2]) using sizeof() - 1. ๐Ÿ’œ

Note: if the check fails the returned Ustr * will be "". same deal as the others, check ustr_len() and go "oh" ๐Ÿ˜ญ


USTRP1()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Data for Ustr string
  • Type[2]: const char[]

Explanation: this function works like USTR1(), but returns a Ustrp instead. โœจ


USTRP2()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded 2nd byte of number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Encoded 1st byte of number of the length of Ustr string
  • Type[2]: symbol
  • Parameter[3]: Data for Ustr string
  • Type[3]: const char[]

Explanation: this function works like USTR4(), but returns a Ustrp instead. (yes, that's what the page says โ€” we're just relaying the vibes verbatim ๐ŸŽ€)


USTRP4()

  • Returns: Ustrp string
  • Type: struct Ustrp *
  • Parameter[1]: Encoded 4th byte of number of the length of Ustrp string
  • Type[1]: symbol
  • Parameter[2]: Encoded 3rd byte of number of the length of Ustrp string
  • Type[2]: symbol
  • Parameter[3]: Encoded 2nd byte of number of the length of Ustrp string
  • Type[3]: symbol
  • Parameter[4]: Encoded 1st byte of number of the length of Ustrp string
  • Type[4]: symbol
  • Parameter[5]: Data for Ustr string
  • Type[5]: const char[]

Explanation: this function works like USTR2(), but returns a Ustrp instead. ๐Ÿ’…


USTRP1_CHK()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Data for Ustr string
  • Type[2]: const char[]

Explanation: this function works like USTR1_CHK(), but returns a Ustrp instead. ๐Ÿ”ฅ


USTRP2_CHK()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Encoded 2nd byte of number of the length of Ustr string
  • Type[1]: symbol
  • Parameter[2]: Encoded 1st byte of number of the length of Ustr string
  • Type[2]: symbol
  • Parameter[3]: Data for Ustr string
  • Type[3]: const char[]

Explanation: this function works like USTR4_CHK(), but returns a Ustrp instead. ๐Ÿฆ‹


USTRP4_CHK()

  • Returns: Ustrp string
  • Type: struct Ustrp *
  • Parameter[1]: Encoded 4th byte of number of the length of Ustrp string
  • Type[1]: symbol
  • Parameter[2]: Encoded 3rd byte of number of the length of Ustrp string
  • Type[2]: symbol
  • Parameter[3]: Encoded 2nd byte of number of the length of Ustrp string
  • Type[3]: symbol
  • Parameter[4]: Encoded 1st byte of number of the length of Ustrp string
  • Type[4]: symbol
  • Parameter[5]: Data for Ustr string
  • Type[5]: const char[]

Explanation: this function works like USTR2_CHK(), but returns a Ustrp instead. ๐Ÿ’–


๐ŸŒˆ Creating fixed Ustr functions ๐ŸŒˆ

okay so now we're in the fixed-size era โ€” where you bring the memory and Ustr just moves in and decorates ๐ŸŽ€


USTR_SIZE_FIXED()

  • Returns: Size of area of memory
  • Type: size_t
  • Parameter[1]: Size of area of memory
  • Type[1]: size_t

Explanation: this macro function is replaced by a static conversion from the max length desired (Parameter[1]) to the storage size needed. in other words it works out what ustr_size_overhead() will be, and adds that value. ๐Ÿงฎ

Note: this is useful is you want a small fixed size allocation, as you can declare it like so:

char buf[USTR_SIZE_FIXED(4)];

...to give you exactly 4 bytes as a maximum, this is esp. useful if you want a limited (ustr_limited() == USTR_TRUE) Ustr string. periodt ๐Ÿ’…


ustr_init_fixed()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Pointer to area of memory to use as a Ustr string
  • Type[1]: void *
  • Parameter[2]: Size of area of memory
  • Type[2]: size_t
  • Parameter[3]: Whether the fixed size Ustr should be limited
  • Type[3]: int
  • Parameter[4]: The initial length of the Ustr
  • Type[4]: size_t

Explanation: this creates a new Ustr string, which is "fixed". this means the Ustr storage is managed outside of the ustr_* API, it is often used for stack allocated strings. ๐Ÿซถ

as you add data to the Ustr past the size allowed via. the fixed storge the Ustr will automatically be converted into an allocated Ustr. so if this is possible you should always call ustr_free(), as this does nothing if given a fixed size Ustr. (yes โ€” the glow-up into allocated memory is real, and yes, you should still call ustr_free() just in case ๐Ÿ˜Œ)

Note: for simplicity you probably want to use USTR_SC_INIT_AUTO() or USTR_SC_INIT_AUTO() when possible. (that's literally what the page says, both of them, same name twice โ€” we don't gatekeep, we report ๐Ÿ“‹)


USTR_SC_INIT_AUTO()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Area of memory to use as a Ustr string
  • Type[1]: char[]
  • Parameter[2]: Whether the fixed size Ustr should be limited
  • Type[2]: int
  • Parameter[3]: The initial length of the Ustr
  • Type[3]: size_t

Explanation: this calls ustr_init_fixed() with sizeof() the area of memory (Parameter[1]) as the second argument. โœจ

Note: this does mean that the first argument must be the correct size, as far as sizeof() is concerned, as in...

char buf_sz[1024];
Ustr *s1 = USTR_SC_INIT_AUTO(buf_sz, USTR_FALSE, 0);

...so passing pointers to memory from malloc() will probably just return NULL. ๐Ÿ™ˆ like, sizeof() can't see through a pointer bestie, it's doing its best.


USTR_SC_INIT_AUTO_OSTR()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Area of memory to use as a Ustr string
  • Type[1]: char[]
  • Parameter[2]: Whether the fixed size Ustr should be limited
  • Type[2]: int
  • Parameter[3]: The initial string in the buffer, as a constant string
  • Type[3]: size_t

Explanation: this calls ustr_init_fixed() with sizeof() the area of memory (Parameter[1]) as the second argument, given as an "object string". ๐ŸŒธ

Note: this does mean that the first argument must be the correct size, as far as sizeof() is concerned, as in...

char buf_sz[1024] = USTR_BEG_FIXED2 "abcd";
Ustr *s1 = USTR_SC_INIT_AUTO_OSTR(buf_sz, USTR_FALSE, "abcd");

...so passing pointers to memory from malloc() will probably just return NULL. same rule as before, the sizeof() vibe check does not pass for pointers, sorry bestie ๐Ÿ’€

๐Ÿซถ Debugging functions ๐Ÿซถ

Okay bestie, this is the "wait, is my Ustr actually okay?" toolbox. Use it when things smell weird.


ustr_assert_valid()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a Ustr string โ€” Type[1]: Ustr *

This one runs a few internal consistency checks and is literally there to help you catch it when a Ustr has gone invalid. Little vibe check for your string ๐Ÿ’…

Note: it calls ustr_assert_ret(), so even when USTR_DEBUG is off the checks still get performed and the result still comes back to you. No sneaky silent skipping โœจ

ustr_assert_valid_subustr()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a Ustr string โ€” Type[1]: Ustr *
  • Parameter[2]: Position in the Ustr โ€” Type[2]: size_t
  • Parameter[3]: Length to delete from the Ustr โ€” Type[3]: size_t

Calls ustr_assert_valid() and also checks that the position and length actually sit inside the Ustr. Not valid? You get 0. Valid? You get ustr_len(). That's the whole deal ๐ŸŽ€


USTR_CNTL_MALLOC_CHECK_BEG()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Condition for begin malloc checking or not โ€” Type[1]: int

Starts malloc checking, meaning every ustr allocation goes through the malloc check routines. But heads up: it fails if the condition check (Parameter[1]) fails. ๐Ÿ™ˆ

Note: turning malloc checking on after one or more allocations have already happened will give you false failures โ€” unless you truly, genuinely know what you're doing. Like, iykyk. You can also auto-turn it on by giving the USTR_CNTL_MC environment variable the value of "1", "yes" or "on".

USTR_CNTL_MALLOC_CHECK_LVL()

  • Returns: Level of current malloc check
  • Type: int
  • Parameter[1]: Nothing โ€” Type[1]: void

Returns the current "level" of the malloc check โ€” 0 means malloc check isn't enabled at all. The level goes up by one every time USTR_CNTL_MALLOC_CHECK_BEG() or USTR_CNTL_MALLOC_CHECK_ADD() returns success, and goes down by one every time USTR_CNTL_MALLOC_CHECK_DEL() or USTR_CNTL_MALLOC_CHECK_END() returns success. Nesting slay ๐Ÿงš


USTR_CNTL_MALLOC_CHECK_MEM()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer returned from malloc check โ€” Type[1]: void *

Asserts that the pointer (Parameter[1]) was allocated from malloc checking. That's it.

Note: unless you're doing something special, or you're using a builtin Ustr_pool, it is very likely you just want to call USTR_CNTL_MALLOC_CHECK_MEM_USTR() instead. Fr fr, save yourself the trouble ๐Ÿ’€

USTR_CNTL_MALLOC_CHECK_MEM_SZ()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer returned from malloc check โ€” Type[1]: void *
  • Parameter[2]: Length of allocated memory โ€” Type[2]: size_t

Asserts the pointer (Parameter[1]) was allocated from malloc checking and that it has the specified size (Parameter[2]). Exact match energy ๐Ÿ‘‘

Note: unless you're doing something special, or you're using a builtin Ustr_pool, you very likely want to just call USTR_CNTL_MALLOC_CHECK_MEM_USTR().

USTR_CNTL_MALLOC_CHECK_MEM_MINSZ()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer returned from malloc check โ€” Type[1]: void *
  • Parameter[2]: Length of allocated memory โ€” Type[2]: size_t

Same situation, but chiller: asserts the pointer (Parameter[1]) was allocated from malloc checking and has at least the specified size (Parameter[2]). Minimum, not exact ๐ŸŒธ

Note: unless you're doing something special, or you're using a builtin Ustr_pool, it's very likely you just want USTR_CNTL_MALLOC_CHECK_MEM_USTR().

USTR_CNTL_MALLOC_CHECK_MEM_USTR()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a Ustr string โ€” Type[1]: Ustr *

Asserts that the pointer (Parameter[1]) is a Ustr allocated from malloc checking. But if the Ustr isn't allocated at all? It returns TRUE โ€” no drama, babe ๐Ÿฆ‹

Note: because of the layering between the Ustr code and the pool code, there's a trap: if you allocate an implicitly sized Ustrp from a pool and then delete some data from it (which fails), the Ustr layer will think it has an implicit less than the actual size โ€” so this function will fail. That's literally what USTR_CNTL_MALLOC_CHECK_MEM_USTRP() exists for. Not me being dramatic, it's just the architecture ๐Ÿ˜ญ

USTR_CNTL_MALLOC_CHECK_MEM_USTRP()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a Ustrp string โ€” Type[1]: Ustrp *

Asserts the pointer (Parameter[1]) is a Ustr allocated from a builtin pool using malloc checking. And again, if the Ustr isn't allocated, it returns TRUE. We love a forgiving queen ๐Ÿ’–


USTR_CNTL_MALLOC_CHECK_END()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Nothing โ€” Type[1]: void

This macro cleans up any memory used by malloc check and asserts that no memory is left allocated. The grand finale cleanup ๐ŸŽ€

Note: if any memory is left allocated, every single one that's found gets output to stderr, along with the file/line/function of the level it was allocated from. Receipts, bestie ๐Ÿงพ

USTR_CNTL_MALLOC_CHECK_ADD()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Condition to begin malloc checking or not โ€” Type[1]: int

Works like USTR_CNTL_MALLOC_CHECK_END(), except it fails if the condition check (Parameter[1]) fails or if USTR_CNTL_MALLOC_CHECK_LVL() is zero. Two ways to fail, zero ways to be boring โœจ


USTR_CNTL_MALLOC_CHECK_DEL()

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Condition to end malloc checking or not โ€” Type[1]: int

Works like USTR_CNTL_MALLOC_CHECK_END(), but it fails if the condition check (Parameter[1]) fails or if USTR_CNTL_MALLOC_CHECK_LVL() is one.

Note: the condition (Parameter[1]) you pass to this macro should almost certainly be the return value from USTR_CNTL_MALLOC_CHECK_ADD(). Like, that's the intended pairing, don't fight it ๐Ÿ™

๐Ÿ’œ Creating allocated Ustr functions ๐Ÿ’œ

Now we're making brand-new Ustrs that you own. Main character allocation hours ๐Ÿ”ฅ


ustr_init_size()

  • Returns: Size that needs to be allocated
  • Type: size_t
  • Parameter[1]: Size of allocated storage โ€” Type[1]: size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” Type[2]: size_t
  • Parameter[3]: Exact memory allocations โ€” Type[3]: int
  • Parameter[4]: Length of data in the Ustr โ€” Type[4]: size_t

Figuring out the exact amount of memory you need to store a Ustr with the config you picked. Math era ๐Ÿงฎ


ustr_init_alloc()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Pointer to area of memory to use as a Ustr string โ€” Type[1]: void *
  • Parameter[2]: Size of area of memory โ€” Type[2]: size_t
  • Parameter[3]: Whether Ustr should store the size โ€” Type[3]: size_t
  • Parameter[4]: Number of bytes to use for references โ€” Type[4]: size_t
  • Parameter[5]: Whether the Ustr should use exact allocations โ€” Type[5]: int
  • Parameter[6]: Whether the Ustr should have the "enomem" flag set โ€” Type[6]: int
  • Parameter[7]: The initial length of the Ustr โ€” Type[7]: size_t

This creates a new Ustr string. Important though: you should have allocated that data via USTR_CONF_MALLOC() โ€” otherwise bad things will happen if the Ustr string is ever free'd or reallocated. Like, genuinely bad. Do not skip this ๐Ÿ’€


ustr_dupx_empty()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Size of allocated storage โ€” Type[1]: size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” Type[2]: size_t
  • Parameter[3]: Exact memory allocation flag โ€” Type[3]: int
  • Parameter[4]: ENOMEM, memory error flag โ€” Type[4]: int

Creates an empty Ustr, owned by you, allocated from system memory โ€” or it returns NULL. ๐ŸŒˆ

The size (Parameter[1]) is the desired allocation size for the entire Ustr, including the overhead for metadata. It gets rounded up if it's too small, so passing 1 as the size means you want a stored size but want to allocate the smallest amount of memory possible. Tiny but mighty ๐Ÿ“

The exact memory allocation flag (Parameter[3]) says whether the Ustr should round allocations up to the nearest half power of two, or should be no more than needed.

The ENOMEM memory error flag (Parameter[4]) sets the initial state of the user-visible flag for memory allocation errors. Examples: ustr_enomem(), ustr_setf_enomem_clr() and ustr_setf_enomem_err().

Note: the reference byte count can only be one of these values: 0, 1, 2 or 4, or 8 (on environments with a 64bit size_t). No improvising, bestie ๐Ÿ™ˆ It can be useful to ensure the Ustr is in system memory, so you can add things to it and check for errors with ustr_enomem(). If you chose to store the allocated size in the Ustr, then the number of bytes allocated for the reference count will be a minimum of 2.

ustr_dup_empty()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Nothing โ€” Type[1]: void

Same as calling ustr_dupx_empty() with the current set of default options. Convenience icon โœจ


ustr_dupx_undef()

  • Returns: Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Size of allocated storage โ€” Type[1]: size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” Type[2]: size_t
  • Parameter[3]: Exact memory allocations โ€” Type[3]: int
  • Parameter[4]: ENOMEM, memory error flag โ€” Type[4]: int
  • Parameter[5]: Length of new undefined data โ€” Type[5]: size_t

Works exactly like you called ustr_dupx_empty() and then ustr_add_undef(). Combo move ๐ŸŽ€


ustr_dup_undef()

  • Returns: Pointer to a Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Length of new undefined data โ€” Type[1]: size_t

Same as calling ustr_dupx_undef() with the current set of default options. Defaults forever ๐Ÿ’…


ustr_dup()

  • Returns: A pointer to a Ustr string
  • Type: struct Ustr *
  • Parameter[1]: Pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *

This one tries to bump up the reference count on the Ustr string you passed in, and if that succeeds, it just returns that back to you. If it fails, it creates a brand-new Ustr string that looks identical to the old one โ€” apart from the reference count. Either way you get a string, so, slay ๐Ÿฆ‹

Note:

Okay so real talk, bestie: because the new Ustr string is configured identically to the old Ustr string, the result can be very different from what you get if you call ustr_dup_buf() with ustr_cstr() and ustr_len() from the original string โ€” because that route just uses whatever the default configuration is. ๐Ÿ’…

Especially worth noting: if you ustr_dup() a Ustr string with an explicit size of 900 but a length of 1, and the reference count is full, the returned Ustr string will have a size of 900 bytes and so will have allocated a little over that. ustr_dup_buf(), even with a sized configuration, would only allocate about 12 bytes and have a size a little less than that. No cap. โœจ

Function: ustr_dupx()

Returns: pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Size of allocated storage โ€” size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” size_t
  • Parameter[3]: Exact memory allocations โ€” int
  • Parameter[4]: ENOMEM, memory error flag โ€” int
  • Parameter[5]: Pointer to a constant Ustr string โ€” const struct Ustr *

Explanation: This function tries to add a reference if the value of the size, reference bytes, exact memory allocations and ENOMEM are the same as those in the passed Ustr string (Parameter[5]). If the comparison fails or the addition of a reference fails, it works like ustr_dupx_buf() using ustr_cstr() and ustr_len(). ๐Ÿซถ

Function: ustr_sc_dup()

Returns: a pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **

Explanation: This function works like calling ustr_dup(), but if the reference count is maxed out and a new Ustr string has been allocated, that new string is stored in the passed argument (Parameter[1]) and the โ€œoldโ€ Ustr string is returned.

Note: The reason to use this is that if you have a โ€œmainโ€ Ustr string pointer that a lot of things are getting references to, then when the reference count maxes out youโ€™ll degrade into worst-case behaviour which acts as though there are no reference counts. This function stops that problem. As an example, if you have a 1 byte reference count and have 255 * 2 references, then using ustr_dup() will create 256 Ustr strings; using this function will create 4 Ustr strings. ๐Ÿ‘‘

Function: ustr_sc_dupx()

Returns: pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Size of allocated storage โ€” size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” size_t
  • Parameter[3]: Exact memory allocations โ€” int
  • Parameter[4]: ENOMEM, memory error flag โ€” int
  • Parameter[5]: A pointer to a pointer to a Ustr string โ€” struct Ustr **

Explanation: This function works like calling ustr_dupx(), but if the reference count is maxed out and a new Ustr string is allocated, that new string is stored in the passed argument (Parameter[1]) and the โ€œoldโ€ Ustr string is returned. If the configurations of the new Ustr string and the old Ustr string are not the same, this function works identically to ustr_dupx().

Note: The reason to use this is that if you have a โ€œmainโ€ Ustr string pointer that a lot of things are getting references to, then when the reference count maxes out youโ€™ll degrade into worst-case behaviour which acts as though there are no reference counts. This function stops that problem. As an example, if you have a 1 byte reference count and have 255 * 2 references, then using ustr_dupx() will create 256 Ustr strings; using this function will create 4 Ustr strings. ๐Ÿ’–

Function: ustr_dup_buf()

Returns: a pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Pointer to data โ€” const void *
  • Parameter[2]: Length of data โ€” size_t

Explanation: This function works as if you had called ustr_dup_undef() and then copied the data into the new undefined space. ๐ŸŒธ

Function: ustr_dupx_buf()

Returns: pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Size of allocated storage โ€” size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” size_t
  • Parameter[3]: Exact memory allocations โ€” int
  • Parameter[4]: ENOMEM, memory error flag โ€” int
  • Parameter[5]: Pointer to data โ€” const void *
  • Parameter[6]: Length of data โ€” size_t

Explanation: This function works as if you had called ustr_dupx_undef() and then copied the data into the new undefined space. ๐Ÿฆ‹

Function: ustr_dup_cstr()

Returns: a pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Pointer to constant C-style string โ€” const char *

Explanation: This function works as if you had called ustr_dup_buf() and passed strlen() as the length. โœจ

Function: ustr_dupx_cstr()

Returns: pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Size of allocated storage โ€” size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” size_t
  • Parameter[3]: Exact memory allocations โ€” int
  • Parameter[4]: ENOMEM, memory error flag โ€” int
  • Parameter[5]: Pointer to constant C-style string โ€” const char *

Explanation: This function works as if you had called ustr_dupx_buf() and passed strlen() as the length. ๐ŸŽ€

Function: USTR_DUP_OSTR()

Returns: a pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: A constant C-style string โ€” const char []

Explanation: This function works as if you had called ustr_dup_buf() and passed sizeof() - 1 as the length. ๐Ÿš

Function: USTR_DUP_OBJ()

Returns: a pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: A symbol โ€” ...

Explanation: This function works as if you had called ustr_dup_buf() and passed sizeof() as the length.

Note: In most cases youโ€™ll want to use USTR_DUP_OSTR(). ๐Ÿ’…

Function: ustr_dup_subustr()

Returns: a pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: Position in the Ustr โ€” size_t
  • Parameter[3]: Length to add from the Ustr โ€” size_t

Explanation: This function mostly works as if you had called ustr_dup_buf() with the ustr_cstr() + position - 1 and length values of the Ustr string to be added.

Note: If the position is 1 and the length is the length of the Ustr string, then it just calls ustr_dup(). ๐ŸŒˆ

Function: ustr_dupx_subustr()

Returns: pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Size of allocated storage โ€” size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” size_t
  • Parameter[3]: Exact memory allocations โ€” int
  • Parameter[4]: ENOMEM, memory error flag โ€” int
  • Parameter[5]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[6]: Position in the Ustr โ€” size_t
  • Parameter[7]: Length to add from the Ustr โ€” size_t

Explanation: This function mostly works as if you had called ustr_dupx_buf() with the ustr_cstr() + position - 1 and length values of the Ustr string to be added.

Note: If the position is 1 and the length is the length of the Ustr string, then it just calls ustr_dupx(). ๐Ÿ’œ

Function: ustr_dup_rep_chr()

Returns: a pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Byte value of data โ€” char
  • Parameter[2]: Length of bytes as data โ€” size_t

Explanation: This function works as if you had called ustr_dup_undef() and then copied the byte value to each position. ๐Ÿ“

Function: ustr_dupx_rep_chr()

Returns: pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Size of allocated storage โ€” size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” size_t
  • Parameter[3]: Exact memory allocations โ€” int
  • Parameter[4]: ENOMEM, memory error flag โ€” int
  • Parameter[5]: Byte value of data โ€” char
  • Parameter[6]: Length of bytes as data โ€” size_t

Explanation: This function works as if you had called ustr_dupx_undef() and then copied the byte value to each position. ๐Ÿ’€

Function: ustr_sc_vjoin()

Returns: pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Separator to go between Ustr strings โ€” const struct Ustr *
  • Parameter[2]: A pointer to the first constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: A pointer to the second constant Ustr string โ€” const struct Ustr *
  • Parameter[4]: Variable argument list variable, from va_start() โ€” va_list

Explanation: This function works as if you called ustr_dup() on the first Ustr string (Parameter[2]), and then ustr_add() on the separator (Parameter[1]) followed by ustr_add() on the second Ustr string (Parameter[3]). This process then repeats for all the Ustr strings in the variable argument list (Parameter[4]) until a USTR_NULL is reached.

Note: This function doesnโ€™t guarantee to just take a reference to one of the passed Ustr strings, even if that is what would happen if you called the above manually. ๐Ÿ”ฅ

Function: ustr_sc_join()

Returns: pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Separator to go between Ustr strings โ€” const struct Ustr *
  • Parameter[2]: A pointer to the first constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: A pointer to the second constant Ustr string โ€” const struct Ustr *
  • Parameter[4]: Zero or more pointers to constant Ustr strings and then USTR_NULL โ€” ...

Explanation: This function calls va_start() to get a variable argument list and then calls ustr_sc_vjoin().

Note: This function doesnโ€™t guarantee to just take a reference to one of the passed Ustr strings, even if that is what would happen if you called the above manually. ๐Ÿงš

Function: ustr_sc_vjoinx()

Returns: pointer to a Ustr string โ€” struct Ustr *

  • Parameter[1]: Size of allocated storage โ€” size_t
  • Parameter[2]: Number of bytes to use for reference count โ€” size_t
  • Parameter[3]: Exact memory allocations โ€” int
  • Parameter[4]: ENOMEM, memory error flag โ€” int
  • Parameter[5]: Separator to go between Ustr strings โ€” const struct Ustr *
  • Parameter[6]: A pointer to the first constant Ustr string โ€” const struct Ustr *
  • Parameter[7] โ€” a pointer to the second constant Ustr string
    • Type[7] โ€” const struct Ustr *
    • Parameter[8] โ€” the variable argument list variable, straight from va_start()
      • Type[8] โ€” va_list

Explanation:

It's literally the same energy as calling ustr_dupx() on the first Ustr string (Parameter[2]), then ustr_add() on the separator (Parameter[1]), then ustr_add() on the second Ustr string (Parameter[3]). And then that whole little routine repeats for every Ustr string chilling in the variable argument list (Parameter[4]) until it bumps into a USTR_NULL. ๐ŸŒธ

Note: bestie, this function does not pinky-promise to just take a reference to one of the Ustr strings you passed in โ€” even if that's exactly what would've happened if you'd done all that manual calling yourself. No cap.

Function: ustr_sc_joinx()

Returns: pointer to a Ustr string โ€” Type: struct Ustr *

  • Parameter[1] โ€” size of allocated storage
    • Type[1] โ€” size_t
  • Parameter[2] โ€” number of bytes to use for the reference count
    • Type[2] โ€” size_t
  • Parameter[3] โ€” exact memory allocations
    • Type[3] โ€” int
  • Parameter[4] โ€” ENOMEM, the memory error flag
    • Type[4] โ€” int
  • Parameter[5] โ€” the separator that goes between the Ustr strings
    • Type[5] โ€” const struct Ustr *
  • Parameter[6] โ€” a pointer to the first constant Ustr string
    • Type[6] โ€” const struct Ustr *
  • Parameter[7] โ€” a pointer to the second constant Ustr string
    • Type[7] โ€” const struct Ustr *
  • Parameter[8] โ€” zero or more pointers to constant Ustr strings, and then USTR_NULL
    • Type[8] โ€” ...

Explanation:

This one just calls va_start() to grab a variable argument list, and then hands everything off to ustr_sc_vjoinx(). Middle-man behaviour honestly, but it slays. โœจ

Function: ustr_sc_vconcat()

Returns: pointer to a Ustr string โ€” Type: struct Ustr *

  • Parameter[1] โ€” a pointer to the first constant Ustr string
    • Type[1] โ€” const struct Ustr *
  • Parameter[2] โ€” the variable argument list variable, from va_start()
    • Type[2] โ€” va_list

Explanation:

Works exactly like you called ustr_dup() on the first Ustr string (Parameter[1]), then ustr_add() on the second Ustr string (Parameter[3]). Then the whole thing loops for every Ustr string in the variable argument list (Parameter[4]) until a USTR_NULL shows up. ๐Ÿฆ‹

Note: again, no guarantee that it'll simply take a reference to one of the Ustr strings you handed over โ€” even if that's what would've gone down if you'd done it manually. It's giving "trust me bro" energy but make it documented.

Function: ustr_sc_concat()

Returns: pointer to a Ustr string โ€” Type: struct Ustr *

  • Parameter[1] โ€” a pointer to the first constant Ustr string
    • Type[1] โ€” const struct Ustr *
  • Parameter[2] โ€” zero or more pointers to constant Ustr strings, and then USTR_NULL
    • Type[2] โ€” ...

Explanation:

Calls va_start() to get a variable argument list, then calls ustr_sc_vconcat(). That's it, that's the whole personality. ๐Ÿ’…

Function: ustr_sc_vconcatx()

Returns: pointer to a Ustr string โ€” Type: struct Ustr *

  • Parameter[1] โ€” size of allocated storage
    • Type[1] โ€” size_t
  • Parameter[2] โ€” number of bytes to use for the reference count
    • Type[2] โ€” size_t
  • Parameter[3] โ€” exact memory allocations
    • Type[3] โ€” int
  • Parameter[4] โ€” ENOMEM, the memory error flag
    • Type[4] โ€” int
  • Parameter[5] โ€” a pointer to the first constant Ustr string
    • Type[5] โ€” const struct Ustr *
  • Parameter[6] โ€” the variable argument list variable, from va_start()
    • Type[6] โ€” va_list

Explanation:

Same deal as calling ustr_dupx() on the first Ustr string (Parameter[1]), then ustr_add() on the second Ustr string (Parameter[3]), repeating for everything in the variable argument list (Parameter[4]) until a USTR_NULL is reached. ๐ŸŽ€

Note: and once more for the people in the back โ€” it doesn't guarantee it'll just take a reference to one of the Ustr strings you passed, even if that's what would happen if you did the above manually. iykyk.

Function: ustr_sc_concatx()

Returns: pointer to a Ustr string โ€” Type: struct Ustr *

  • Parameter[1] โ€” size of allocated storage
    • Type[1] โ€” size_t
  • Parameter[2] โ€” number of bytes to use for the reference count
    • Type[2] โ€” size_t
  • Parameter[3] โ€” exact memory allocations
    • Type[3] โ€” int
  • Parameter[4] โ€” ENOMEM, the memory error flag
    • Type[4] โ€” int
  • Parameter[5] โ€” a pointer to the first constant Ustr string
    • Type[5] โ€” const struct Ustr *
  • Parameter[6] โ€” zero or more pointers to constant Ustr strings, and then USTR_NULL
    • Type[6] โ€” ...

Explanation:

Calls va_start() to get the variable argument list, then calls ustr_sc_vconcatx(). Short king of a function. ๐Ÿ‘‘


๐Ÿ—‘๏ธ Deleting a Ustr, or data within a Ustr ๐Ÿ—‘๏ธ

Function: ustr_free()

Returns: nothing โ€” Type: void

  • Parameter[1] โ€” pointer to a Ustr
    • Type[1] โ€” struct Ustr *

Explanation:

Decrements the reference count on a Ustr (if there is one), and frees it if it's allocated and the reference count has dropped to zero. Cleanup era. ๐Ÿงน

Note: if you pass it USTR_NULL, it does absolutely nothing. Zero drama.

Function: ustrp_free()

Returns: nothing โ€” Type: void

  • Parameter[1] โ€” pointer to a Ustr pool object
    • Type[1] โ€” struct Ustr_pool *
  • Parameter[2] โ€” pointer to a Ustrp (a pool-allocated Ustr)
    • Type[2] โ€” struct Ustrp *

Explanation:

Acts like ustr_free(), except instead of the ustr system free it calls the pool_free member function of the Ustr_pool (Parameter[1]). Pool party rules. ๐Ÿซง

Function: ustr_sc_free()

Returns: nothing โ€” Type: void

  • Parameter[1] โ€” a pointer to a pointer to a Ustr string
    • Type[1] โ€” struct Ustr **

Explanation:

Calls ustr_free() and then sets the pointer (Parameter[1]) to USTR_NULL โ€” which is a noop when you hand it to ustr_free(). This is the anti-"double free" error hack, and honestly it's iconic for that. ๐Ÿ”ฅ

Note: the point-to-the-pointer must be non-NULL, but the function also accepts a NULL ustr and just does nothing. So you can pass the same pointer to this thing a bunch of times and only the very first call does anything at all. no cap, spam it safely.

Function: ustr_sc_free2()

Returns: nothing โ€” Type: void

  • Parameter[1] โ€” a pointer to a pointer to a Ustr string
    • Type[1] โ€” struct Ustr **
  • Parameter[2] โ€” pointer to a Ustr string
    • Type[2] โ€” struct Ustr *

Explanation:

Behaves like ustr_sc_free(), but instead of setting the pointer (Parameter[1]) to USTR_NULL, it sets it to the Ustr string (Parameter[2]). Swapping one for another, main character energy. ๐ŸŒˆ

Note: the point-to-the-pointer must be non-NULL, and this function also accepts a NULL ustr to be freed and does nothing. So you can safely pass the same pointer to ustr_sc_free() and then to this function. ๐Ÿ’€ The passed value (Parameter[2]) shouldn't be USTR_NULL โ€” and in debugging mode the function will assert() that it isn't. literally do not test it.

Function: ustr_sc_free_shared()

Returns: nothing โ€” Type: void

  • Parameter[1] โ€” a pointer to a pointer to a Ustr string
    • Type[1] โ€” struct Ustr **

Explanation:

This is the easy-peasy way to "free" a Ustr string that's been shared (ustr_shared() returns USTR_TRUE) โ€” because normally ustr_free() just gets ignored on a shared Ustr string. It simply calls ustr_setf_owner() and then ustr_sc_free(). Two steps, one slay. ๐ŸŽ€

Function: ustr_del()

Returns: success or failure โ€” Type: int

  • Parameter[1] โ€” pointer to a pointer to a Ustr string
    • Type[1] โ€” struct Ustr **
  • Parameter[2] โ€” length to delete from the Ustr
    • Type[2] โ€” size_t

Explanation:

Deletes data off the end of the Ustr, and it might re-size the Ustr while it's at it.

Note: the Ustr is never re-sized when the size is stored explicitly, so the pointer never changes. Your pointer stays exactly where you left it, bestie. ๐Ÿ“

Function: ustr_del_subustr()

Returns: success or failure โ€” Type: int

  • Parameter[1] โ€” pointer to a pointer to a Ustr string
    • Type[1] โ€” struct Ustr **
  • Parameter[2] โ€” position in the Ustr
    • Type[2] โ€” size_t
  • Parameter[3] โ€” length to delete from the Ustr
    • Type[3] โ€” size_t

Explanation:

Works like ustr_del(), but it can delete an arbitrary section of the Ustr instead of just the tail end. Surgical. โœ‚๏ธ

Function: ustr_sc_del()

Returns: nothing โ€” Type: void

  • Parameter[1] โ€” a pointer to a pointer to a Ustr string
    • Type[1] โ€” struct Ustr **

Explanation:

Basically calling ustr_del() with ustr_len() as the length โ€” except if that fails, it does a ustr_free() and then sets the pointer to USTR(""). Nuking it from orbit, gracefully. ๐Ÿ’…

Note: the upside is that you don't have to check for memory failure errors yourself. The catch? If there is a memory failure and you're running a non-default configuration, the configuration reverts back to the default. trade-offs, babe.

๐Ÿ’– Adding data to a Ustr ๐Ÿ’–

okay bestie, this cluster is all about making your Ustr bigger and pushing more data into it. every single one of these returns success or failure as an int, and they all take that pointer-to-a-pointer-to-a-Ustr situation, so keep an eye on your struct Ustr ** โœจ

๐ŸŒธ Function: ustr_add_undef() ๐ŸŒธ

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: Length of new undefined data โ€” Type[2]: size_t

Explanation: The Ustr string is expanded (possibly reallocated) so that it can contain length (Parameter[2]) extra data ๐Ÿซถ. If the length is not zero, the Ustr will be writable. Or it'll return USTR_FALSE (zero) on failure ๐Ÿ˜ญ.

๐ŸŽ€ Function: ustr_add_buf() ๐ŸŽ€

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: Pointer to data โ€” Type[2]: const void *
  • Parameter[3]: Length of data โ€” Type[3]: size_t

Explanation: This function works as if you had called ustr_add_undef() and then copied the data into the new undefined space โœจ.

๐Ÿฆ‹ Function: ustr_add_cstr() ๐Ÿฆ‹

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: Pointer to constant C-style string โ€” Type[2]: const char *

Explanation: This function works as if you had called ustr_add_buf() and passed strlen() as the length ๐Ÿซถ.

๐ŸŒˆ Function: USTR_ADD_OSTR() ๐ŸŒˆ

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: A constant C-style string โ€” Type[2]: const char []

Explanation: This function works as if you had called ustr_add_buf() and passed sizeof() - 1 as the length โœจ.

๐Ÿ’œ Function: USTR_ADD_OBJ() ๐Ÿ’œ

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: A symbol โ€” Type[2]: ...

Explanation: This function works as if you had called ustr_add_buf() and passed sizeof() as the length ๐Ÿ‘‘

Note: In most cases you'll want to use USTR_ADD_OSTR() ๐Ÿ’…

๐Ÿ“ Function: ustr_add() ๐Ÿ“

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a constant Ustr string โ€” Type[2]: const struct Ustr *

Explanation: This function mostly works as if you had called ustr_add_buf() with the ustr_cstr() and ustr_len() values of the Ustr string to be added ๐Ÿซถ.

Note: If the Ustr string is zero length and isn't writable this function may just add a reference, this is fine for Ustr strings that are "constant" because if the Ustr is read-only then the memory will not be written to ๐Ÿ’–.

๐Ÿงš Function: ustr_add_subustr() ๐Ÿงš

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a constant Ustr string โ€” Type[2]: const struct Ustr *
  • Parameter[3]: Position in the Ustr โ€” Type[3]: size_t
  • Parameter[4]: Length to add from the Ustr โ€” Type[4]: size_t

Explanation: This function mostly works as if you had called ustr_add_buf() with the ustr_cstr() + position - 1 and length values of the Ustr string to be added. The exception being if you add a ustr to itself, while only having a single reference count, the simple method would access a free'd ustr, but this function just works ๐Ÿ˜ญโœจ.

Note: If the position is 1 and the length is the length of the Ustr string then it just calls ustr_add() ๐Ÿ’….

๐ŸŒŸ Function: ustr_add_rep_chr() ๐ŸŒŸ

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: Byte value of data โ€” Type[2]: char
  • Parameter[3]: Length of bytes as data โ€” Type[3]: size_t

Explanation: This function works as if you had called ustr_add_undef() and then copied the byte value to each position ๐Ÿซถ.


๐Ÿฆ‹ Setting a Ustr to some data ๐Ÿฆ‹

now we're not just adding, we're setting โ€” like a full little reset-and-fill moment, except every function here is still returning success or failure as an int, and still doing the struct Ustr ** dance ๐Ÿ’–

๐Ÿ’… Function: ustr_set_undef() ๐Ÿ’…

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: size_t โ€” Type[2]: size_t

Explanation: This function works as if you had called ustr_del() for the entire string and the ustr_add_undef() โœจ.

๐ŸŽ€ Function: ustr_set_empty() ๐ŸŽ€

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **

Explanation: This function works as if you had called ustr_del() for the entire string, however the string will be allocated if this completes ๐Ÿซถ.

๐ŸŒธ Function: ustr_set_buf() ๐ŸŒธ

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: Buffer containing data โ€” Type[2]: const void *
  • Parameter[3]: Length of Buffer โ€” Type[3]: size_t

Explanation: This function works as if you had called ustr_del() for the entire string and the ustr_add_buf() โœจ.

๐ŸŒˆ Function: ustr_set_cstr() ๐ŸŒˆ

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a constant C-style string โ€” Type[2]: const char *

Explanation: This function works as if you had called ustr_del() for the entire string and then ustr_add_cstr() ๐Ÿซถ.

๐Ÿ’œ Function: USTR_SET_OSTR() ๐Ÿ’œ

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: A constant C-style string โ€” Type[2]: const char []

Explanation: This function works as if you had called ustr_del() for the entire string and then USTR_ADD_OSTR() โœจ.

๐Ÿ“ Function: USTR_SET_OBJ() ๐Ÿ“

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: A symbol โ€” Type[2]: ...

Explanation: This function works as if you had called ustr_del() for the entire string and then USTR_ADD_OBJ() ๐Ÿ‘‘

Note: In most cases you'll want to use USTR_SET_OSTR() ๐Ÿ’…

๐Ÿงš Function: ustr_set() ๐Ÿงš

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a constant Ustr string โ€” Type[2]: const struct Ustr *

Explanation: This function works as if you had called ustr_del() for the entire string and the ustr_add() ๐Ÿซถ.

๐ŸŒŸ Function: ustr_set_subustr() ๐ŸŒŸ

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a constant Ustr string โ€” Type[2]: const struct Ustr *
  • Parameter[3]: Position in the Ustr โ€” Type[3]: size_t
  • Parameter[4]: Length to set from the Ustr โ€” Type[4]: size_t

Explanation: This function works as if you had called ustr_del() for the entire string and the ustr_add_subustr(). The exception being if you set a ustr to itself, while only having a single reference count, the simple method would access a free'd ustr data, but this function just works ๐Ÿ˜ญโœจ.

๐ŸŽ€ Function: ustr_set_rep_chr() ๐ŸŽ€

Returns: Success or failure โ€” type int ๐Ÿ’–

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: Byte value of data โ€” Type[2]: char
  • Parameter[3]: Length of bytes as data โ€” Type[3]: size_t

Explanation: This function works as if you had called ustr_del() for the entire string and the ustr_add_rep_chr() ๐Ÿซถ.

๐ŸŽ€ Inserting data into a Ustr ๐ŸŽ€

okay so inserting is the โœจglow-upโœจ version of adding, because you get to say where. Every one of these takes a position after which the new data goes, and ngl that + 1 detail matters โ€” iykyk.


๐ŸŒธ ustr_ins_undef()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: a pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: position after which the data should be added โ€” size_t
  • Parameter[3]: length of new undefined data โ€” size_t

Explanation: the Ustr string gets expanded (possibly reallocated, so bestie, watch that pointer ๐Ÿ‘€) so it can contain length (Parameter[2]) extra data, from after the required position. If the length is not zero the Ustr will be writable. Or it'll return USTR_FALSE (zero) on failure, rip ๐Ÿ˜ญ. The data in the Ustr is moved as needed to put the new data at position (Parameter[2]) + 1.


๐Ÿฆ‹ ustr_ins_buf()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: position after which the data should be added โ€” size_t
  • Parameter[3]: pointer to data โ€” const void *
  • Parameter[4]: length of data โ€” size_t

Explanation: this one works as if you'd called ustr_ins_undef() and then copied the data into the new undefined space. That's it, that's the vibe ๐Ÿ’…


๐Ÿงš ustr_ins_cstr()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: position after which the data should be added โ€” size_t
  • Parameter[3]: pointer to constant C-style string โ€” const char *

Explanation: works as if you'd called ustr_ins_buf() and passed strlen() as the length. classic, no notes โœจ


๐Ÿ’œ USTR_INS_OSTR()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: position after which the data should be added โ€” size_t
  • Parameter[3]: a constant C-style string โ€” const char []

Explanation: works as if you'd called ustr_ins_buf() and passed sizeof() - 1 as the length. (You're inserting a string literal here, and it ate ๐Ÿ”ฅ)


๐Ÿ‘‘ USTR_INS_OBJ()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: position after which the data should be added โ€” size_t
  • Parameter[3]: a symbol โ€” ...

Explanation: works as if you'd called ustr_ins_buf() and passed sizeof() as the length.

Note: in most cases you'll want to use USTR_INS_OSTR(). Like, fr fr, that's the one.

๐Ÿ“ ustr_ins()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: position after which the data should be added โ€” size_t
  • Parameter[3]: a pointer to a constant Ustr string โ€” const struct Ustr *

Explanation: works as if you'd called ustr_ins_buf() with the ustr_cstr() and ustr_len() values of the Ustr string to be added. Ustr-on-Ustr action, we love to see it ๐Ÿซถ


๐ŸŒˆ ustr_ins_subustr()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: position after which the data should be added โ€” size_t
  • Parameter[2]: a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: position in the Ustr โ€” size_t
  • Parameter[4]: length to ins from the Ustr โ€” size_t

Explanation: this one mostly works as if you'd called ustr_ins_buf() with the ustr_cstr() + position - 1 and length values of the Ustr string to be insed. The exception โ€” and this is the iconic part โ€” is if you insert a ustr into itself while only having a single reference count: the simple method would go and access freed ustr data ๐Ÿ’€, but this function just works. main character energy, honestly.


โญ ustr_ins_rep_chr()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: position after which the data should be added โ€” size_t
  • Parameter[2]: byte value of data โ€” char
  • Parameter[3]: length of bytes as data โ€” size_t

Explanation: works as if you'd called ustr_ins_undef() and then copied the byte value to each position. repeated char moment, we love a pattern ๐ŸŒธ


๐Ÿ’– Adding, duplicating and setting formatted data to a Ustr ๐Ÿ’–

the *fmt* girlies are here and they're all basically "do the snprintf() thing, then hand it to the buffer function." every single one of them. no cap. keep an eye on which parameter number each explanation points at, because that's just how it's written ๐Ÿซ 


๐ŸŽ€ ustr_add_vfmt_lim()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: a pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: limit of data to add โ€” size_t
  • Parameter[3]: a pointer to a constant C-style string โ€” const char *
  • Parameter[4]: variable argument list variable, from va_start() โ€” va_list

Explanation: works like calling the system vsnprintf() with the limit (Parameter[2]) as the limit to vsnprintf() and then calling ustr_add_buf().


๐Ÿฆ‹ ustr_add_vfmt()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: a pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: a pointer to a constant C-style string โ€” const char *
  • Parameter[3]: variable argument list variable, from va_start() โ€” va_list

Explanation: works like calling the system vsnprintf() and then calling ustr_add_buf().


โœจ ustr_add_fmt_lim()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: a pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: limit of data to add โ€” size_t
  • Parameter[3]: a pointer to a constant C-style string โ€” const char *
  • Parameter[4]: options depending on value of Parameter[3] โ€” ...

Explanation: works like calling the system snprintf() with the limit (Parameter[2]) as the limit to snprintf() and then calling ustr_add_buf().


๐Ÿ”ฅ ustr_add_fmt()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: a pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: a pointer to a constant C-style string โ€” const char *
  • Parameter[3]: options depending on value of Parameter[2] โ€” ...

Explanation: works like calling the system snprintf() and then calling ustr_add_buf().


๐Ÿ’œ ustr_dup_vfmt_lim()

  • Returns: pointer to a Ustr string
  • Type: struct Ustr *
  • Parameter[1]: limit of data to dup โ€” size_t
  • Parameter[2]: pointer to a constant Ustr string โ€” const char *
  • Parameter[3]: variable argument list variable, from va_start() โ€” va_list

Explanation: works like calling the system vsnprintf() with the limit (Parameter[2]) as the limit to vsnprintf() and then calling ustr_dup_buf().


๐Ÿงš ustr_dup_vfmt()

  • Returns: pointer to a Ustr string
  • Type: struct Ustr *
  • Parameter[1]: limit of data to dup โ€” size_t
  • Parameter[2]: pointer to a constant Ustr string โ€” const char *
  • Parameter[3]: variable argument list variable, from va_start() โ€” va_list

Explanation: works like calling the system vsnprintf() and then calling ustr_dup_buf().


๐ŸŒธ ustr_dup_fmt_lim()

  • Returns: pointer to a Ustr string
  • Type: struct Ustr *
  • Parameter[1]: limit of data to dup โ€” size_t
  • Parameter[2]: pointer to a constant Ustr string โ€” const char *
  • Parameter[3]: options depending on value of Parameter[2] โ€” ...

Explanation: works like calling the system snprintf() with the limit (Parameter[2]) as the limit to snprintf() and then calling ustr_dup_buf().


๐Ÿ‘‘ ustr_dup_fmt()

  • Returns: pointer to a Ustr string
  • Type: struct Ustr *
  • Parameter[1]: pointer to a constant Ustr string โ€” const char *
  • Parameter[2]: options depending on value of Parameter[1] โ€” ...

Explanation: works like calling the system snprintf() and then calling ustr_dup_buf().


๐ŸŒˆ ustr_dupx_fmt_lim()

  • Returns: pointer to a Ustr string
  • Type: struct Ustr *
  • Parameter[1]: size of allocated storage โ€” size_t
  • Parameter[2]: number of bytes to use for reference count โ€” size_t
  • Parameter[3]: exact memory allocations โ€” int
  • Parameter[4]: ENOMEM, memory error flag โ€” int
  • Parameter[5]: limit of data to dup โ€” size_t
  • Parameter[6]: pointer to a constant Ustr string โ€” const char *
  • Parameter[7]: options depending on value of Parameter[6] โ€” ...

Explanation: works like calling the system snprintf() with the limit (Parameter[2]) as the limit to snprintf() and then calling ustr_dupx_buf(). (yes, seven parameters. she's that girl ๐Ÿ’…)


โญ ustr_dupx_fmt()

  • Returns: pointer to a Ustr string
  • Type: struct Ustr *
  • Parameter[1]: size of allocated storage โ€” size_t
  • Parameter[2]: number of bytes to use for reference count โ€” size_t
  • Parameter[3]: exact memory allocations โ€” int
  • Parameter[4]: ENOMEM, memory error flag โ€” int
  • Parameter[5]: pointer to a constant Ustr string โ€” const char *
  • Parameter[6]: options depending on value of Parameter[5] โ€” ...

Explanation: works like calling the system snprintf() and then calling ustr_dup_bufx().


๐Ÿ“ ustr_set_vfmt_lim()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: a pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: limit of data to set โ€” size_t
  • Parameter[3]: a pointer to a constant C-style string โ€” const char *
  • Parameter[4]: variable argument list variable, from va_start() โ€” va_list

Explanation: works like calling ustr_del() for all the data and then ustr_add_vfmt_lim(). wipe the slate, then go off โœจ


๐Ÿฆ‹ ustr_set_vfmt()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: a pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: a pointer to a constant C-style string โ€” const char *
  • Parameter[3]: variable argument list variable, from va_start() โ€” va_list

Explanation: works like calling ustr_del() for all the data and then ustr_add_vfmt().


๐ŸŽ€ ustr_set_fmt_lim()

  • Returns: success or failure
  • Type: int
  • Parameter[1]: a pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: limit of data to set โ€” size_t
  • Parameter[3]: a pointer to a constant C-style string โ€” const char *
  • Parameter[4]: options depending on value of Parameter[3] โ€” ...

Explanation: okay so this one's explanation is literally mid-thought over here ๐Ÿ˜ญ hold that thought โ€” it picks up right where this leaves off, and I am not about to improvise on you ๐Ÿซถ

This function works like calling ustr_del() for all the data and then ustr_add_fmt_lim(). Short, sweet, and lowkey iconic. ๐Ÿ’…


๐ŸŒธ Function: ustr_set_fmt() ๐ŸŒธ

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[3] โ€” Options depending on value of Parameter[2] โ€” Type: ...

Explanation:

This function works like calling ustr_del() for all the data and then ustr_add_fmt(). Clean slate energy, no cap. โœจ


๐Ÿฆ‹ Function: ustr_ins_vfmt_lim() ๐Ÿฆ‹

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position after which the data should be added โ€” Type: size_t
  • Parameter[3] โ€” Limit of data to insert โ€” Type: size_t
  • Parameter[4] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[5] โ€” Variable argument list variable, from va_start() โ€” Type: va_list

Explanation:

This function works like calling the system vsnprintf() with the limit (Parameter[3]) as the limit to vsnprintf() and then calling ustr_ins_buf(). Basically: format it with a cap, then insert it. Obsessed. ๐Ÿ’–


๐ŸŽ€ Function: ustr_ins_vfmt() ๐ŸŽ€

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position after which the data should be added โ€” Type: size_t
  • Parameter[3] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[4] โ€” Variable argument list variable, from va_start() โ€” Type: va_list

Explanation:

This function works like calling the system vsnprintf() and then calling ustr_ins_buf(). No limit era โ€” just vibes and formatting. ๐ŸŒˆ


โญ Function: ustr_ins_fmt_lim() โญ

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position after which the data should be added โ€” Type: size_t
  • Parameter[3] โ€” Limit of data to insert โ€” Type: size_t
  • Parameter[4] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[5] โ€” Options depending on value of Parameter[4] โ€” Type: ...

Explanation:

This function works like calling the system snprintf() with the limit (Parameter[3]) as the limit to snprintf() and then calling ustr_ins_buf(). Limit set, boundaries respected, we love to see it. ๐Ÿ‘‘


๐Ÿ’œ Function: ustr_ins_fmt() ๐Ÿ’œ

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position after which the data should be added โ€” Type: size_t
  • Parameter[3] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[4] โ€” Options depending on value of Parameter[3] โ€” Type: ...

Explanation:

This function works like calling the system snprintf() and then calling ustr_ins_buf(). Format, then insert โ€” the classic duo. ๐Ÿซถ


๐ŸŒบ Function: ustr_sub_vfmt_lim() ๐ŸŒบ

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position where to start substitution โ€” Type: size_t
  • Parameter[3] โ€” Limit of data to substitute โ€” Type: size_t
  • Parameter[4] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[5] โ€” Variable argument list variable, from va_start() โ€” Type: va_list

Explanation:

This function works like calling the system vsnprintf() with the limit (Parameter[3]) as the limit to vsnprintf() and then calling ustr_sub_buf(). Swap-in with a cap, periodt. ๐Ÿ“


๐Ÿงš Function: ustr_sub_vfmt() ๐Ÿงš

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position where to start substitution โ€” Type: size_t
  • Parameter[3] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[4] โ€” Variable argument list variable, from va_start() โ€” Type: va_list

Explanation:

This function works like calling the system vsnprintf() and then calling ustr_sub_buf(). Substitute era, unlimited format energy. โœจ


๐Ÿ”ฅ Function: ustr_sub_fmt_lim() ๐Ÿ”ฅ

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position where to start substitution โ€” Type: size_t
  • Parameter[3] โ€” Limit of data to substitute โ€” Type: size_t
  • Parameter[4] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[5] โ€” Options depending on value of Parameter[4] โ€” Type: ...

Explanation:

This function works like calling the system snprintf() with the limit (Parameter[3]) as the limit to snprintf() and then calling ustr_sub_buf(). Cap it, format it, substitute it. Slay. ๐Ÿ’…


๐Ÿ‘‘ Function: ustr_sub_fmt() ๐Ÿ‘‘

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position where to start substitution โ€” Type: size_t
  • Parameter[3] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[4] โ€” Options depending on value of Parameter[3] โ€” Type: ...

Explanation:

This function works like calling the system snprintf() and then calling ustr_sub_buf(). Formatting and substitution, bestie โ€” the main character combo. ๐ŸŒŸ


๐ŸŒˆ Function: ustr_sc_sub_vfmt_lim() ๐ŸŒˆ

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position where to start substitution โ€” Type: size_t
  • Parameter[3] โ€” Length of substitution โ€” Type: size_t
  • Parameter[4] โ€” Limit of data to substitute โ€” Type: size_t
  • Parameter[5] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[6] โ€” Variable argument list variable, from va_start() โ€” Type: va_list

Explanation:

This function works like calling the system vsnprintf() with the limit (Parameter[4]) as the limit to vsnprintf() and then calling ustr_sc_sub_buf(). Length plus limit plus format โ€” she's doing the most, and honestly? Ate. ๐Ÿ’–


๐Ÿ’€ Function: ustr_sc_sub_vfmt() ๐Ÿ’€

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position where to start substitution โ€” Type: size_t
  • Parameter[3] โ€” Length of substitution โ€” Type: size_t
  • Parameter[4] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[5] โ€” Variable argument list variable, from va_start() โ€” Type: va_list

Explanation:

This function works like calling the system vsnprintf() and then calling ustr_sc_sub_buf(). Length-aware substitute with va-list energy โ€” no cap, just format. ๐Ÿฆ‹


๐ŸŒธ Function: ustr_sc_sub_fmt_lim() ๐ŸŒธ

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position where to start substitution โ€” Type: size_t
  • Parameter[3] โ€” Length of substitution โ€” Type: size_t
  • Parameter[4] โ€” Limit of data to substitute โ€” Type: size_t
  • Parameter[5] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[6] โ€” Options depending on value of Parameter[5] โ€” Type: ...

Explanation:

This function works like calling the system snprintf() with the limit (Parameter[3]) as the limit to snprintf() and then calling ustr_sc_sub_buf(). Yes โ€” the manual says Parameter[3] here, and we're just reporting it exactly, bestie. ๐Ÿ’€โœจ


๐ŸŽ€ Function: ustr_sc_sub_fmt() ๐ŸŽ€

Returns: Success or failure โ€” Type: int

  • Parameter[1] โ€” A pointer to a pointer to a Ustr string โ€” Type: struct Ustr **
  • Parameter[2] โ€” Position where to start substitution โ€” Type: size_t
  • Parameter[3] โ€” Length of substitution โ€” Type: size_t
  • Parameter[4] โ€” A pointer to a constant C-style string โ€” Type: const char *
  • Parameter[5] โ€” Options depending on value of Parameter[5] โ€” Type: ...

Explanation:

This function works like calling the system snprintf() and then calling ustr_sc_sub_buf(). Format it, substitute it with a length, and let the function handle the rest. ๐Ÿ’…

โœจ Accessing the variables of a Ustr โœจ

Okay bestie, this is the part where you peek at what a Ustr is actually holding. No cap, these little functions are the vibe check for your stringโ€™s internals ๐Ÿ’…

๐ŸŒธ Function: ustr_len() ๐ŸŒธ

  • Returns: The length of the Ustr
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: This one hands you the length of the data inside the Ustr, kinda like strlen() but it wonโ€™t get the answer wrong when there are extra NIL bytes chilling in there. Iconic behavior, honestly.

๐Ÿฆ‹ Function: ustr_cstr() ๐Ÿฆ‹

  • Returns: Read-only pointer to the start of data in the Ustr
  • Type: const char *
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: This gives you a read-only pointer to the beginning of the Ustrโ€™s data. And because a Ustr always has a terminating NIL byte, this pointer is also a valid C-style string. Slay.

๐ŸŽ€ Function: ustr_wstr() ๐ŸŽ€

  • Returns: Writable pointer to the start of data in the Ustr, or NULL
  • Type: char *
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: struct Ustr *

Explanation: This gives you a writable pointer to the start of the Ustrโ€™s data. Again, since thereโ€™s always a terminating NIL byte, it doubles as a valid C-style string. However, if the ustr is read-only (ustr_ro() == USTR_TRUE), this function returns NULL.

Note: Unless the string is owned (ustr_owner() == USTR_TRUE), changing data through this pointer can be a very bad idea, because then every reference gets updated too. See ustr_sc_wstr(). Like, donโ€™t just start editing shared data, bestie ๐Ÿ˜ญ

๐Ÿ’œ Function: ustr_alloc() ๐Ÿ’œ

  • Returns: A boolean flag of either USTR_TRUE or USTR_FALSE
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Tells you if the Ustr is currently living in allocated storage. Simple as that.

๐ŸŒˆ Function: ustr_exact() ๐ŸŒˆ

  • Returns: A boolean flag of either USTR_TRUE or USTR_FALSE
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: This one tells you if the Ustr is doing exact allocations, meaning as it grows it only gets storage allocated exactly as needed, not in half powers of two.

Note: This will always be USTR_FALSE for read-only Ustr strings (ustr_ro() == USTR_TRUE), even though the default may be to use exact sized allocations when adding data to them etc.

๐Ÿ’ซ Function: ustr_sized() ๐Ÿ’ซ

  • Returns: A boolean flag of either USTR_TRUE or USTR_FALSE
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Tells you if the Ustr stores an explicit allocation size. If not, the size is implied as the next highest half power of two. Math but make it string storage โœจ

๐Ÿ“ Function: ustr_ro() ๐Ÿ“

  • Returns: A boolean flag of either USTR_TRUE or USTR_FALSE
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Says if the Ustr is currently in read-only storage. Read-only storage is not writable, but it can be referenced via ustr_dup() an infinite number of times. Obsessed with a storage mode that never gets tired.

๐ŸŒธ Function: ustr_fixed() ๐ŸŒธ

  • Returns: A boolean flag of either USTR_TRUE or USTR_FALSE
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Says if the Ustr is currently in fixed size storage. Fixed size storage is writable, but it cannot be referenced.

Note: Fixed size storage always explicitly stores the size of the storage.

๐Ÿงš Function: ustr_enomem() ๐Ÿงš

  • Returns: A boolean flag of either USTR_TRUE or USTR_FALSE
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: This just returns the value of the user settable flag in the Ustr. It can be set via ustr_setf_enomem_err() and cleared by ustr_setf_enomem_clr(). It gets automatically set to on whenever a memory allocation failure happens for a Ustr.

Note: If a Ustr is referenced multiple times, ustr_setf_enomem_err() will fail. This always fails for Ustrโ€™s in read-only storage.

๐Ÿฆ‹ Function: ustr_shared() ๐Ÿฆ‹

  • Returns: A boolean flag of either USTR_TRUE or USTR_FALSE
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Says if the Ustr is in the โ€œsharedโ€ mode. It can be set via ustr_setf_shared() and cleared by ustr_setf_owner() on allocated Ustrโ€™s. Shared mode means a Ustr can be referenced and unreferenced an infinite number of times.

Note: This always succeeds for Ustrโ€™s in read-only storage. This always fails for Ustrโ€™s in fixed size storage.

๐Ÿ’… Function: ustr_limited() ๐Ÿ’…

  • Returns: A boolean flag of either USTR_TRUE or USTR_FALSE
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Says if the Ustr is currently in fixed size storage and cannot move to allocated storage.

Note: This always fails for Ustrโ€™s in allocated storage. This always fails for Ustrโ€™s in read-only storage.

๐Ÿ‘‘ Function: ustr_owner() ๐Ÿ‘‘

  • Returns: A boolean flag of either USTR_TRUE or USTR_FALSE
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Says if there is only a single reference to the Ustr string. Main character energy: itโ€™s the only one holding the string.

Note: This always fails for Ustrโ€™s in read-only storage. This always succeeds for Ustrโ€™s in fixed size storage.

๐ŸŒŸ Function: ustr_size() ๐ŸŒŸ

  • Returns: size_t
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Calculates the maximum amount of data that could be stored (i.e. the max ustr_len()) without having to re-size the Ustr string.

๐ŸŒˆ Function: ustr_size_alloc() ๐ŸŒˆ

  • Returns: size_t
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Returns the size of the storage for the Ustr.

๐Ÿ’œ Function: ustr_size_overhead() ๐Ÿ’œ

  • Returns: size_t
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *

Explanation: Returns the difference between the size of the storage and the maximum amount of data that could be stored without having to re-size the Ustr string.

๐ŸŽ€ Function: ustr_conf() ๐ŸŽ€

  • Returns: Nothing
  • Type: void
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Return size allocated number
  • Type[2]: size_t *
  • Parameter[3]: Return number of bytes used in the reference count
  • Type[3]: size_t *
  • Parameter[4]: Return exact allocations flag
  • Type[4]: int *
  • Parameter[5]: Return number of bytes used in the length
  • Type[5]: size_t *
  • Parameter[5]: Return number of references to this Ustr
  • Type[5]: size_t *

Explanation: Gives you the configuration of the current Ustr that you need to duplicate it via the ustr_dupx_*() functions. It also gives the number of bytes used for the length and the number of references, which are mainly informational.

Note: This function differs from calling the ustr_exact() etc. functions in that it returns the global options if this Ustr isnโ€™t allocated, thus telling you what the configuration would be if the Ustr was turned into an allocated Ustr by adding data etc. Zero references for an allocated Ustr with a non-zero number of bytes for a reference count means itโ€™s in โ€œsharedโ€ mode).

๐Ÿ’– Setting the flags of a Ustr ๐Ÿ’–

โœจ Function: ustr_setf_enomem_err() โœจ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: A pointer to a Ustr string
  • Type[1]: struct Ustr *

Explanation: Sets the enomem flag, which you can observe via the ustr_enomem() function. The implication of setting this flag is that a memory error has occurred in a previous function call on this Ustr.

Note: This function fails if ustr_owner() fails for the Ustr.

๐ŸŒธ Function: ustr_setf_enomem_clr() ๐ŸŒธ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: A pointer to a Ustr string
  • Type[1]: struct Ustr *

Explanation: Clears the enomem flag, which you can observe via the ustr_enomem() function. The implication of this flag being set is that a memory error has occurred in a previous function call on this Ustr, so on clearing the flag you should know you have brought the Ustr back to a known state.

Note: This function fails if ustr_owner() fails for the Ustr.

๐Ÿฆ‹ Function: ustr_setf_share() ๐Ÿฆ‹

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: A pointer to a Ustr string
  • Type[1]: struct Ustr *

Explanation: Sets the shared mode, which you can observe via the ustr_shared() function. This is used on a Ustr so that it can have more references than it is able to hold in its reference count. After this call the Ustr can be referenced and unreferenced an infinite number of times.

Note: After this call the Ustr will never be deleted until ustr_setf_owner() is called. This function fails if ustr_alloc() fails for the Ustr.

๐Ÿ‘‘ Function: ustr_setf_owner() ๐Ÿ‘‘

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: A pointer to a Ustr string
  • Type[1]: struct Ustr *

Explanation: Removes the shared mode, which you can observe via the ustr_shared() function. This is used so that a Ustr in shared mode can be freed.

Note: This function fails if ustr_alloc() fails for the Ustr.

๐ŸŒˆ Comparing data in a Ustr ๐ŸŒˆ

๐Ÿ’ซ Function: ustr_cmp_buf() ๐Ÿ’ซ

  • Returns: Less than zero, zero or greater than zero depending on comparison
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: A pointer to constant bytes, to compare
  • Type[2]: const void *
  • Parameter[3]: Length of comparison bytes
  • Type[3]: size_t

Explanation: Works like memcmp() on the Ustr and the passed data.

๐Ÿ“ Function: ustr_cmp() ๐Ÿ“

  • Returns: Less than zero, zero or greater than zero depending on comparison
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string
  • Type[2]: const struct Ustr *

Explanation: Works like ustr_cmp_buf() but with the data from ustr_cstr() and the length from ustr_len().

๐Ÿ’… Function: ustr_cmp_subustr() ๐Ÿ’…

  • Returns: Less than zero, zero or greater than zero depending on comparison
  • Type: int
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string
  • Type[2]: const struct Ustr *
  • Parameter[3]: Position in the Ustr โ€” size_t
  • Parameter[4]: Length to compare from the Ustr โ€” size_t

Explanation: This function works like ustr_cmp() but with a limit on the data and length. (yes bestie, it's the "only look at this slice" version ๐Ÿ’…)


๐Ÿฆ‹ ustr_cmp_cstr()

Returns: Less than zero, zero, or greater than zero depending on the comparison Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant C-style string โ€” const char *

Explanation: This function works like ustr_cmp_buf() but with a length from strlen().

๐Ÿฆ‹ ustr_cmp_fast_buf()

Returns: Less than zero, zero, or greater than zero depending on the comparison Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to constant bytes, to compare โ€” const void *
  • Parameter[3]: Length of comparison bytes โ€” size_t

Explanation: This function works like ustr_cmp_buf() but the order of comparison is optimized for speed, but is much less friendly to humans. like, it ate and left no crumbs for readability ๐Ÿ˜ญ the machine is thriving, your eyeballs are not

๐Ÿฆ‹ ustr_cmp_fast()

Returns: Less than zero, zero, or greater than zero depending on the comparison Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *

Explanation: This function works like ustr_cmp_fast_buf() but with the data from ustr_cstr() and the length from ustr_len().

๐Ÿฆ‹ ustr_cmp_fast_subustr()

Returns: Less than zero, zero, or greater than zero depending on the comparison Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: Position in the Ustr โ€” size_t
  • Parameter[4]: Length to compare from the Ustr โ€” size_t

Explanation: This function works like ustr_cmp_fast() but with a limit on the data and length.

๐Ÿฆ‹ ustr_cmp_fast_cstr()

Returns: Less than zero, zero, or greater than zero depending on the comparison Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant C-style string โ€” const char *

Explanation: This function works like ustr_cmp_fast_buf() but with a length from strlen().


๐ŸŽ€ ustr_cmp_case_buf()

Returns: Less than zero, zero, or greater than zero depending on the comparison Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to constant bytes, to compare โ€” const void *
  • Parameter[3]: Length of comparison bytes โ€” size_t

Explanation: This function works like ustr_cmp_buf() but the order of comparison ignores ASCII case. so A and a are the same girlie here, no cap ๐Ÿ’–

๐ŸŽ€ ustr_cmp_case()

Returns: Less than zero, zero, or greater than zero depending on the comparison Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *

Explanation: This function works like ustr_cmp_case_buf() but with the data from ustr_cstr() and the length from ustr_len().

๐ŸŽ€ ustr_cmp_case_subustr()

Returns: Less than zero, zero, or greater than zero depending on the comparison Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: Position in the Ustr โ€” size_t
  • Parameter[4]: Length to compare from the Ustr โ€” size_t

Explanation: This function works like ustr_cmp_case() but with a limit on the data and length.

๐ŸŽ€ ustr_cmp_case_cstr()

Returns: Less than zero, zero, or greater than zero depending on the comparison Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant C-style string โ€” const char *

Explanation: This function works like ustr_cmp_case_buf() but with a length from strlen().


โœจ the _eq girlies โ€” same energy, just a yes/no answer โœจ

Heads up bestie: all of these return success or failure as an int, instead of the whole less-than/zero/greater-than situation. So much chiller to read ๐Ÿซถ

๐Ÿ’œ ustr_cmp_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *

Explanation: This function works like comparing ustr_cmp() against 0.

๐Ÿ’œ ustr_cmp_buf_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to constant bytes, to compare โ€” const void *
  • Parameter[3]: Length of comparison bytes โ€” size_t

Explanation: This function works like comparing ustr_cmp_buf() against 0.

๐Ÿ’œ ustr_cmp_subustr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: Position in the Ustr โ€” size_t
  • Parameter[4]: Length to compare from the Ustr โ€” size_t

Explanation: This function works like comparing ustr_cmp_subustr() against 0.

๐Ÿ’œ ustr_cmp_cstr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant C-style string โ€” const char *

Explanation: This function works like comparing ustr_cmp_cstr() against 0.

๐Ÿ’œ ustr_cmp_case_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *

Explanation: This function works like comparing ustr_cmp_case() against 0.

๐Ÿ’œ ustr_cmp_case_buf_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to constant bytes, to compare โ€” const void *
  • Parameter[3]: Length of comparison bytes โ€” size_t

Explanation: This function works like comparing ustr_cmp_case_buf() against 0.

๐Ÿ’œ ustr_cmp_case_subustr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: Position in the Ustr โ€” size_t
  • Parameter[4]: Length to compare from the Ustr โ€” size_t

Explanation: This function works like comparing ustr_cmp_case_subustr() against 0.

๐Ÿ’œ ustr_cmp_case_cstr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant C-style string โ€” const char *

Explanation: This function works like comparing ustr_cmp_case_cstr() against 0.


๐ŸŒˆ the _prefix_eq besties โ€” "does it start with this?" energy ๐ŸŒˆ

Okay so these ones are the iconique "is this a prefix of that?" checks. The comparison is capped at the length of the right hand side, so the left side gets to be longer and it's still a slay โœ…

๐ŸŒธ ustr_cmp_prefix_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *

Explanation: This function works like comparing ustr_cmp() against 0, but the comparison is limited to the length of the right hand side.

๐ŸŒธ ustr_cmp_prefix_buf_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to constant bytes, to compare โ€” const void *
  • Parameter[3]: Length of comparison bytes โ€” size_t

Explanation: This function works like comparing ustr_cmp_buf() against 0, but the comparison is limited to the length of the right hand side (Parameter[3]).

๐ŸŒธ ustr_cmp_prefix_cstr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant C-style string โ€” const char *

Explanation: This function works like comparing ustr_cmp_cstr() against 0, but the comparison is limited to the length of the right hand side.

๐ŸŒธ ustr_cmp_prefix_subustr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: Position in the Ustr โ€” size_t
  • Parameter[4]: Length to compare from the Ustr โ€” size_t

Explanation: This function works like comparing ustr_cmp_subustr() against 0, but the comparison is limited to the given length (Parameter[4]).

๐ŸŒธ ustr_cmp_case_prefix_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *

Explanation: This function works like comparing ustr_cmp_case() against 0, but the comparison is limited to the length of the right hand side. (and yes, it's still ignoring ASCII case, bestie โ€” the case is right there in the name ๐Ÿ’…)

๐ŸŒธ ustr_cmp_case_prefix_buf_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to constant bytes, to compare โ€” const void *
  • Parameter[3]: Length of comparison bytes โ€” size_t

Explanation: This function works like comparing ustr_cmp_case_buf() against 0, but the comparison is limited to the length of the right hand side (Parameter[3]).

๐ŸŒธ ustr_cmp_case_prefix_cstr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant C-style string โ€” const char *

Explanation: This function works like comparing ustr_cmp_case_cstr() against 0, but the comparison is limited to the length of the right hand side.

๐ŸŒธ ustr_cmp_case_prefix_subustr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *

ustr_cmp_suffix_subustr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: a pointer to a constant Ustr string โ€” Type[2]: const struct Ustr *
  • Parameter[3]: position in the Ustr โ€” Type[3]: size_t
  • Parameter[4]: length to compare from the Ustr โ€” Type[4]: size_t

Explanation:

This one does the same thing as comparing ustr_cmp_subustr() against 0, except it's looking at the end of the left hand side. Tail-end energy only ๐Ÿ’…


ustr_cmp_case_suffix_eq()

Returns: Success or failure Type: int

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: a pointer to a constant Ustr string โ€” Type[2]: const struct Ustr *

Explanation:

Works exactly like ustr_cmp_case_prefix_eq(), but it's checking the end of the left hand side instead of the start. Same vibe, opposite end ๐ŸŽ€


ustr_cmp_case_suffix_buf_eq()

Returns: Success or failure Type: int

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: a pointer to constant bytes, to compare โ€” Type[2]: const void *
  • Parameter[3]: length of comparison bytes โ€” Type[3]: size_t

Explanation:

Just like ustr_cmp_case_prefix_buf_eq(), except the comparison happens at the end of the left hand side. Case-insensitive, backwards-leaning, iconic ๐Ÿ’–


ustr_cmp_case_suffix_cstr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: a pointer to a constant C-style string โ€” Type[2]: const char *

Explanation:

Behaves like ustr_cmp_case_prefix_cstr_eq() but the end of the left hand side is what's getting compared. Periodt โœจ


ustr_cmp_case_suffix_subustr_eq()

Returns: Success or failure Type: int

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: a pointer to a constant Ustr string โ€” Type[2]: const struct Ustr *
  • Parameter[3]: position in the Ustr โ€” Type[3]: size_t
  • Parameter[4]: length to compare from the Ustr โ€” Type[4]: size_t

Explanation:

It works like comparing ustr_cmp_case_subustr() against 0, but bestie, it compares the end of the left hand side. That's it, that's the whole gig ๐Ÿฆ‹


๐Ÿ”Ž Searching for data in a Ustr ๐Ÿ”Ž

Okay this whole section is the "where tf is it" section and honestly it's lowkey the most useful one. Pay attention to the notes on the reverse ones though, they're sneaky ๐Ÿ‘€


ustr_srch_chr_fwd()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: byte data to search for โ€” Type[3]: char

Explanation:

This hunts down the data in Parameter[3] inside the Ustr, but it first skips Parameter[2] bytes. Forward direction, always ๐ŸŒˆ


ustr_srch_chr_rev()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: byte data to search for โ€” Type[3]: char

Explanation:

Same as ustr_srch_chr_fwd() but it goes from the end of the string back to the beginning. Backwards baddie behaviour ๐Ÿ’…

Note: The searching starts from the end of the string, so the offset is an offset from the end. BUT the position of a byte is always relative to the beginning. So if you're doing a loop you have to take the position from the length. Do not skip this note, I'm literally begging ๐Ÿ˜ญ

ustr_srch_buf_fwd()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: a pointer to data to search for โ€” Type[3]: const void *
  • Parameter[4]: length of the data to search for โ€” Type[4]: size_t

Explanation:

Searches for the data at Parameter[3], which is Parameter[4] bytes long, inside the Ustr, skipping Parameter[2] bytes first. Buffers, forward, flawless ๐Ÿซถ


ustr_srch_buf_rev()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: a pointer to data to search for โ€” Type[3]: const void *
  • Parameter[4]: length of the data to search for โ€” Type[4]: size_t

Explanation:

Exactly like ustr_srch_buf_fwd() except it travels from the end of the string toward the beginning.

Note: Searching starts from the end, so the offset is the offset from the end. The position of a byte though? Always relative to the beginning. For loops, take the position from the length. Same note, same chaos ๐Ÿ™ˆ

ustr_srch_fwd()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: a pointer to a constant Ustr string, to search for โ€” Type[3]: const struct Ustr *

Explanation:

Acts like ustr_srch_buf_fwd(), but it grabs the data pointer by calling ustr_cstr() and the length by calling ustr_len() on the Ustr you handed it in Parameter[3]. Convenient? Extremely ๐Ÿ’–


ustr_srch_rev()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: a pointer to a constant Ustr string, to search for โ€” Type[3]: const struct Ustr *

Explanation:

Like ustr_srch_fwd() but it starts at the end of the string and works its way to the beginning.

Note: The offset is from the end because that's where searching starts. Byte positions are still relative to the beginning though, so for a loop you take the position from the length. Not me repeating myself, the manpage is repeating itself, blame the manpage ๐Ÿ’€

ustr_srch_cstr_fwd()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: a pointer to C-style string data, to search for โ€” Type[3]: const char *

Explanation:

Works like ustr_srch_buf_fwd() except it figures out the length by calling strlen() on Parameter[3]. So like, you don't have to pass a length. Slay ๐ŸŒธ


ustr_srch_cstr_rev()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: a pointer to C-style string data, to search for โ€” Type[3]: const char *

Explanation:

Like ustr_srch_cstr_fwd() but reversed โ€” end of string to the beginning, bestie.

Note: Searching starts from the end, so that offset is measured from the end. Position of a byte is always relative to the beginning, so loops need you to take the position from the length. Third time's the charm ๐Ÿ“

ustr_srch_subustr_fwd()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: a pointer to a constant Ustr string โ€” Type[3]: const struct Ustr *
  • Parameter[4]: position in the Ustr โ€” Type[4]: size_t
  • Parameter[5]: length of data to search, from the Ustr โ€” Type[5]: size_t

Explanation:

Behaves like ustr_srch_fwd() but it shifts the data to start at the right position, then limits the length to the value you passed. Substring searching, but make it โœจpreciseโœจ


ustr_srch_subustr_rev()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: a pointer to a constant Ustr string โ€” Type[3]: const struct Ustr *
  • Parameter[4]: position in the Ustr โ€” Type[4]: size_t
  • Parameter[5]: length of data to search, from the Ustr โ€” Type[5]: size_t

Explanation:

Like ustr_srch_rev() but it moves the data to start at the correct position and caps the length at the value you gave it.

Note: Searching kicks off from the end of the string, so the offset is an offset from the end. Byte positions remain relative to the beginning, so for loops you take the position from the length. Yes, again. It's important, okay ๐Ÿ˜ค

ustr_srch_case_chr_fwd()

Returns: position in the Ustr, or zero if not found Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type[1]: const struct Ustr *
  • Parameter[2]: offset within string to start searching at โ€” Type[2]: size_t
  • Parameter[3]: byte data to search for โ€” Type[3]: char

Explanation:

(โ€ฆokay this one's explanation is literally getting picked up in the next part, hold that thought bestie ๐Ÿ’…)

the case-insensitive searches, cont'd ๐Ÿ’…

Ok so the rest of the ustr_srch_case_* squad โ€” every single one of these is literally just its normal twin but it treats ASCII uppercase and lowercase as the same thing. Slay, case-insensitivity ate.

Function: ustr_srch_case_chr_rev()

  • Returns: Position in the Ustr, or zero if not found
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string to start searching at
  • Type[2]: size_t
  • Parameter[3]: Byte data to search for
  • Type[3]: char

Explanation:

This function works like ustr_srch_chr_fwd(), but treats ASCII uppercase and lowercase as equivalent.


Function: ustr_srch_case_buf_fwd()

  • Returns: Position in the Ustr, or zero if not found
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string to start searching at
  • Type[2]: size_t
  • Parameter[3]: A pointer to data to search for
  • Type[3]: const void *
  • Parameter[4]: Length of the data to search for
  • Type[4]: size_t

Explanation:

This function works like ustr_srch_buf_fwd(), but treats ASCII uppercase and lowercase as equivalent.


Function: ustr_srch_case_buf_rev()

  • Returns: Position in the Ustr, or zero if not found
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string to start searching at
  • Type[2]: size_t
  • Parameter[3]: A pointer to data to search for
  • Type[3]: const void *
  • Parameter[4]: Length of the data to search for
  • Type[4]: size_t

Explanation:

This function works like ustr_srch_buf_rev(), but treats ASCII uppercase and lowercase as equivalent.


Function: ustr_srch_case_fwd()

  • Returns: Position in the Ustr, or zero if not found
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string to start searching at
  • Type[2]: size_t
  • Parameter[3]: A pointer to a constant Ustr string, to search for
  • Type[3]: const struct Ustr *

Explanation:

This function works like ustr_srch_fwd(), but treats ASCII uppercase and lowercase as equivalent.


Function: ustr_srch_case_rev()

  • Returns: Position in the Ustr, or zero if not found
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string to start searching at
  • Type[2]: size_t
  • Parameter[3]: A pointer to a constant Ustr string, to search for
  • Type[3]: const struct Ustr *

Explanation:

This function works like ustr_srch_rev(), but treats ASCII uppercase and lowercase as equivalent.


Function: ustr_srch_case_cstr_fwd()

  • Returns: Position in the Ustr, or zero if not found
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string to start searching at
  • Type[2]: size_t
  • Parameter[3]: A pointer to C-style string data, to search for
  • Type[3]: const char *

Explanation:

This function works like ustr_srch_cstr_fwd(), but treats ASCII uppercase and lowercase as equivalent.


Function: ustr_srch_case_cstr_rev()

  • Returns: Position in the Ustr, or zero if not found
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string to start searching at
  • Type[2]: size_t
  • Parameter[3]: A pointer to C-style string data, to search for
  • Type[3]: const char *

Explanation:

This function works like ustr_srch_cstr_rev(), but treats ASCII uppercase and lowercase as equivalent.


Function: ustr_srch_case_subustr_fwd()

  • Returns: Position in the Ustr, or zero if not found
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string to start searching at
  • Type[2]: size_t
  • Parameter[3]: A pointer to a constant Ustr string
  • Type[3]: const struct Ustr *
  • Parameter[4]: Position in the Ustr
  • Type[4]: size_t
  • Parameter[5]: Length of data to search, from the Ustr
  • Type[5]: size_t

Explanation:

This function works like ustr_srch_subustr_fwd(), but treats ASCII uppercase and lowercase as equivalent.


Function: ustr_srch_case_subustr_rev()

  • Returns: Position in the Ustr, or zero if not found
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string to start searching at
  • Type[2]: size_t
  • Parameter[3]: A pointer to a constant Ustr string
  • Type[3]: const struct Ustr *
  • Parameter[4]: Position in the Ustr
  • Type[4]: size_t
  • Parameter[5]: Length of data to search, from the Ustr
  • Type[5]: size_t

Explanation:

This function works like ustr_srch_subustr_rev(), but treats ASCII uppercase and lowercase as equivalent.


๐ŸŒธ Span lengths of data in a Ustr ๐ŸŒธ

New section bestie!! This one is all about spans โ€” like, how far does a run of matching bytes go from one end? spn = "how many bytes HERE are in the set", cspn = "how many bytes here are NOT in the set" (the complement, hence the c). Two directions: _fwd scans from the start, _rev scans from the end. Iconic symmetry, no cap. โœจ

Function: ustr_spn_chr_fwd()

  • Returns: Number of bytes in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start spanning from
  • Type[2]: size_t
  • Parameter[3]: Byte data
  • Type[3]: char

Explanation:

This function returns the length of the start of the Ustr (Parameter[1]) that only contains bytes that are equal to the data (Parameter[3]), skipping offset (Parameter[2]) bytes.


Function: ustr_spn_chr_rev()

  • Returns: Number of bytes in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start spanning from
  • Type[2]: size_t
  • Parameter[3]: Byte data
  • Type[3]: char

Explanation:

This function returns the length of the end of the Ustr (Parameter[1]) that only contains bytes that are equal to the data (Parameter[3]), skipping offset (Parameter[2]) bytes.


Function: ustr_spn_chrs_fwd()

  • Returns: Number of bytes in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start spanning from
  • Type[2]: size_t
  • Parameter[3]: Array of byte data, for spanning
  • Type[3]: const char *
  • Parameter[4]: Length of byte data, for spanning
  • Type[4]: size_t

Explanation:

This function returns the length of the start of the Ustr (Parameter[1]) that only contains bytes that are equal to any byte in the data (Parameter[3]), skipping offset (Parameter[2]) bytes.


Function: ustr_spn_chrs_rev()

  • Returns: Number of bytes in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start spanning from
  • Type[2]: size_t
  • Parameter[3]: Array of byte data
  • Type[3]: const char *
  • Parameter[4]: Length of byte data
  • Type[4]: size_t

Explanation:

This function returns the length of the end of the Ustr (Parameter[1]) that only contains bytes that are equal to any byte in the data (Parameter[3]), skipping offset (Parameter[2]) bytes.


Function: ustr_spn_fwd()

  • Returns: Number of bytes in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start spanning from
  • Type[2]: size_t
  • Parameter[3]: A pointer to a constant Ustr string, containing spanning bytes
  • Type[3]: const struct Ustr *

Explanation:

This function works like ustr_spn_buf_fwd() but passing ustr_cstr() and ustr_len()


Function: ustr_spn_rev()

  • Returns: Number of bytes in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start spanning from
  • Type[2]: size_t
  • Parameter[3]: A pointer to a constant Ustr string, containing spanning bytes
  • Type[3]: const struct Ustr *

Explanation:

This function works like ustr_spn_buf_rev() but passing ustr_cstr() and ustr_len()


Function: ustr_spn_cstr_fwd()

  • Returns: Number of bytes in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start spanning from
  • Type[2]: size_t
  • Parameter[3]: A pointer to a constant C-style string, containing spanning bytes
  • Type[3]: const char *

Explanation:

This function works like ustr_spn_buf_fwd() but passing strlen() for the length.


Function: ustr_spn_cstr_rev()

  • Returns: Number of bytes in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start spanning from
  • Type[2]: size_t
  • Parameter[3]: A pointer to a constant C-style string, containing spanning bytes
  • Type[3]: const char *

Explanation:

This function works like ustr_spn_buf_rev() but passing strlen() for the length.


Function: ustr_cspn_chr_fwd()

  • Returns: Number of bytes not in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start compliment spanning from
  • Type[2]: size_t
  • Parameter[3]: Byte data
  • Type[3]: char

Explanation:

This function returns the length of the start of the Ustr (Parameter[1]) that only contains bytes that are not equal to the data (Parameter[3]), skipping offset (Parameter[2]) bytes.


Function: ustr_cspn_chr_rev()

  • Returns: Number of bytes not in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start compliment spanning from
  • Type[2]: size_t
  • Parameter[3]: Byte data
  • Type[3]: char

Explanation:

This function returns the length of the end of the Ustr (Parameter[1]) that only contains bytes that are not equal to the data (Parameter[3]), skipping offset (Parameter[2]) bytes.


Function: ustr_cspn_chrs_fwd()

  • Returns: Number of bytes not in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr string
  • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, to start compliment spanning from
  • Type[2]: size_t
  • Parameter[3]: Array of byte data
  • Type[3]: const char *
  • Parameter[4]: Length of byte data
  • Type[4]: size_t

Explanation:

This function returns the length of the start of the Ustr (Parameter[1]) that only contains bytes that are not equal to any byte in the data (Parameter[3]), skipping offset (Parameter[2]) bytes.


Function: ustr_cspn_chrs_rev()

  • Returns: Number of bytes not in the span
  • Type: size_t

okay so picking right back up with the tail end of that last function โ€” here's its full param roster ๐Ÿ‘‡

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, where the compliment spanning starts โ€” Type: size_t
  • Parameter[3]: an array of byte data โ€” Type: const char *
  • Parameter[4]: length of that byte data โ€” Type: size_t

Explanation: this one hands you back the length of the end of the Ustr (Parameter[1]) that only contains bytes which are not equal to any byte in the data (Parameter[3]), skipping Parameter[2] bytes first. no cap, that's the whole vibe ๐Ÿ’…


๐ŸŽ€ ustr_cspn_fwd()

Returns: number of bytes not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, where the compliment spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant Ustr string holding the spanning bytes โ€” Type: const struct Ustr *

Explanation: works exactly like ustr_cspn_buf_fwd(), it's just passing ustr_cstr() and ustr_len() for you. convenience king ๐Ÿ‘‘

๐ŸŽ€ ustr_cspn_rev()

Returns: number of bytes not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, where the compliment spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant Ustr string holding the spanning bytes โ€” Type: const struct Ustr *

Explanation: works like ustr_cspn_buf_rev(), again just passing ustr_cstr() and ustr_len() โœจ

๐ŸŽ€ ustr_cspn_cstr_fwd()

Returns: number of bytes not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, where the compliment spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant C-style string holding the spanning bytes โ€” Type: const char *

Explanation: works like ustr_cspn_buf_fwd() but it passes strlen() for the length. classic C-string behavior, we love a shortcut ๐Ÿซถ

๐ŸŽ€ ustr_cspn_cstr_rev()

Returns: number of bytes not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, to start spanning from โ€” Type: size_t
  • Parameter[3]: a pointer to a constant C-style string holding the spanning bytes โ€” Type: const char *

Explanation: works like ustr_cspn_buf_rev() but it passes strlen() for the length ๐ŸŒธ


๐Ÿฆ‹ ustr_utf8_spn_chrs_fwd()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant C-style UTF-8 string โ€” Type: const char *
  • Parameter[4]: length of the C-style UTF-8 string โ€” Type: size_t

Explanation: works like ustr_spn_chrs_fwd() but the return value, the offset and the length all count UTF-8 characters, not bytes. character girl math, not byte math ๐Ÿ’…

Note: this is much slower than ustr_spn_chrs_fwd(), but like โ€” give it "xy" as a multi-byte UTF-8 character and it actually understands that the span over "xyxz" is 1 UTF-8 character and not 3 bytes. she's thorough, not fast ๐Ÿ˜ญ

๐Ÿฆ‹ ustr_utf8_spn_chrs_rev()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant C-style UTF-8 string โ€” Type: const char *
  • Parameter[4]: (the manpage literally leaves this one blank, bestie โ€” the type is all it gives us) โ€” Type: size_t

Explanation: works like ustr_spn_chrs_rev() but the return value, the offset and the length all use UTF-8 characters instead of bytes ๐ŸŒˆ

Note: much slower than ustr_spn_chrs_rev(), but hand it "xy" as a multi-byte UTF-8 character and it gets that the span over "xyxz" is 1 UTF-8 character and not 3 bytes. iconic attention to detail โœจ

๐Ÿฆ‹ ustr_utf8_spn_fwd()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *

Explanation: works like ustr_spn_fwd() but the return value, the offset and the length all use UTF-8 characters, not bytes ๐ŸŽ€

Note: much slower than ustr_spn_fwd(), but with "xy" as a multi-byte UTF-8 character it knows the span over "xyxz" is 1 UTF-8 character and not 3 bytes ๐Ÿ’–

๐Ÿฆ‹ ustr_utf8_spn_rev()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *

Explanation: works like ustr_spn_rev() but the return value, the offset and the length all use UTF-8 characters, not bytes ๐ŸŒธ

Note: much slower than ustr_spn_rev(), but given "xy" as a multi-byte UTF-8 character it understands the span over "xyxz" is 1 UTF-8 character and not 3 bytes ๐Ÿ‘‘

๐Ÿฆ‹ ustr_utf8_spn_cstr_fwd()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant C-style UTF-8 string โ€” Type: const char *

Explanation: works like ustr_spn_cstr_fwd() but the return value, the offset and the length all use UTF-8 characters, not bytes ๐Ÿ’œ

Note: much slower than ustr_spn_cstr_fwd(), but with "xy" as a multi-byte UTF-8 character it understands the span over "xyxz" is 1 UTF-8 character, not 3 bytes ๐Ÿฆ‹

๐Ÿฆ‹ ustr_utf8_spn_cstr_rev()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant C-style UTF-8 string โ€” Type: const char *

Explanation: works like ustr_spn_cstr_rev() but the return value, the offset and the length all use UTF-8 characters, not bytes ๐Ÿ“

Note: much slower than ustr_spn_cstr_rev(), but given "xy" as a multi-byte UTF-8 character it gets that the span over "xyxz" is 1 UTF-8 character and not 3 bytes ๐Ÿงš


๐Ÿ”ฅ ustr_utf8_cspn_chrs_fwd()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where compliment spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant C-style UTF-8 string โ€” Type: const char *
  • Parameter[4]: length of the C-style UTF-8 string โ€” Type: size_t

Explanation: works like ustr_cspn_chrs_fwd() but the return value, the offset and the length all use UTF-8 characters, not bytes ๐Ÿ’…

Note: much slower than ustr_cspn_chrs_fwd(), but given "xy" as a multi-byte UTF-8 character it understands the compliment span over "xzxy" is 1 UTF-8 character and not 0 bytes. yes bestie, one, not zero ๐Ÿ˜ญ

๐Ÿ”ฅ ustr_utf8_cspn_chrs_rev()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where compliment spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant C-style UTF-8 string โ€” Type: const char *
  • Parameter[4]: length of the C-style UTF-8 string โ€” Type: size_t

Explanation: works like ustr_cspn_chrs_rev() but the return value, the offset and the length all use UTF-8 characters, not bytes ๐ŸŽ€

Note: much slower than ustr_cspn_chrs_rev(), but with "xy" as a multi-byte UTF-8 character it understands the compliment span over "xzxy" is 1 UTF-8 character and not 0 bytes โœจ

๐Ÿ”ฅ ustr_utf8_cspn_fwd()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where compliment spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to a constant Ustr UTF-8 string holding the spanning data โ€” Type: const struct Ustr *

Explanation: works like ustr_cspn_fwd() but the return value, the offset and the length all use UTF-8 characters, not bytes ๐ŸŒˆ

Note: much slower than ustr_cspn_fwd(), but given "xy" as a multi-byte UTF-8 character it understands the compliment span over "xzxy" is 1 UTF-8 character and not 0 bytes ๐Ÿ’–

๐Ÿ”ฅ ustr_utf8_cspn_rev()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where compliment spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to constant Ustr UTF-8 string data holding the spanning data โ€” Type: const struct Ustr *

Explanation: works like ustr_cspn_rev() but the return value, the offset and the length all use UTF-8 characters, not bytes ๐Ÿฆ‹

Note: much slower than ustr_cspn_rev(), but with "xy" as a multi-byte UTF-8 character it understands the compliment span over "xzxy" is 1 UTF-8 character and not 0 bytes ๐ŸŒธ

๐Ÿ”ฅ ustr_utf8_cspn_cstr_fwd()

Returns: number of UTF-8 characters not in the span โ€” Type: size_t

  • Parameter[1]: a pointer to a constant Ustr UTF-8 string โ€” Type: const struct Ustr *
  • Parameter[2]: offset within the string, in UTF-8 characters, where compliment spanning starts โ€” Type: size_t
  • Parameter[3]: a pointer to constant C-style UTF-8 string data holding the spanning data โ€” Type: const char *

Explanation: works like ustr_cspn_cstr_fwd() but the return value, the offset and the length all use UTF-8 characters, not bytes ๐Ÿ‘‘

Note:

Note (still carrying on from the last function): This is much slower than ustr_cspn_cstr_fwd() but given "xy" as a multi-byte UTF-8 character it understands that the compliment span over "xzxy" is 1 UTF-8 character and not 0 bytes.

๐Ÿ’… Function: ustr_utf8_cspn_cstr_rev() ๐Ÿ’…

  • Returns: Number of UTF-8 characters not in the span
  • Type: size_t
  • Parameter[1]: A pointer to a constant Ustr UTF-8 string
    • Type[1]: const struct Ustr *
  • Parameter[2]: Offset within string, in UTF-8 characters, to start compliment spanning from
    • Type[2]: size_t
  • Parameter[3]: A pointer to C-style UTF-8 string data, containing spanning data
    • Type[3]: const char *

Explanation: This function works like ustr_cspn_cstr_rev() but the return value, offset, and length all use UTF-8 characters and not bytes.

Note: This is much slower than ustr_spn_cstr_rev() but given "xy" as a multi-byte UTF-8 character it understands that the compliment span over "xzxy" is 1 UTF-8 character and not 0 bytes.

๐ŸŒˆ Doing IO from or to a Ustr ๐ŸŒˆ

okay bestie, this is the file-IO era: reading bytes into a Ustr and writing bytes back out. Weโ€™ve got FILE * objects, delimiters, errno notes, the whole vibe. Letโ€™s go ๐Ÿซถ

๐ŸŽ€ Function: ustr_io_get() ๐ŸŽ€

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: A pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a C file object
    • Type[2]: FILE *
  • Parameter[3]: Number of bytes to read
    • Type[3]: size_t
  • Parameter[4]: Returned number of bytes read
    • Type[4]: size_t *

Explanation: This function tries to read a minimum number of bytes from the file object, into the Ustr string. The exact number read is returned, unless (Parameter[4]) is NULL.

๐ŸŒธ Function: ustr_io_getfile() ๐ŸŒธ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a C file object
    • Type[2]: FILE *

Explanation: This function calls ustr_io_get() repeatedly until EOF is encountered.

Note: The errno value when this function ends could either be from fopen(), fread(), or if both of those succeeded from fclose().

๐Ÿฆ‹ Function: ustr_io_getfilename() ๐Ÿฆ‹

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A C-style string of a filename
    • Type[2]: const char *

Explanation: This function opens a specified file, and then calls ustr_io_getfile(). Finally closing the FILE * object.

โญ Function: ustr_io_getdelim() โญ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a C file object
    • Type[2]: FILE *
  • Parameter[3]: A delimiter byte to stop reading at
    • Type[3]: char

Explanation: This function reads bytes from the file until it hits the delimiter byte.

Note: The delimiter is included, use ustr_del() to remove 1 byte from the end if you don't want it. This function assumes a delimiter will happen every 80 bytes or so.

๐Ÿ“ Function: ustr_io_getline() ๐Ÿ“

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a C file object
    • Type[2]: FILE *

Explanation: This function works like calling ustr_io_getdelim() with '\n' as the delimiter.

๐Ÿ’– Function: ustr_io_put() ๐Ÿ’–

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a C file object
    • Type[2]: FILE *
  • Parameter[3]: Number of bytes to write
    • Type[3]: size_t

Explanation: This function is the opposite of ustr_io_get(), taking bytes from the beginning of the Ustr and writing them to the file.

Note: Deleting bytes from the beginning of a Ustr string is the most inefficient thing to do, so it is recommended to use ustr_io_putfile().

๐Ÿงš Function: ustr_io_putline() ๐Ÿงš

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a C file object
    • Type[2]: FILE *
  • Parameter[3]: Number of bytes to write
    • Type[3]: size_t

Explanation: This function works like calling ustr_io_put(), and then writing a '\n' to the file.

Note: This doesn't write a line from the Ustr to the file, if you want that call ustr_io_put() directly, using the return from ustr_srch_chr_fwd() (with a '\n') as the number of bytes argument.

๐Ÿ’œ Function: ustr_io_putfile() ๐Ÿ’œ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a C file object
    • Type[2]: FILE *

Explanation: This function works like calling ustr_io_put() with ustr_len() as the number of bytes.

๐Ÿ‘‘ Function: ustr_io_putfileline() ๐Ÿ‘‘

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a C file object
    • Type[2]: FILE *

Explanation: This function works like calling ustr_io_putline() with ustr_len() as the number of bytes.

๐Ÿ”ฅ Function: ustr_io_putfilename() ๐Ÿ”ฅ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: A C-style string of a filename
    • Type[2]: const char *
  • Parameter[3]: A C-style string of a filemode (the second argument to fopen)
    • Type[3]: const char *

Explanation: This function opens a specified file, and then calls ustr_io_putfile(). Finally closing the FILE * object.

Note: The errno value when this function ends could either be from fopen(), fwrite(), or if both of those succeeded from fclose().

โœจ String substitution/replacement โœจ

String substitution/replacement โ€” the part where we swap out a chunk and slide new data in. Letโ€™s go, bestie ๐Ÿ’–

๐ŸŽ€ Function: ustr_sub_undef() ๐ŸŽ€

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr
    • Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution
    • Type[2]: size_t
  • Parameter[3]: Length of undefined data
    • Type[3]: size_t

Explanation: The Ustr string is expanded as required (possibly reallocated) so that it can contain length (Parameter[2]) data, from the required position. If the length is not zero the Ustr will be writable. Or it'll return USTR_FALSE (zero) on failure.

Note: You can think of the operation as two separate tasks, one which makes the current data in the Ustr undefined and the second which adds undefined data to the ustr to accommodate the desired length.

๐ŸŒˆ Function: ustr_sub_buf() ๐ŸŒˆ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr
    • Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution
    • Type[2]: size_t
  • Parameter[3]: Buffer containing substitution string
    • Type[3]: const void *
  • Parameter[4]: Length of buffer
    • Type[4]: size_t

Explanation: This function works as if you had called ustr_sub_undef() and then copied the data into the new undefined space.

๐Ÿฆ‹ Function: ustr_sub_cstr() ๐Ÿฆ‹

  • Returns: success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr
    • Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution
    • Type[2]: size_t
  • Parameter[3]: A pointer to a constant C-style string, which is the substitution
    • Type[3]: const char *

Explanation: This function works like ustr_sub_buf() but the length is worked out automatically by strlen().

๐Ÿ’ซ Function: USTR_SUB_OSTR() ๐Ÿ’ซ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution
    • Type[2]: size_t
  • Parameter[3]: A constant C-style string
    • Type[3]: const char []

Explanation: This function works as if you had called ustr_sub_buf() and passed sizeof() - 1 as the length.

๐ŸŒŸ Function: USTR_SUB_OBJ() ๐ŸŒŸ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution
    • Type[2]: size_t
  • Parameter[3]: A symbol
    • Type[3]: ...

Explanation: This function works as if you had called ustr_sub_buf() and passed sizeof() as the length.

Note: In most cases you'll want to use USTR_SUB_OSTR().

๐Ÿ’œ Function: ustr_sub() ๐Ÿ’œ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution
    • Type[2]: size_t
  • Parameter[3]: A pointer to a constant Ustr string
    • Type[3]: const struct Ustr *

Explanation: This function works as if you had called ustr_sub_buf() with the ustr_cstr() and ustr_len() values of the Ustr string to be added. The exception being if you substitute a ustr into itself, while only having a single reference count, the simple method could access a free'd ustr data, but this function just works.

๐Ÿงš Function: ustr_sub_subustr() ๐Ÿงš

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution
    • Type[2]: size_t
  • Parameter[3]: A pointer to a constant Ustr string
    • Type[3]: const struct Ustr *
  • Parameter[4]: Position in the Ustr
    • Type[4]: size_t
  • Parameter[5]: Length to substitute from the Ustr
    • Type[5]: size_t

Explanation: This function works mostly as if you had called ustr_sub_buf() with the ustr_cstr() + position - 1 and length values of the Ustr string to be insed. The exception being if you insert a ustr to itself, while only having a single reference count, the simple method would access a free'd ustr data, but this function just works.

๐Ÿ”ฅ Function: ustr_sc_sub_undef() ๐Ÿ”ฅ

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr
    • Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution
    • Type[2]: size_t
  • Parameter[3]: Length of substitution
    • Type[3]: size_t
  • Parameter[4]: Length of undefined data
    • Type[4]: size_t

Explanation: This function works as if you had done ustr_del_subustr() followed by ustr_ins_undef(), however it is significantly more efficient.

๐Ÿ’– Function: ustr_sc_sub_buf() ๐Ÿ’–

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr
    • Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution
    • Type[2]: size_t
  • Parameter[3]: Length of substitution
    • Type[3]: size_t
  • Parameter[4]: Buffer containing substitute data
    • Type[4]: const void *
  • Parameter[5]: Length of Buffer
    • Type[5]: size_t

Explanation: โ€ฆ

okay so this function will substitute a specific number of characters in a Ustr with the data from a buffer, and it does the job of one or more of ustr_add_buf(), ustr_sub_buf() and ustr_del(). ๐Ÿ’…


๐Ÿ’– Function: ustr_sc_sub_cstr()

Returns: Success or failure Type: int

  • Parameter[1]: Pointer to a pointer to a Ustr โ€” Type[1]: struct Ustr **
  • Parameter[2]: Position where to start replacement โ€” Type[2]: size_t
  • Parameter[3]: Length of substitution โ€” Type[3]: size_t
  • Parameter[4]: A pointer to a constant C-style string, containing spanning bytes โ€” Type[4]: const char *

Explanation:

This one works like ustr_sc_sub_buf(), except the length is worked out automatically by strlen(). cute and convenient, honestly. โœจ


๐Ÿฆ‹ Function: ustr_sc_sub()

Returns: success or failure Type: int

  • Parameter[1]: Pointer to a pointer to a Ustr โ€” Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution โ€” Type[2]: size_t
  • Parameter[3]: Length of substitution โ€” Type[3]: size_t
  • Parameter[4]: Pointer to a Ustr containing the substitute string โ€” Type[4]: const struct Ustr *

Explanation:

This function works as if you had called ustr_sc_sub_buf() with the ustr_cstr() and ustr_len() values of the Ustr string to be added. The exception is when you substitute a ustr into itself while only having a single reference count โ€” the simple method could access a free'd ustr data, but this function just works. no cap, that's the whole point. ๐Ÿ’€


๐ŸŒธ Function: ustr_sc_sub_subustr()

Returns: Success or failure Type: int

  • Parameter[1]: Pointer to a pointer to a Ustr โ€” Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution โ€” Type[2]: size_t
  • Parameter[3]: Length of substitution โ€” Type[3]: size_t
  • Parameter[4]: A pointer to a constant Ustr string โ€” Type[4]: const struct Ustr *
  • Parameter[5]: Position in the Ustr โ€” Type[5]: size_t
  • Parameter[6]: Length to substitute from the Ustr โ€” Type[6]: size_t

Explanation:

This function mostly works as if you had called ustr_sc_sub_buf() with the ustr_cstr() + position - 1 and length values of the Ustr string you're putting in. The exception is if you insert a ustr into itself while only having a single reference count โ€” the simple method would access a free'd ustr data, but this function just works. ๐Ÿซถ


๐ŸŽ€ Function: USTR_SC_SUB_OSTR()

Returns: Success or failure Type: int

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution โ€” Type[2]: size_t
  • Parameter[3]: Length of substitution โ€” Type[3]: size_t
  • Parameter[4]: A constant C-style string โ€” Type[4]: const char []

Explanation:

This function works as if you had called ustr_sc_sub_buf() and passed sizeof() - 1 as the length. periodt. ๐Ÿ’–


๐Ÿ‘‘ Function: USTR_SC_SUB_OBJ()

Returns: Success or failure Type: int

  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” Type[1]: struct Ustr **
  • Parameter[2]: Position where to start substitution โ€” Type[2]: size_t
  • Parameter[3]: Length of substitution โ€” Type[3]: size_t
  • Parameter[4]: A symbol โ€” Type[4]: ...

Explanation:

This function works as if you had called ustr_sc_sub_buf() and passed sizeof() as the length. ๐ŸŒˆ

๐Ÿ’ก Note: In most cases you'll want to use USTR_SUB_OSTR().

๐Ÿ“ Function: ustr_replace_buf()

Returns: Number of tokens replaced Type: size_t

  • Parameter[1]: Pointer to a pointer to a Ustr (haystack) โ€” Type[1]: struct Ustr **
  • Parameter[2]: Buffer containing search data โ€” Type[2]: const void *
  • Parameter[3]: Length of search buffer โ€” Type[3]: size_t
  • Parameter[4]: Buffer containing replacement data โ€” Type[4]: const void *
  • Parameter[5]: Length of replacement buffer โ€” Type[5]: size_t
  • Parameter[6]: Maximum number of matches to replace (0 for unlimited) โ€” Type[6]: size_t

Explanation:

This function scans the "haystack" (Parameter[1]) for the "needle" (Parameter[2]) and replaces max_replacements (Parameter[6]) matches with the "replacement" (Parameter[4]). ๐Ÿ”ฅ

๐ŸŒŸ Note: If max_replacements (Parameter[6]) is 0, this function will replace ALL occurrences.

๐Ÿงš Function: ustr_replace_cstr()

Returns: Number of tokens replaced Type: size_t

  • Parameter[1]: Pointer to a pointer to a Ustr (haystack) โ€” Type[1]: struct Ustr **
  • Parameter[2]: A pointer to a constant C-style string, containing search bytes โ€” Type[2]: const char *
  • Parameter[3]: A pointer to a constant C-style string, containing replacement bytes โ€” Type[3]: const char *
  • Parameter[4]: Maximum number of matches to replace (0 for unlimited) โ€” Type[4]: size_t

Explanation:

This function works like ustr_replace_buf() but gets the lengths for the buffer automatically from strlen(). bestie behavior, honestly. โœจ


๐Ÿ’œ Function: ustr_replace()

Returns: Number of tokens replaced Type: int

  • Parameter[1]: Pointer to a pointer to a Ustr (haystack) โ€” Type[1]: struct Ustr **
  • Parameter[2]: Ustr to search for (needle) โ€” Type[2]: const struct Ustr *
  • Parameter[3]: Ustr to replace needle with โ€” Type[3]: const struct Ustr *
  • Parameter[4]: Maximum number of matches to replace (0 for unlimited) โ€” Type[4]: size_t

Explanation:

This function works like ustr_replace_buf() but gets the lengths from the ustr automatically. lowkey iconic. ๐Ÿ’…


๐ŸŽ€ Function: ustr_replace_rep_chr()

Returns: number of replacements made Type: size_t

  • Parameter[1]: pointer to a pointer to a Ustr to be modified โ€” Type[1]: struct Ustr **ps1
  • Parameter[2]: character to replace โ€” Type[2]: char
  • Parameter[3]: number of characters to replace โ€” Type[3]: size_t
  • Parameter[4]: character to replace with โ€” Type[4]: char
  • Parameter[5]: number of characters to replace with โ€” Type[5]: size_t nlen
  • Parameter[6]: maximum number of replacements to make (use 0 for unlimited) โ€” Type[6]: size_t lim

Explanation:

This function replaces a repeating sequence of characters with another repeating sequence of characters. For example...

Ustr *data = ustr_dup_cstr("xxxBxxCxDxxx");
ustr_replace_rep_chr(&data,'x',2,'y',1, 0)

...would change data to be "yxByCxDyx". ๐Ÿฆ‹

๐Ÿ’€ Note: Changing the same letter the same number of times is considered a No-op since it is a vast performance improvement this way. So passing in (&data,'y',2,'y',2 ,0) will have a return value of 0 and the string will be unchanged.

โœจ Splitting a Ustr โœจ

okay so next up: splitting a Ustr into tokens. Think strtok() energy, but with way more control and way more flags. Bestie, read the notes โ€” especially the memory-freeing bits, because that's the main-character plot twist. ๐Ÿ’…

ustr_split_buf()

  • Returns: pointer to a Ustr representing the next token (struct Ustr *)
  • Parameter[1]: pointer to a constant Ustr to be split (const struct Ustr *)
  • Parameter[2]: pointer to an offset (size_t *)
  • Parameter[3]: buffer to use as split search pattern (const void *)
  • Parameter[4]: length of buffer (size_t)
  • Parameter[5]: pointer to a Ustr to be used as the return value (struct Ustr *)
  • Parameter[6]: flags with the prefix USTR_FLAG_SPLIT_ (unsigned int)

This function works in a manner similar to strtok(). Each time you call it, the string inside the buffer (Parameter[3]) is used as a search pattern at which to split. If the pattern is not found, the entire string will be returned. A USTR_NULL return value indicates there are no more tokens remaining.

Parameter[5] is a pointer to a Ustr where the return value will be placed. Passing USTR_NULL to this parameter will cause the string to be allocated and MUST be freed manually. If, however, you pass in a non-null Ustr to this parameter, each call to ustr_split_buf() will free what is in this pointer and place the new token there (when USTR_NULL is returned, nothing needs to be free'd). For example, given...

Ustr *data = ...;
Ustr *tok = USTR_NULL;
const char *sep = ",";
size_t off = 0;
unsigned int flags = USTR_FLAGS_SPLIT_DEF;

...there are two options...

while ((tok = ustr_split_buf(data, &off, sep, strlen(sep), tok, flags)))
{
  /* Do something with tok -- but next iteration of the loop will free
   * and overwrite tok, so you must ustr_dup() if you want to keep it */
}
/* tok is now NULL again after the loop */

...or...

while ((tok = ustr_split_buf(data, &off, sep, strlen(sep), USTR_NULL, flags)))
{
  /* Do something with tok, and it will NOT be freed in the next iteration of
   * the loop */
    ustr_free(tok); /* have to free to avoid mem leaks */
}

...the former of which being the safer option. ๐Ÿซถ

Note: there are several flags that will alter the behaviour of this function, all with the prefix USTR_FLAG_SPLIT_ and the default being USTR_FLAG_SPLIT_DEF.
If you are calling this function directly, it is very likely that you'd want to use ustr_split_cstr() instead.

ustr_split()

  • Returns: pointer to a Ustr representing the next token (struct Ustr *)
  • Parameter[1]: pointer to a constant Ustr to be split (const struct Ustr *)
  • Parameter[2]: pointer to an offset variable (size_t *)
  • Parameter[3]: pointer to a constant Ustr to use as the split search pattern (const struct Ustr *)
  • Parameter[4]: pointer to a Ustr where the return value will be placed (struct Ustr *)
  • Parameter[5]: flags (unsigned int)

Works like ustr_split_buf() but takes a Ustr as the split search pattern instead. Same vibe, different separator container. ๐ŸŽ€


ustr_split_cstr()

  • Returns: pointer to a Ustr representing the next token (struct Ustr *)
  • Parameter[1]: pointer to a constant Ustr to be split (const struct Ustr *)
  • Parameter[2]: pointer to an offset variable (size_t *)
  • Parameter[3]: C string to use as split search pattern (const char *)
  • Parameter[4]: pointer to a Ustr where the return value will be placed (struct Ustr *)
  • Parameter[5]: flags (unsigned int)

Works like ustr_split_buf() but takes a C string as the split search pattern, and so gets the length via strlen(). Classic C-string behavior, no cap. โœจ


ustr_split_spn_chrs()

  • Returns: pointer to a Ustr representing the next token (struct Ustr *)
  • Parameter[1]: pointer to a Ustr to be split (const struct Ustr *)
  • Parameter[2]: pointer to an offset variable (size_t *)
  • Parameter[3]: string representing a set of bytes to use as split chars (const char *)
  • Parameter[4]: length of the string of set of bytes (size_t)
  • Parameter[5]: pointer to a Ustr where the return value will be placed (struct Ustr *)
  • Parameter[6]: flags (unsigned int)

Works like ustr_split_buf() but uses the individual ASCII bytes in the separator string (Parameter[3]) as search patterns. It will split if ANY of these individual characters are matched (much like strtok()). For example: if splitting "this, is,a test" with the separator string ", " the tokens returned would be {"this" "is" "a" "test"}.

Note: if you are calling this function directly, it is very likely that you'd want to use ustr_split_spn_cstr() instead.

ustr_split_spn_cstr()

  • Returns: pointer to a Ustr representing the next token (struct Ustr *)
  • Parameter[1]: pointer to a Ustr to be split (const struct Ustr *)
  • Parameter[2]: pointer to an offset variable (size_t *)
  • Parameter[3]: string representing a set of bytes to use as split chars (const char *)
  • Parameter[4]: pointer to a Ustr where the return value will be placed (struct Ustr *)
  • Parameter[5]: flags (unsigned int)

Works like ustr_split_spn_chrs() but gets the length automatically via strlen(). So convenient, honestly. ๐Ÿ’–


ustr_split_spn()

  • Returns: pointer to a Ustr representing the next token (struct Ustr *)
  • Parameter[1]: pointer to a constant Ustr to be split (const struct Ustr *)
  • Parameter[2]: pointer to an offset variable (size_t *)
  • Parameter[3]: pointer to a constant Ustr to use as the split search pattern (const struct Ustr *)
  • Parameter[4]: pointer to a Ustr where the return value will be placed (struct Ustr *)
  • Parameter[5]: flags (unsigned int)

Works like ustr_split_spn_chrs() but takes a Ustr as the split chars instead. Same split-char logic, but the separator set is a whole Ustr now. ๐Ÿฆ‹


๐ŸŒˆ Dealing with UTF-8 in a Ustr ๐ŸŒˆ

Now we're getting into the cute-but-technical part: UTF-8. These functions are here to help you validate, count, measure, convert, and even reverse UTF-8 strings. Unicode bestie era fr fr. ๐Ÿงš

ustr_utf8_valid()

  • Returns: a boolean flag of either USTR_TRUE or USTR_FALSE (int)
  • Parameter[1]: a pointer to a constant Ustr string (const struct Ustr *)

This function tries its best to find out if the string is a valid UTF-8 string. It's giving "vibe check but for byte sequences." โœ…


ustr_utf8_len()

  • Returns: the number of the UTF-8 characters in the Ustr (size_t)
  • Parameter[1]: a pointer to a constant Ustr string (const struct Ustr *)

This function counts the number of UTF-8 characters in the Ustr.

Note: this function gives undefined answers on strings that aren't UTF-8 valid. So maybe don't do that, bestie. ๐Ÿ˜ญ

ustr_utf8_width()

  • Returns: ssize_t (ssize_t)
  • Parameter[1]: a pointer to a constant Ustr string (const struct Ustr *)

This function returns the visible width of the string, assuming it is a valid UTF-8 string. This is like converting to wide characters and using wcwidth(). It's literally the "how wide does this look on screen" function. ๐Ÿ‘‘


ustr_utf8_chars2bytes()

  • Returns: length of span in bytes (size_t)
  • Parameter[1]: a pointer to a constant Ustr string (const struct Ustr *)
  • Parameter[2]: position of a span in UTF-8 characters (size_t)
  • Parameter[3]: length of a span in UTF-8 characters (size_t)
  • Parameter[4]: returns the position of the span in bytes (size_t *)

This function converts a span, in UTF-8 characters, to the same span in bytes. Character math โ†’ byte math, slay. ๐Ÿ”ฅ


ustr_utf8_bytes2chars()

  • Returns: returns the position of a span in UTF-8 characters (size_t)
  • Parameter[1]: a pointer to a constant Ustr string (const struct Ustr *)
  • Parameter[2]: position of a span in bytes (size_t)
  • Parameter[3]: length of a span in bytes (size_t)
  • Parameter[4]: returns length of a span in UTF-8 characters (size_t *)

This function converts a span, in bytes, to the same span in UTF-8 characters. Byte math โ†’ character math, iconic. ๐Ÿ’…

Note: because a byte span can start or end within a UTF-8 character, converting the return values back into bytes via ustr_utf8_chars2bytes() may make the span be slightly bigger (position slightly earlier, and the length slightly longer). So don't expect a perfect round trip every time โ€” it's giving "close enough, bestie." ๐Ÿ™ˆ

ustr_sc_utf8_reverse()

  • Returns: success or failure (int)
  • Parameter[1]: a pointer to a pointer to a Ustr string (struct Ustr **)

This function reverses the UTF-8 characters in the Ustr string, assuming it is a valid UTF-8 string, so the last one becomes the first and the second to last becomes the second etc. Not me making the whole string do a 180. ๐Ÿ”„โœจ

โœจ Parsing ASCII integer numbers from a Ustr โœจ

okay bestie, this is the part where we teach a Ustr to read numbers out of itself ๐Ÿ‘‘ like full on "hey string, what does this text actually mean as an int?" energy. Literally every function here returns the parsed number or zero on error (yes, zero is the "something went sideways" vibe check), and every single one takes a base of 2โ€“36 plus flags starting with USTR_FLAG_PARSE_NUM_. periodt.


๐ŸŒธ Function: ustr_parse_uintmaxx()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” uintmax_t
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” absolute minimum value โ€” uintmax_t
  • Parameter[5] โ€” absolute maximum value โ€” uintmax_t
  • Parameter[6] โ€” thousands separator โ€” const char *
  • Parameter[7] โ€” return length of parsed number โ€” size_t *
  • Parameter[8] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐Ÿ’…

This function parses an ASCII representation of a number from a Ustr (Parameter[1]) starting at the offset (Parameter[2]). it's the full-control version โ€” you hand it the min, the max, the separator, and out it comes ๐Ÿซถ

๐ŸŽ€ Note: if stdint.h isn't available this function won't be available. no stdint, no entry, sorry bestie.

๐Ÿฆ‹ Function: ustr_parse_uintmax()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” uintmax_t
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” return length of parsed number โ€” size_t *
  • Parameter[5] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐Ÿ’–

This function works like ustr_parse_uintmaxx() with the minimum and maximum values taken as 0 and UINTMAX_MAX, and the thousands separator as "_". the chill version of the icon above โญ

๐ŸŽ€ Note: if stdint.h isn't available this function won't be available.

๐ŸŒˆ Function: ustr_parse_intmax()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” intmax_t
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” return length of parsed number โ€” size_t *
  • Parameter[5] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐Ÿ’œ

This function works like ustr_parse_uintmaxx() with the minimum and maximum values taken as -INTMAX_MIN and INTMAX_MAX, and the thousands separator as "_". signed gang, we're so back ๐Ÿ˜ค

๐ŸŽ€ Note: if stdint.h isn't available this function won't be available.

๐Ÿงš Function: ustr_parse_ulongx()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” unsigned long
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” absolute minimum value โ€” unsigned long
  • Parameter[5] โ€” absolute maximum value โ€” unsigned long
  • Parameter[6] โ€” thousands separator โ€” const char *
  • Parameter[7] โ€” return length of parsed number โ€” size_t *
  • Parameter[8] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐Ÿ‘‘

This function works like ustr_parse_uintmaxx() but returns an unsigned long. and here's the main character detail: it is always available even when stdint.h isn't. no cap, this one shows up no matter what ๐Ÿ”ฅ


๐Ÿ“ Function: ustr_parse_ulong()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” unsigned long
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” return length of parsed number โ€” size_t *
  • Parameter[5] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐ŸŒธ

This function works like ustr_parse_ulongx() with the minimum and maximum values taken as 0 and ULONG_MAX, and the thousands separator as "_". classic defaults, ate ๐Ÿ’…


๐Ÿซถ Function: ustr_parse_long()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” long
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” return length of parsed number โ€” size_t *
  • Parameter[5] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐Ÿ’€

This function works like ustr_parse_ulongx() with the minimum and maximum values taken as -LONG_MIN and LONG_MAX, and the thousands separator as "_". negative numbers finally get their moment โœจ


๐ŸŽ€ Function: ustr_parse_uint()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” unsigned int
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” return length of parsed number โ€” size_t *
  • Parameter[5] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐Ÿฆ‹

This function works like ustr_parse_ulongx() with the minimum and maximum values taken as 0 and UINT_MAX, and the thousands separator as "_". your everyday unsigned lil guy, lowkey iconic ๐ŸŒŸ


๐ŸŒŸ Function: ustr_parse_int()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” int
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” return length of parsed number โ€” size_t *
  • Parameter[5] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐Ÿ˜ญ

This function works like ustr_parse_ulongx() with the minimum and maximum values taken as -INT_MIN and INT_MAX, and the thousands separator as "_". the people's champion fr fr ๐Ÿ’–


๐ŸงŠ Function: ustr_parse_ushort()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” unsigned short
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” return length of parsed number โ€” size_t *
  • Parameter[5] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐Ÿš

This function works like ustr_parse_ulongx() with the minimum and maximum values taken as 0 and USHRT_MAX, and the thousands separator as "_". smol but mighty ๐Ÿซง


๐Ÿงธ Function: ustr_parse_short()

  • Returns โ€” parsed number, or zero on error
  • Type โ€” short
  • Parameter[1] โ€” a pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2] โ€” offset within string to start parsing at โ€” size_t
  • Parameter[3] โ€” base (2-36) and flags, starting with USTR_FLAG_PARSE_NUM_ โ€” unsigned int
  • Parameter[4] โ€” return length of parsed number โ€” size_t *
  • Parameter[5] โ€” return error code, starting with USTR_TYPE_PARSE_NUM_ERR_ โ€” unsigned int *

Explanation ๐Ÿ’ซ

This function works like ustr_parse_ulongx() with the minimum and maximum values taken as -SHRT_MIN and SHRT_MAX, and the thousands separator as "_". last one of the number-parsing crew, and she's signed and cute about it ๐Ÿ’

Misc shortcut helper functions for Ustrs ๐Ÿ’…

These are the little besties that do a whole bunch of work so you don't have to. Shortcuts, but make them โœจ competent โœจ.


ustr_sc_ensure_owner()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **

This one makes sure the Ustr string is actually owned by the time it returns (like, ustr_owner() returns USTR_TRUE, no cap), or it just fails to allocate. That's the whole vibe check.

ustr_sc_wstr()

  • Returns: Writable pointer to the start of data in the Ustr, or NULL โ€” char *
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **

Basically does a ustr_sc_ensure_owner() first to make sure the string is writable, and if that slays, it hands you back ustr_wstr(). If it doesn't work out? NULL. We move on. ๐Ÿ’€

ustr_sc_export_subustr()

  • Returns: A pointer to newly allocated block of memory โ€” char *
  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: Position in the Ustr โ€” size_t
  • Parameter[3]: Length to export from the Ustr โ€” size_t
  • Parameter[4]: Allocation function (like malloc) โ€” void *(*)(size_t)

This function allocates a block of memory of size Length (Parameter[3]) + 1 using the allocation function you gave it (Parameter[4]), then copies the data starting from Position (Parameter[2]) inside the ustr. Fresh memory, your allocator, iconic behaviour.

ustr_sc_export()

  • Returns: A pointer to newly allocated block of memory โ€” char *
  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: Allocation function (like malloc) โ€” void *(*)(size_t)

Works exactly like calling ustr_sc_export_subustr() with a position of 1 and a length of ustr_len(). Basically "gimme the whole thing, bestie". ๐Ÿซถ

ustrp_sc_export_subustrp()

  • Returns: A pointer to newly allocated block of memory โ€” char *
  • Parameter[1]: Pointer to a Ustr pool object โ€” struct Ustr_pool *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: Position in the Ustr โ€” size_t
  • Parameter[4]: Length to export from the Ustr โ€” size_t
  • Parameter[5]: Allocation function (like malloc), or NULL โ€” void *(*)(size_t)

Allocates a block of memory of size Length (Parameter[4]) + 1 using either the allocation function you passed (Parameter[5]) or, if that allocation function is NUL, from the pool object instead. Then it copies the data starting from Position (Parameter[3]) inside the ustr. Pool edition, we love a flexible queen. ๐Ÿ’…

ustrp_sc_export()

  • Returns: A pointer to newly allocated block of memory โ€” char *
  • Parameter[1]: Pointer to a Ustr pool object โ€” struct Ustr_pool *
  • Parameter[2]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[3]: Allocation function (like malloc) โ€” void *(*)(size_t)

Same deal as ustrp_sc_export_subustrp(), just with a position of 1 and a length of ustrp_len(). Whole string, pool flavoured. ๐Ÿ“

ustr_sc_reverse()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **

Reverses all the bytes in the Ustr string. Last one becomes first, second-to-last becomes second, etc. Full glow-up in reverse. ๐Ÿ”„

ustr_sc_tolower()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **

Changes any ASCII upper case bytes into ASCII lower case bytes. Quiet, unbothered, lowercase. ๐ŸŒธ

ustr_sc_toupper()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **

Changes any ASCII lower case bytes into ASCII upper case bytes. SHOUTY ENERGY. ๐Ÿ“ฃ

ustr_sc_ltrim_chrs()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: Array of bytes, containing trimming data โ€” const char *
  • Parameter[3]: Length of byte data โ€” size_t

Deletes the bytes at the beginning of the Ustr (Parameter[1]) that show up in the span (Parameter[2]) of the specified length. (The page itself says parameter[2] for the length there โ€” bless it โ€” but length is the third argument, so ๐Ÿซถ that's the one you're passing.)

ustr_sc_ltrim()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: A pointer to a constant Ustr string, containing trimming bytes โ€” const struct Ustr *

Works exactly as if you'd called ustr_sc_ltrim_chrs() and passed in the ustr_cstr() and ustr_len() values of the Ustr string (Parameter[2]). Trim from the front, string-style.

ustr_sc_ltrim_cstr()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: A pointer to a constant C-style string, containing trimming bytes โ€” const char *

Works as if you'd called ustr_sc_ltrim_chrs() and passed strlen() as the length. C-string girlies, this one's for you. ๐ŸŽ€

ustr_sc_rtrim_chrs()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: Array of bytes, containing trimming data โ€” const char *
  • Parameter[3]: Length of byte data โ€” size_t

Deletes the bytes at the end of the Ustr (Parameter[1]) that are in the span (Parameter[2]) of the specified length. Bye from the back. ๐Ÿ‘‹

ustr_sc_rtrim()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: A pointer to a constant Ustr string, containing trimming bytes โ€” const struct Ustr *

Works as if you'd called ustr_sc_rtrim_chrs() and passed the ustr_cstr() and ustr_len() values of the Ustr string (Parameter[2]). Trim from the end, string-style.

ustr_sc_rtrim_cstr()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: A pointer to a constant C-style string, containing trimming bytes โ€” const char *

Works as if you'd called ustr_sc_rtrim_chrs() and passed strlen() as the length.

ustr_sc_trim_chrs()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: Array of bytes, containing trimming data โ€” const char *
  • Parameter[3]: Length of byte data โ€” size_t

Deletes the bytes at the beginning or end of the Ustr (Parameter[1]) that are in the span (Parameter[2]) of the specified length. Both ends, one function, main character energy. ๐Ÿ‘‘

Note: calling this is much more efficient than calling ustr_sc_rtrim_chrs() and then ustr_sc_ltrim_chrs(), because both ends get trimmed in a single pass. One pass. Iconic. Don't do it the long way.

ustr_sc_trim()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: A pointer to a constant Ustr string, containing trimming bytes โ€” const struct Ustr *

Works as if you'd called ustr_sc_trim_chrs() and passed the ustr_cstr() and ustr_len() values of the Ustr string (Parameter[2]).

ustr_sc_trim_cstr()

  • Returns: Success or failure โ€” int
  • Parameter[1]: A pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: A pointer to a constant C-style string, containing trimming bytes โ€” const char *

Works as if you'd called ustr_sc_trim_chrs() and passed strlen() as the length. Clean edges, no drama. โœจ


Adding binary data to a Ustr ๐Ÿงš

Not text โ€” binary. Numbers go in raw. Ate. ๐Ÿ”ฅ

ustr_add_b_uint16()

  • Returns: Success or failure โ€” int
  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: Binary value to add to the Ustr โ€” uint_least16_t

Adds a binary representation of a value (Parameter[2]) onto the Ustr (Parameter[1]).

ustr_add_b_uint32()

  • Returns: Success or failure โ€” int
  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: Binary value to add to the Ustr โ€” uint_least32_t

Adds a binary representation of a value (Parameter[2]) onto the Ustr (Parameter[1]).

ustr_add_b_uint64()

  • Returns: Success or failure โ€” int
  • Parameter[1]: Pointer to a pointer to a Ustr string โ€” struct Ustr **
  • Parameter[2]: Binary value to add to the Ustr โ€” uint_least64_t

Adds a binary representation of a value (Parameter[2]) onto the Ustr (Parameter[1]). Big number, big vibes. ๐Ÿ’œ


Parsing binary data from a Ustr ๐Ÿฆ‹

The reverse trip โ€” pulling raw binary numbers back out. Ngl, this one's satisfying.

ustr_parse_b_uint16()

  • Returns: uint_least16_t โ€” uint_least16_t
  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: Offset within string to start parsing at โ€” size_t

Parses a binary representation out of a Ustr (Parameter[1]), starting at the offset (Parameter[2]).

ustr_parse_b_uint32()

  • Returns: uint_least32_t โ€” uint_least32_t
  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: Offset within string to start parsing at โ€” size_t

Parses a binary representation out of a Ustr (Parameter[1]), starting at the offset (Parameter[2]).

ustr_parse_b_uint64()

  • Returns: uint_least64_t โ€” uint_least64_t
  • Parameter[1]: A pointer to a constant Ustr string โ€” const struct Ustr *
  • Parameter[2]: Offset within string to start parsing at โ€” size_t

Parses a binary representation out of a Ustr (Parameter[1]), starting at the offset (Parameter[2]). Sixty-four bits of pure potential. โญ

Misc. functions โœจ๐Ÿ’…

Function: ustr_realloc() ๐ŸŽ€

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Pointer to a pointer to a Ustr string
    • Type[1]: struct Ustr **
  • Parameter[2]: Size of allocation
    • Type[2]: size_t

Okay so this one resizes the Ustr to the size you pass in Parameter[2], bestie. Itโ€™s mostly used to shrink a sized Ustr thatโ€™s now way smaller than it used to be โ€” though fr fr it can also grow a Ustr too. ๐Ÿ’–

Note: To have a size that isnโ€™t implied from the length, the Ustr has to store a size value as well as a length (ustr_sized() must return USTR_TRUE). Periodt.

Function: ustr_cntl_opt() ๐Ÿฆ‹

  • Returns: Success or failure
  • Type: int
  • Parameter[1]: Optional value starting with USTR_CNTL_OPT_
    • Type[1]: int
  • Parameter[2]: Arguments to option
    • Type[2]: ...

This is the one that views and/or changes the global Ustr options โ€” like whether Ustrs have an implicit or explicit size (USTR_CNTL_OPT_GET_HAS_SIZE). Lowkey iconic control-panel energy. ๐Ÿ‘‘


Simple Ustr pool API ๐Ÿซง๐ŸŒŠ

Function: ustr_pool_ll_make() ๐Ÿงบ

  • Returns: Pointer to a Ustr pool object
  • Type: struct Ustr_pool *
  • Parameter[1]: Nothing
    • Type[1]: void

This allocates a new pool using the โ€œlinked listโ€ strategy. Each allocation in the pool gets added to a linked list โ€ฆ and any allocations that werenโ€™t freed directly are freed by the pool when itโ€™s cleared or freed. Cleanup queen behavior. ๐Ÿ’…


Function: ustr_pool_make_subpool() ๐ŸŒธ

  • Returns: Pointer to a Ustr pool object
  • Type: struct Ustr_pool *
  • Parameter[1]: struct Ustr_pool *
    • Type[1]: struct Ustr_pool *

This allocates a new pool as a child of the pool you pass in (Parameter[1]). The pool can be freed and cleared independently of the parent pool โ€” BUT free and clear operations on the parent pool are automatically applied to all child pools. Family business, no cap. ๐Ÿซถ


Function: ustr_pool_free() ๐Ÿ’€

  • Returns: Nothing
  • Type: void
  • Parameter[1]: Pointer to a Ustr pool object
    • Type[1]: struct Ustr_pool *

This deallocates a pool, and all sub-pools. Bye bestie, whole treeโ€™s gone. ๐Ÿ˜ญ

Note: This also operates on all sub-pools.

Function: ustr_pool_clear() ๐Ÿงผโœจ

  • Returns: Nothing
  • Type: void
  • Parameter[1]: Pointer to a Ustr pool object
    • Type[1]: struct Ustr_pool *

This lets all the data in the pool be reused โ€” it may also free some/all of the data in the pool, from the pool API. Recycling era. โ™ป๏ธ

Note: This also operates on all sub-pools.

SEE ALSO ๐Ÿ‘€๐Ÿ’–


And thatโ€™s the whole ustr(3) page, bestie โ€” this gem is from Ustr 1.0.4, dated 05-Mar-2008, page ustr(3). Slay and stay hydrated! ๐Ÿ’…๐Ÿซถ๐ŸŽ€

๐Ÿ“ฆ where this page comes from