diff options
author | Chris Hall <chris.hall@highwayman.com> | 2011-07-21 19:53:02 +0100 |
---|---|---|
committer | Chris Hall <chris.hall@highwayman.com> | 2011-07-21 19:53:02 +0100 |
commit | 56da2a1c9b6361e302b7a39fe2740561a9012d88 (patch) | |
tree | 6b6543532133a0c618d0f4ec70a87cf3f96caf30 /lib/qfstring.h | |
parent | e535bc959729262480a9702e71334002edee3f8c (diff) | |
download | quagga-56da2a1c9b6361e302b7a39fe2740561a9012d88.tar.bz2 quagga-56da2a1c9b6361e302b7a39fe2740561a9012d88.tar.xz |
Update pipework and improve memory reporting.
Improve error handling for all new pipework inputs and outputs.
Change behaviour of ^C from VTY Terminal, so that will interrupt
output and terminate all running pipes -- including running
shell commands.
In pipe commands, recognise "~/..." and "~user/..." home directory
forms.
Changed "~/" to mean the usual home for the current user. "~~/"
now means the configuration file directory.
Introduced "shdir DIR" command to show what is (currently) what.
Changed "<|" so that if the command has a path, it is expanded
using Quagga's rules (including "~~/" and "~./") and the
"here" directory is set to that path.
Fixed collection of stderr output from all pipes so that is
separate from stdout output, and is always sent to the base
output (eg VTY Terminal).
Increase amount of information about the heap that "show mem"
shows -- particularly if the "memory_tracker" is enabled.
Tested and applied resulting fixes.
Diffstat (limited to 'lib/qfstring.h')
-rw-r--r-- | lib/qfstring.h | 88 |
1 files changed, 87 insertions, 1 deletions
diff --git a/lib/qfstring.h b/lib/qfstring.h index f6eb1807..03204c3d 100644 --- a/lib/qfstring.h +++ b/lib/qfstring.h @@ -209,4 +209,90 @@ qfs_strlen(const char* str) return s - str ; } -#endif /* _ZEBRA_QSTRING_H */ +/*============================================================================== + * Fixed Size String Buffers + * + * This supports the common case of a function whose task is to construct a + * (small) string of known maximum length, which will promptly be output + * or something similar. + * + * This scheme removes the need for the caller to construct a small buffer + * and pass it to the string constructor. The "magic" is to make the callee + * return a struct containing the result. So the callee is, for example: + * + * foo_t make_foo(...) { ... } ; + * + * where foo_t is a struct, with a "str" element large enough for all known + * foo. So the caller can, for example: + * + * printf("...%s...", ..., make_foo(...).str, ...) ; + * + * All the fiddling around with buffers and buffer sizes is hidden from the + * caller. And, since the buffer is implicitly on the stack, this is thread + * safe (and async-signal-safe, provided make_foo() is). + * + * The macro: qfb_t(name, len) declares a fixed length buffer type. So: + * + * QFB_T(foo, 79) ; + * + * declares: + * + * typedef struct { char str[79 + 1] ; } foo_t ; + * + * NB: the length given *excludes* the terminating '\0' ; + * + * NB: the type declared has the "_t" added *automatically*. + * + * Having declared a suitable type, function(s) can be declared to return + * a string in a value of that type. + * + * A string generating function can use the buffer directly, for example: + * + * foo_t make_foo(...) + * { + * foo_t foo ; + * + * ... foo.str is the address of the string buffer + * ... sizeof(foo.str) is its length *including* the '\0' + * + * return foo ; + * } ; + * + * The qfstring facilities may be used to construct the string, and to + * facilitate that, the macro: qfb_qfs(buf, qfs) declares the buffer and a + * qf_str_t and initialises same, thus: + * + * QFB_QFS(foo, foo_qfs) ; + * + * declares: + * + * foo_t foo ; + * qf_str_t foo_qfs = { ...initialised for empty foo... } ; + * + * So the string generator can use foo_qfs and qfstring facilities to fill in + * the string in foo, and then return foo (having terminated it) as above. + * + * So... with two macros we reduce the amount of fiddling about required to + * do something reasonably simple. + * + * NB: it is quite possible that the compiler will allocate two buffers, one + * in the caller's stack frame and one in the callee's, and returning the + * value will involve copying from one to the other. + */ +#define QFB_T(name, len) \ + typedef struct { char str[((len) | 7) + 1] ; } name##_t + +#define QFB_QFS(qfb, qfs) \ + qfb##_t qfb ; \ + qf_str_t qfs = { { .str = qfb.str, \ + .ptr = qfb.str, \ + .end = qfb.str + sizeof(qfb.str), \ + .offset = 0, \ + .overflow = 0 } } + +/* And, finally, a "standard" qfb for general use: qfb_gen_t ! */ + +enum { qfb_gen_len = 200 } ; /* More than enough for most purposes ! */ +QFB_T(qfb_gen, qfb_gen_len) ; + +#endif /* _ZEBRA_QFSTRING_H */ |