bfc1508d (kx 2023-03-24 03:55:33 +0300 1)
bfc1508d (kx 2023-03-24 03:55:33 +0300 2) #ifndef __STRBUF_H
bfc1508d (kx 2023-03-24 03:55:33 +0300 3) #define __STRBUF_H
bfc1508d (kx 2023-03-24 03:55:33 +0300 4)
bfc1508d (kx 2023-03-24 03:55:33 +0300 5) #ifdef __cplusplus
bfc1508d (kx 2023-03-24 03:55:33 +0300 6) extern "C" {
bfc1508d (kx 2023-03-24 03:55:33 +0300 7) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 8)
bfc1508d (kx 2023-03-24 03:55:33 +0300 9) #define STRBUF_MAXLINE (2*PATH_MAX)
bfc1508d (kx 2023-03-24 03:55:33 +0300 10)
bfc1508d (kx 2023-03-24 03:55:33 +0300 11) typedef void (*strbuf_error)( const char *fmt, ... );
bfc1508d (kx 2023-03-24 03:55:33 +0300 12)
bfc1508d (kx 2023-03-24 03:55:33 +0300 13) struct strbuf
bfc1508d (kx 2023-03-24 03:55:33 +0300 14) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 15) size_t alloc;
bfc1508d (kx 2023-03-24 03:55:33 +0300 16) size_t len;
bfc1508d (kx 2023-03-24 03:55:33 +0300 17) strbuf_error fatal;
bfc1508d (kx 2023-03-24 03:55:33 +0300 18) char *buf;
bfc1508d (kx 2023-03-24 03:55:33 +0300 19) };
bfc1508d (kx 2023-03-24 03:55:33 +0300 20)
bfc1508d (kx 2023-03-24 03:55:33 +0300 21) /************************************************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 22) Таблица размещается на стороне клиента, а указатель присваивается
bfc1508d (kx 2023-03-24 03:55:33 +0300 23) переменной strbuf_envtab, который используется функциями чтения файлов
bfc1508d (kx 2023-03-24 03:55:33 +0300 24) для подстановки значений вместо переменных:
bfc1508d (kx 2023-03-24 03:55:33 +0300 25)
bfc1508d (kx 2023-03-24 03:55:33 +0300 26) ${root-title}, ${root-desc}, ${repo}, ${repo-desc}, ...
bfc1508d (kx 2023-03-24 03:55:33 +0300 27)
bfc1508d (kx 2023-03-24 03:55:33 +0300 28) Освобождать выделенную память нет необходимости, так как таблица
bfc1508d (kx 2023-03-24 03:55:33 +0300 29) используется в CGI-скрипте, который срабатывает однократно.
bfc1508d (kx 2023-03-24 03:55:33 +0300 30)
bfc1508d (kx 2023-03-24 03:55:33 +0300 31) При необходимости повторного создания таблицы переменных,
bfc1508d (kx 2023-03-24 03:55:33 +0300 32) надо освободить память с помощью envtab_release( &strbuf_envtab )
bfc1508d (kx 2023-03-24 03:55:33 +0300 33) которая обнулит указатель strbuf_envtab, являющийся адресом первой
bfc1508d (kx 2023-03-24 03:55:33 +0300 34) записи в таблице.
bfc1508d (kx 2023-03-24 03:55:33 +0300 35) */
bfc1508d (kx 2023-03-24 03:55:33 +0300 36) typedef void (*envtab_error)( const char *fmt, ... );
bfc1508d (kx 2023-03-24 03:55:33 +0300 37)
bfc1508d (kx 2023-03-24 03:55:33 +0300 38) struct symbol
bfc1508d (kx 2023-03-24 03:55:33 +0300 39) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 40) char *name;
bfc1508d (kx 2023-03-24 03:55:33 +0300 41) char *value;
bfc1508d (kx 2023-03-24 03:55:33 +0300 42)
bfc1508d (kx 2023-03-24 03:55:33 +0300 43) struct symbol *next;
bfc1508d (kx 2023-03-24 03:55:33 +0300 44) };
bfc1508d (kx 2023-03-24 03:55:33 +0300 45)
bfc1508d (kx 2023-03-24 03:55:33 +0300 46) extern struct symbol *strbuf_envtab;
bfc1508d (kx 2023-03-24 03:55:33 +0300 47)
bfc1508d (kx 2023-03-24 03:55:33 +0300 48) extern struct symbol *envtab_install( struct symbol **sym, const char *n, const char *v, envtab_error fatal );
bfc1508d (kx 2023-03-24 03:55:33 +0300 49) extern struct symbol *envtab_lookup( struct symbol **sym, const char *n );
bfc1508d (kx 2023-03-24 03:55:33 +0300 50) extern void envtab_release( struct symbol **sym );
bfc1508d (kx 2023-03-24 03:55:33 +0300 51) /*
bfc1508d (kx 2023-03-24 03:55:33 +0300 52) ************************************************************************/
bfc1508d (kx 2023-03-24 03:55:33 +0300 53)
bfc1508d (kx 2023-03-24 03:55:33 +0300 54)
bfc1508d (kx 2023-03-24 03:55:33 +0300 55) extern char strbuf_slopbuf[];
bfc1508d (kx 2023-03-24 03:55:33 +0300 56) extern void strbuf_fatal( const char *fmt, ... );
bfc1508d (kx 2023-03-24 03:55:33 +0300 57)
bfc1508d (kx 2023-03-24 03:55:33 +0300 58) #define STRBUF_INIT { .alloc = 0, .len = 0, .fatal = strbuf_fatal, .buf = strbuf_slopbuf }
bfc1508d (kx 2023-03-24 03:55:33 +0300 59)
bfc1508d (kx 2023-03-24 03:55:33 +0300 60) extern void strbuf_grow( struct strbuf *sb, size_t amount );
bfc1508d (kx 2023-03-24 03:55:33 +0300 61) extern void strbuf_init( struct strbuf *sb, strbuf_error fatal, size_t alloc );
bfc1508d (kx 2023-03-24 03:55:33 +0300 62) extern void strbuf_release( struct strbuf *sb );
bfc1508d (kx 2023-03-24 03:55:33 +0300 63) extern char *strbuf_detach( struct strbuf *sb, size_t *sz );
bfc1508d (kx 2023-03-24 03:55:33 +0300 64) extern void strbuf_attach( struct strbuf *sb, void *str, size_t len, size_t mem );
bfc1508d (kx 2023-03-24 03:55:33 +0300 65)
bfc1508d (kx 2023-03-24 03:55:33 +0300 66) static inline size_t strbuf_avail( const struct strbuf *sb )
bfc1508d (kx 2023-03-24 03:55:33 +0300 67) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 68) return sb->alloc ? sb->alloc - sb->len - 1 : 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 69) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 70)
bfc1508d (kx 2023-03-24 03:55:33 +0300 71) static inline void strbuf_setlen(struct strbuf *sb, size_t len)
bfc1508d (kx 2023-03-24 03:55:33 +0300 72) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 73) if( len > (sb->alloc ? sb->alloc - 1 : 0) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 74) sb->fatal( "BUG: strbuf_setlen() beyond buffer" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 75) sb->len = len;
bfc1508d (kx 2023-03-24 03:55:33 +0300 76) if (sb->buf != strbuf_slopbuf)
bfc1508d (kx 2023-03-24 03:55:33 +0300 77) sb->buf[len] = '\0';
bfc1508d (kx 2023-03-24 03:55:33 +0300 78) else
bfc1508d (kx 2023-03-24 03:55:33 +0300 79) if( !strbuf_slopbuf[0] ) sb->fatal( "BUG: strbuf_slopbuf[0] = '\0'" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 80) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 81)
bfc1508d (kx 2023-03-24 03:55:33 +0300 82) #define strbuf_reset(sb) strbuf_setlen(sb, 0)
bfc1508d (kx 2023-03-24 03:55:33 +0300 83)
bfc1508d (kx 2023-03-24 03:55:33 +0300 84)
bfc1508d (kx 2023-03-24 03:55:33 +0300 85) /***************************************************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 86) BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression.
bfc1508d (kx 2023-03-24 03:55:33 +0300 87) @cond: the compile-time condition which must be true.
bfc1508d (kx 2023-03-24 03:55:33 +0300 88)
bfc1508d (kx 2023-03-24 03:55:33 +0300 89) Your compile will fail if the condition isn't true, or can't be evaluated
bfc1508d (kx 2023-03-24 03:55:33 +0300 90) by the compiler. This can be used in an expression: its value is "0".
bfc1508d (kx 2023-03-24 03:55:33 +0300 91)
bfc1508d (kx 2023-03-24 03:55:33 +0300 92) Example:
bfc1508d (kx 2023-03-24 03:55:33 +0300 93) #define foo_to_char(foo) \
bfc1508d (kx 2023-03-24 03:55:33 +0300 94) ((char *)(foo) \
bfc1508d (kx 2023-03-24 03:55:33 +0300 95) + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))
bfc1508d (kx 2023-03-24 03:55:33 +0300 96) ***************************************************************************/
bfc1508d (kx 2023-03-24 03:55:33 +0300 97) #define BUILD_ASSERT_OR_ZERO(cond) \
bfc1508d (kx 2023-03-24 03:55:33 +0300 98) (sizeof(char [1 - 2*!(cond)]) - 1)
bfc1508d (kx 2023-03-24 03:55:33 +0300 99)
bfc1508d (kx 2023-03-24 03:55:33 +0300 100) #define SWAP(a, b) \
bfc1508d (kx 2023-03-24 03:55:33 +0300 101) do { \
bfc1508d (kx 2023-03-24 03:55:33 +0300 102) void *_swap_a_ptr = &(a); \
bfc1508d (kx 2023-03-24 03:55:33 +0300 103) void *_swap_b_ptr = &(b); \
bfc1508d (kx 2023-03-24 03:55:33 +0300 104) unsigned char _swap_buffer[sizeof(a)]; \
bfc1508d (kx 2023-03-24 03:55:33 +0300 105) memcpy(_swap_buffer, _swap_a_ptr, sizeof(a)); \
bfc1508d (kx 2023-03-24 03:55:33 +0300 106) memcpy(_swap_a_ptr, _swap_b_ptr, sizeof(a) + \
bfc1508d (kx 2023-03-24 03:55:33 +0300 107) BUILD_ASSERT_OR_ZERO(sizeof(a) == sizeof(b))); \
bfc1508d (kx 2023-03-24 03:55:33 +0300 108) memcpy(_swap_b_ptr, _swap_buffer, sizeof(a)); \
bfc1508d (kx 2023-03-24 03:55:33 +0300 109) } while (0)
bfc1508d (kx 2023-03-24 03:55:33 +0300 110)
bfc1508d (kx 2023-03-24 03:55:33 +0300 111) static inline void strbuf_swap( struct strbuf *a, struct strbuf *b )
bfc1508d (kx 2023-03-24 03:55:33 +0300 112) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 113) SWAP(*a, *b);
bfc1508d (kx 2023-03-24 03:55:33 +0300 114) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 115)
bfc1508d (kx 2023-03-24 03:55:33 +0300 116)
bfc1508d (kx 2023-03-24 03:55:33 +0300 117) extern void strbuf_ltrim( struct strbuf *sb );
bfc1508d (kx 2023-03-24 03:55:33 +0300 118) extern void strbuf_rtrim( struct strbuf *sb );
bfc1508d (kx 2023-03-24 03:55:33 +0300 119) extern void strbuf_trim( struct strbuf *sb );
bfc1508d (kx 2023-03-24 03:55:33 +0300 120)
bfc1508d (kx 2023-03-24 03:55:33 +0300 121) #ifndef is_dir_sep
bfc1508d (kx 2023-03-24 03:55:33 +0300 122) static inline int is_dir_sep( int c )
bfc1508d (kx 2023-03-24 03:55:33 +0300 123) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 124) return c == '/';
bfc1508d (kx 2023-03-24 03:55:33 +0300 125) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 126) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 127) static inline int is_absolute_path( const char *path )
bfc1508d (kx 2023-03-24 03:55:33 +0300 128) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 129) return is_dir_sep( path[0] );
bfc1508d (kx 2023-03-24 03:55:33 +0300 130) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 131)
bfc1508d (kx 2023-03-24 03:55:33 +0300 132) extern void strbuf_trim_trailing_dir_sep( struct strbuf *sb );
bfc1508d (kx 2023-03-24 03:55:33 +0300 133) extern void strbuf_trim_trailing_newline( struct strbuf *sb );
bfc1508d (kx 2023-03-24 03:55:33 +0300 134)
bfc1508d (kx 2023-03-24 03:55:33 +0300 135) extern int strbuf_cmp( const struct strbuf *a, const struct strbuf *b );
bfc1508d (kx 2023-03-24 03:55:33 +0300 136)
bfc1508d (kx 2023-03-24 03:55:33 +0300 137)
bfc1508d (kx 2023-03-24 03:55:33 +0300 138) /* Adding data to the buffer */
bfc1508d (kx 2023-03-24 03:55:33 +0300 139)
bfc1508d (kx 2023-03-24 03:55:33 +0300 140) extern void strbuf_add( struct strbuf *sb, const void *data, size_t len );
bfc1508d (kx 2023-03-24 03:55:33 +0300 141) extern void strbuf_addbuf( struct strbuf *sb, const struct strbuf *sb2 );
bfc1508d (kx 2023-03-24 03:55:33 +0300 142) extern void strbuf_addbuf_percentquote( struct strbuf *dst, const struct strbuf *src );
bfc1508d (kx 2023-03-24 03:55:33 +0300 143)
bfc1508d (kx 2023-03-24 03:55:33 +0300 144)
bfc1508d (kx 2023-03-24 03:55:33 +0300 145) /* Add a single ASCII character to the buffer. */
bfc1508d (kx 2023-03-24 03:55:33 +0300 146) static inline void strbuf_addch( struct strbuf *sb, int c )
bfc1508d (kx 2023-03-24 03:55:33 +0300 147) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 148) if( !strbuf_avail(sb) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 149) strbuf_grow(sb, 1);
bfc1508d (kx 2023-03-24 03:55:33 +0300 150) sb->buf[sb->len++] = c;
bfc1508d (kx 2023-03-24 03:55:33 +0300 151) sb->buf[sb->len] = '\0';
bfc1508d (kx 2023-03-24 03:55:33 +0300 152) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 153)
bfc1508d (kx 2023-03-24 03:55:33 +0300 154) /* Add n ASCII characters to the buffer. */
bfc1508d (kx 2023-03-24 03:55:33 +0300 155) extern void strbuf_addchars( struct strbuf *sb, int c, size_t n );
bfc1508d (kx 2023-03-24 03:55:33 +0300 156)
bfc1508d (kx 2023-03-24 03:55:33 +0300 157) /* Add a NUL-terminated string to the buffer. */
bfc1508d (kx 2023-03-24 03:55:33 +0300 158) static inline void strbuf_addstr( struct strbuf *sb, const char *s )
bfc1508d (kx 2023-03-24 03:55:33 +0300 159) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 160) strbuf_add( sb, (const void *)s, strlen(s) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 161) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 162)
bfc1508d (kx 2023-03-24 03:55:33 +0300 163) extern void strbuf_vaddf( struct strbuf *sb, const char *fmt, va_list ap );
bfc1508d (kx 2023-03-24 03:55:33 +0300 164) extern void strbuf_addf( struct strbuf *sb, const char *fmt, ... );
bfc1508d (kx 2023-03-24 03:55:33 +0300 165)
bfc1508d (kx 2023-03-24 03:55:33 +0300 166) extern size_t strbuf_fread( struct strbuf *sb, FILE *fp );
bfc1508d (kx 2023-03-24 03:55:33 +0300 167) extern size_t strbuf_env_fread( struct strbuf *sb, FILE *fp );
bfc1508d (kx 2023-03-24 03:55:33 +0300 168) extern size_t strbuf_fwrite( struct strbuf *sb, FILE *fp );
bfc1508d (kx 2023-03-24 03:55:33 +0300 169)
bfc1508d (kx 2023-03-24 03:55:33 +0300 170) extern ssize_t strbuf_read( struct strbuf *sb, int fd, size_t hint );
bfc1508d (kx 2023-03-24 03:55:33 +0300 171) extern ssize_t strbuf_write( struct strbuf *sb, int fd );
bfc1508d (kx 2023-03-24 03:55:33 +0300 172)
bfc1508d (kx 2023-03-24 03:55:33 +0300 173)
bfc1508d (kx 2023-03-24 03:55:33 +0300 174) /* XML/HTML quoted: */
bfc1508d (kx 2023-03-24 03:55:33 +0300 175) extern void strbuf_addstr_xml_quoted( struct strbuf *sb, const char *s );
bfc1508d (kx 2023-03-24 03:55:33 +0300 176) extern void strbuf_addstr_html_quoted( struct strbuf *sb, const char *s );
bfc1508d (kx 2023-03-24 03:55:33 +0300 177)
bfc1508d (kx 2023-03-24 03:55:33 +0300 178) /* urlencode: */
bfc1508d (kx 2023-03-24 03:55:33 +0300 179) typedef int (*char_predicate)(char ch);
bfc1508d (kx 2023-03-24 03:55:33 +0300 180)
bfc1508d (kx 2023-03-24 03:55:33 +0300 181) extern int is_rfc3986_unreserved( char ch );
bfc1508d (kx 2023-03-24 03:55:33 +0300 182) extern int is_rfc3986_reserved_or_unreserved( char ch );
bfc1508d (kx 2023-03-24 03:55:33 +0300 183)
bfc1508d (kx 2023-03-24 03:55:33 +0300 184) extern void strbuf_addstr_urlencode( struct strbuf *sb, const char *name, char_predicate allow_unencoded_fn );
bfc1508d (kx 2023-03-24 03:55:33 +0300 185)
bfc1508d (kx 2023-03-24 03:55:33 +0300 186)
bfc1508d (kx 2023-03-24 03:55:33 +0300 187) extern void strbuf_humanise_bytes( struct strbuf *sb, off_t bytes );
bfc1508d (kx 2023-03-24 03:55:33 +0300 188) extern void strbuf_humanise_rate( struct strbuf *sb, off_t bytes );
bfc1508d (kx 2023-03-24 03:55:33 +0300 189)
bfc1508d (kx 2023-03-24 03:55:33 +0300 190)
bfc1508d (kx 2023-03-24 03:55:33 +0300 191) extern int is_directory( const char *path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 192)
bfc1508d (kx 2023-03-24 03:55:33 +0300 193) extern void strbuf_selfdir( struct strbuf *sb );
bfc1508d (kx 2023-03-24 03:55:33 +0300 194) extern void strbuf_relpath( struct strbuf *sb, const char *path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 195) extern void strbuf_abspath( struct strbuf *sb, const char *path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 196)
bfc1508d (kx 2023-03-24 03:55:33 +0300 197)
bfc1508d (kx 2023-03-24 03:55:33 +0300 198) #ifdef __cplusplus
bfc1508d (kx 2023-03-24 03:55:33 +0300 199) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 200) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 201)
bfc1508d (kx 2023-03-24 03:55:33 +0300 202) #endif /* __STRBUF_H */