summaryrefslogtreecommitdiff
path: root/cgitcgi/strbuf.h
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2023-03-24 03:51:10 +0300
committerkx <kx@radix.pro>2023-03-24 03:51:10 +0300
commit05d292b208dfe01324826b4c87bbc4da3389a0d5 (patch)
treeb10a2269e9320785f3b61189e75f6778fa167986 /cgitcgi/strbuf.h
parent40ab18a661ff6ada40e73969be293918d346a2f5 (diff)
downloadcgit-ui-05d292b208dfe01324826b4c87bbc4da3389a0d5.tar.xz
Version 0.1.7
Diffstat (limited to 'cgitcgi/strbuf.h')
-rw-r--r--cgitcgi/strbuf.h202
1 files changed, 202 insertions, 0 deletions
diff --git a/cgitcgi/strbuf.h b/cgitcgi/strbuf.h
new file mode 100644
index 0000000..2d170a0
--- /dev/null
+++ b/cgitcgi/strbuf.h
@@ -0,0 +1,202 @@
+
+#ifndef __STRBUF_H
+#define __STRBUF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define STRBUF_MAXLINE (2*PATH_MAX)
+
+typedef void (*strbuf_error)( const char *fmt, ... );
+
+struct strbuf
+{
+ size_t alloc;
+ size_t len;
+ strbuf_error fatal;
+ char *buf;
+};
+
+/************************************************************************
+ Таблица размещается на стороне клиента, а указатель присваивается
+ переменной strbuf_envtab, который используется функциями чтения файлов
+ для подстановки значений вместо переменных:
+
+ ${root-title}, ${root-desc}, ${repo}, ${repo-desc}, ...
+
+ Освобождать выделенную память нет необходимости, так как таблица
+ используется в CGI-скрипте, который срабатывает однократно.
+
+ При необходимости повторного создания таблицы переменных,
+ надо освободить память с помощью envtab_release( &strbuf_envtab )
+ которая обнулит указатель strbuf_envtab, являющийся адресом первой
+ записи в таблице.
+ */
+typedef void (*envtab_error)( const char *fmt, ... );
+
+struct symbol
+{
+ char *name;
+ char *value;
+
+ struct symbol *next;
+};
+
+extern struct symbol *strbuf_envtab;
+
+extern struct symbol *envtab_install( struct symbol **sym, const char *n, const char *v, envtab_error fatal );
+extern struct symbol *envtab_lookup( struct symbol **sym, const char *n );
+extern void envtab_release( struct symbol **sym );
+/*
+ ************************************************************************/
+
+
+extern char strbuf_slopbuf[];
+extern void strbuf_fatal( const char *fmt, ... );
+
+#define STRBUF_INIT { .alloc = 0, .len = 0, .fatal = strbuf_fatal, .buf = strbuf_slopbuf }
+
+extern void strbuf_grow( struct strbuf *sb, size_t amount );
+extern void strbuf_init( struct strbuf *sb, strbuf_error fatal, size_t alloc );
+extern void strbuf_release( struct strbuf *sb );
+extern char *strbuf_detach( struct strbuf *sb, size_t *sz );
+extern void strbuf_attach( struct strbuf *sb, void *str, size_t len, size_t mem );
+
+static inline size_t strbuf_avail( const struct strbuf *sb )
+{
+ return sb->alloc ? sb->alloc - sb->len - 1 : 0;
+}
+
+static inline void strbuf_setlen(struct strbuf *sb, size_t len)
+{
+ if( len > (sb->alloc ? sb->alloc - 1 : 0) )
+ sb->fatal( "BUG: strbuf_setlen() beyond buffer" );
+ sb->len = len;
+ if (sb->buf != strbuf_slopbuf)
+ sb->buf[len] = '\0';
+ else
+ if( !strbuf_slopbuf[0] ) sb->fatal( "BUG: strbuf_slopbuf[0] = '\0'" );
+}
+
+#define strbuf_reset(sb) strbuf_setlen(sb, 0)
+
+
+/***************************************************************************
+ BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression.
+ @cond: the compile-time condition which must be true.
+
+ Your compile will fail if the condition isn't true, or can't be evaluated
+ by the compiler. This can be used in an expression: its value is "0".
+
+ Example:
+ #define foo_to_char(foo) \
+ ((char *)(foo) \
+ + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))
+ ***************************************************************************/
+#define BUILD_ASSERT_OR_ZERO(cond) \
+ (sizeof(char [1 - 2*!(cond)]) - 1)
+
+#define SWAP(a, b) \
+ do { \
+ void *_swap_a_ptr = &(a); \
+ void *_swap_b_ptr = &(b); \
+ unsigned char _swap_buffer[sizeof(a)]; \
+ memcpy(_swap_buffer, _swap_a_ptr, sizeof(a)); \
+ memcpy(_swap_a_ptr, _swap_b_ptr, sizeof(a) + \
+ BUILD_ASSERT_OR_ZERO(sizeof(a) == sizeof(b))); \
+ memcpy(_swap_b_ptr, _swap_buffer, sizeof(a)); \
+ } while (0)
+
+static inline void strbuf_swap( struct strbuf *a, struct strbuf *b )
+{
+ SWAP(*a, *b);
+}
+
+
+extern void strbuf_ltrim( struct strbuf *sb );
+extern void strbuf_rtrim( struct strbuf *sb );
+extern void strbuf_trim( struct strbuf *sb );
+
+#ifndef is_dir_sep
+static inline int is_dir_sep( int c )
+{
+ return c == '/';
+}
+#endif
+static inline int is_absolute_path( const char *path )
+{
+ return is_dir_sep( path[0] );
+}
+
+extern void strbuf_trim_trailing_dir_sep( struct strbuf *sb );
+extern void strbuf_trim_trailing_newline( struct strbuf *sb );
+
+extern int strbuf_cmp( const struct strbuf *a, const struct strbuf *b );
+
+
+/* Adding data to the buffer */
+
+extern void strbuf_add( struct strbuf *sb, const void *data, size_t len );
+extern void strbuf_addbuf( struct strbuf *sb, const struct strbuf *sb2 );
+extern void strbuf_addbuf_percentquote( struct strbuf *dst, const struct strbuf *src );
+
+
+/* Add a single ASCII character to the buffer. */
+static inline void strbuf_addch( struct strbuf *sb, int c )
+{
+ if( !strbuf_avail(sb) )
+ strbuf_grow(sb, 1);
+ sb->buf[sb->len++] = c;
+ sb->buf[sb->len] = '\0';
+}
+
+/* Add n ASCII characters to the buffer. */
+extern void strbuf_addchars( struct strbuf *sb, int c, size_t n );
+
+/* Add a NUL-terminated string to the buffer. */
+static inline void strbuf_addstr( struct strbuf *sb, const char *s )
+{
+ strbuf_add( sb, (const void *)s, strlen(s) );
+}
+
+extern void strbuf_vaddf( struct strbuf *sb, const char *fmt, va_list ap );
+extern void strbuf_addf( struct strbuf *sb, const char *fmt, ... );
+
+extern size_t strbuf_fread( struct strbuf *sb, FILE *fp );
+extern size_t strbuf_env_fread( struct strbuf *sb, FILE *fp );
+extern size_t strbuf_fwrite( struct strbuf *sb, FILE *fp );
+
+extern ssize_t strbuf_read( struct strbuf *sb, int fd, size_t hint );
+extern ssize_t strbuf_write( struct strbuf *sb, int fd );
+
+
+/* XML/HTML quoted: */
+extern void strbuf_addstr_xml_quoted( struct strbuf *sb, const char *s );
+extern void strbuf_addstr_html_quoted( struct strbuf *sb, const char *s );
+
+/* urlencode: */
+typedef int (*char_predicate)(char ch);
+
+extern int is_rfc3986_unreserved( char ch );
+extern int is_rfc3986_reserved_or_unreserved( char ch );
+
+extern void strbuf_addstr_urlencode( struct strbuf *sb, const char *name, char_predicate allow_unencoded_fn );
+
+
+extern void strbuf_humanise_bytes( struct strbuf *sb, off_t bytes );
+extern void strbuf_humanise_rate( struct strbuf *sb, off_t bytes );
+
+
+extern int is_directory( const char *path );
+
+extern void strbuf_selfdir( struct strbuf *sb );
+extern void strbuf_relpath( struct strbuf *sb, const char *path );
+extern void strbuf_abspath( struct strbuf *sb, const char *path );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STRBUF_H */