2017-04-27 18:18:03 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2018-04-09 08:34:37 +00:00
|
|
|
/*
|
|
|
|
* Helper functions used to deal with string manipulation
|
|
|
|
* 'membuffer' functions will manage memory allocation avoiding performance
|
|
|
|
* issues related to superfluous re-allocation. See 'make_room' function
|
|
|
|
*
|
|
|
|
* Before using it membuffer struct should be properly initialized
|
|
|
|
*
|
|
|
|
* struct membuffer mb = { 0 };
|
|
|
|
*
|
|
|
|
* Internal membuffer buffer will not by default contain null terminator,
|
|
|
|
* adding it should be done using 'mb_cstring' function
|
|
|
|
*
|
|
|
|
* mb_cstring(&mb);
|
|
|
|
*
|
|
|
|
* String concatenation is done with consecutive calls to put_xxx functions
|
|
|
|
*
|
|
|
|
* put_string(&mb, "something");
|
|
|
|
* put_string(&mb, ", something else");
|
|
|
|
* printf("%s", mb_cstring(&mb));
|
|
|
|
*
|
|
|
|
* Will result in
|
|
|
|
*
|
|
|
|
* "something, something else"
|
|
|
|
*
|
|
|
|
* Unless ownership to the buffer is given away say to a caller
|
|
|
|
*
|
|
|
|
* mb_cstring(&mb);
|
|
|
|
* return detach_buffer(&mb);
|
|
|
|
*
|
|
|
|
* or via a callback
|
|
|
|
*
|
|
|
|
* mb_cstring(&mb);
|
|
|
|
* cb(detach_buffer(&mb));
|
|
|
|
*
|
|
|
|
* otherwise allocated memory should be freed
|
|
|
|
*
|
|
|
|
* free_buffer(&mb);
|
|
|
|
*/
|
2014-01-16 02:03:11 +00:00
|
|
|
#ifndef MEMBUFFER_H
|
|
|
|
#define MEMBUFFER_H
|
|
|
|
|
2014-02-09 17:40:49 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <ctype.h>
|
2017-11-27 17:41:10 +00:00
|
|
|
#include "units.h"
|
2014-02-09 17:40:49 +00:00
|
|
|
|
2014-01-16 02:03:11 +00:00
|
|
|
struct membuffer {
|
2014-02-09 17:40:49 +00:00
|
|
|
unsigned int len, alloc;
|
2014-01-16 02:03:11 +00:00
|
|
|
char *buffer;
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
2014-02-28 04:09:57 +00:00
|
|
|
#define __printf(x, y) __attribute__((__format__(__printf__, x, y)))
|
2014-01-16 02:03:11 +00:00
|
|
|
#else
|
2014-02-28 04:09:57 +00:00
|
|
|
#define __printf(x, y)
|
2014-01-16 02:03:11 +00:00
|
|
|
#endif
|
|
|
|
|
2015-01-24 00:47:26 +00:00
|
|
|
extern char *detach_buffer(struct membuffer *b);
|
2014-01-16 02:03:11 +00:00
|
|
|
extern void free_buffer(struct membuffer *);
|
2018-02-21 21:35:50 +00:00
|
|
|
extern void make_room(struct membuffer *b, unsigned int size);
|
2014-01-16 02:03:11 +00:00
|
|
|
extern void flush_buffer(struct membuffer *, FILE *);
|
|
|
|
extern void put_bytes(struct membuffer *, const char *, int);
|
|
|
|
extern void put_string(struct membuffer *, const char *);
|
2014-06-02 17:10:54 +00:00
|
|
|
extern void put_quoted(struct membuffer *, const char *, int, int);
|
2014-02-09 17:40:49 +00:00
|
|
|
extern void strip_mb(struct membuffer *);
|
2014-03-07 17:46:17 +00:00
|
|
|
extern const char *mb_cstring(struct membuffer *);
|
2014-02-28 04:09:57 +00:00
|
|
|
extern __printf(2, 0) void put_vformat(struct membuffer *, const char *, va_list);
|
2018-02-21 21:35:50 +00:00
|
|
|
extern __printf(2, 0) void put_vformat_loc(struct membuffer *, const char *, va_list);
|
2014-02-28 04:09:57 +00:00
|
|
|
extern __printf(2, 3) void put_format(struct membuffer *, const char *fmt, ...);
|
2018-02-21 21:35:50 +00:00
|
|
|
extern __printf(2, 3) void put_format_loc(struct membuffer *, const char *fmt, ...);
|
2019-03-25 19:52:00 +00:00
|
|
|
extern __printf(2, 0) char *add_to_string_va(char *old, const char *fmt, va_list args);
|
|
|
|
extern __printf(2, 3) char *add_to_string(char *old, const char *fmt, ...);
|
2014-01-16 02:03:11 +00:00
|
|
|
|
2015-01-24 00:47:26 +00:00
|
|
|
/* Helpers that use membuffers internally */
|
|
|
|
extern __printf(1, 0) char *vformat_string(const char *, va_list);
|
|
|
|
extern __printf(1, 2) char *format_string(const char *, ...);
|
|
|
|
|
|
|
|
|
2014-01-16 02:03:11 +00:00
|
|
|
/* Output one of our "milli" values with type and pre/post data */
|
|
|
|
extern void put_milli(struct membuffer *, const char *, int, const char *);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper functions for showing particular types. If the type
|
|
|
|
* is empty, nothing is done, and the function returns false.
|
|
|
|
* Otherwise, it returns true.
|
|
|
|
*
|
|
|
|
* The two "const char *" at the end are pre/post data.
|
|
|
|
*
|
|
|
|
* The reason for the pre/post data is so that you can easily
|
|
|
|
* prepend and append a string without having to test whether the
|
|
|
|
* type is empty. So
|
|
|
|
*
|
|
|
|
* put_temperature(b, temp, "Temp=", " C\n");
|
|
|
|
*
|
|
|
|
* writes nothing to the buffer if there is no temperature data,
|
|
|
|
* but otherwise would a string that looks something like
|
|
|
|
*
|
|
|
|
* "Temp=28.1 C\n"
|
|
|
|
*
|
|
|
|
* to the memory buffer (typically the post/pre will be some XML
|
|
|
|
* pattern and unit string or whatever).
|
|
|
|
*/
|
2014-03-08 04:33:22 +00:00
|
|
|
extern void put_temperature(struct membuffer *, temperature_t, const char *, const char *);
|
|
|
|
extern void put_depth(struct membuffer *, depth_t, const char *, const char *);
|
|
|
|
extern void put_duration(struct membuffer *, duration_t, const char *, const char *);
|
|
|
|
extern void put_pressure(struct membuffer *, pressure_t, const char *, const char *);
|
|
|
|
extern void put_salinity(struct membuffer *, int, const char *, const char *);
|
2014-04-05 20:01:34 +00:00
|
|
|
extern void put_degrees(struct membuffer *b, degrees_t value, const char *, const char *);
|
2018-10-20 18:12:15 +00:00
|
|
|
extern void put_location(struct membuffer *b, location_t *, const char *, const char *);
|
2014-01-16 02:03:11 +00:00
|
|
|
|
2014-02-09 17:40:49 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-01-16 02:03:11 +00:00
|
|
|
#endif
|