07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#pragma once
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering/***
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering This file is part of systemd.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering Copyright 2010 Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering systemd is free software; you can redistribute it and/or modify it
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering under the terms of the GNU Lesser General Public License as published by
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering (at your option) any later version.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering systemd is distributed in the hope that it will be useful, but
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering Lesser General Public License for more details.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering You should have received a copy of the GNU Lesser General Public License
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering***/
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <alloca.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <stdbool.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <stddef.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <string.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "macro.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering/* What is interpreted as whitespace? */
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define WHITESPACE " \t\n\r"
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define NEWLINE "\n\r"
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define QUOTES "\"\'"
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define COMMENTS "#;"
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define GLOB_CHARS "*?["
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define DIGITS "0123456789"
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz"
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering#define ALPHANUMERICAL LETTERS DIGITS
b11d6a7bed4d867fb9f6ff4e7eb4ab20fcdc9301Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define streq(a,b) (strcmp((a),(b)) == 0)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringint strcmp_ptr(const char *a, const char *b) _pure_;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic inline bool streq_ptr(const char *a, const char *b) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return strcmp_ptr(a, b) == 0;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering}
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic inline const char* strempty(const char *s) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return s ? s : "";
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering}
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic inline const char* strnull(const char *s) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return s ? s : "(null)";
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering}
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic inline const char *strna(const char *s) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return s ? s : "n/a";
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering}
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic inline bool isempty(const char *p) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return !p || !p[0];
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering}
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic inline char *startswith(const char *s, const char *prefix) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering size_t l;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering l = strlen(prefix);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering if (strncmp(s, prefix, l) == 0)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return (char*) s + l;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return NULL;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering}
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic inline char *startswith_no_case(const char *s, const char *prefix) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering size_t l;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering l = strlen(prefix);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering if (strncasecmp(s, prefix, l) == 0)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return (char*) s + l;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return NULL;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering}
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *endswith(const char *s, const char *postfix) _pure_;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *endswith_no_case(const char *s, const char *postfix) _pure_;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *first_word(const char *s, const char *word) _pure_;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringconst char* split(const char **state, size_t *l, const char *separator, bool quoted);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define FOREACH_WORD(word, length, s, state) \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _FOREACH_WORD(word, length, s, WHITESPACE, false, state)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _FOREACH_WORD(word, length, s, separator, false, state)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define FOREACH_WORD_QUOTED(word, length, s, state) \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _FOREACH_WORD(word, length, s, WHITESPACE, true, state)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define _FOREACH_WORD(word, length, s, separator, quoted, state) \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *strappend(const char *s, const char *suffix);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *strnappend(const char *s, const char *suffix, size_t length);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *strjoin(const char *x, ...) _sentinel_;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define strjoina(a, ...) \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering ({ \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering const char *_appendees_[] = { a, __VA_ARGS__ }; \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering char *_d_, *_p_; \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering int _len_ = 0; \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering unsigned _i_; \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _len_ += strlen(_appendees_[_i_]); \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _p_ = _d_ = alloca(_len_ + 1); \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _p_ = stpcpy(_p_, _appendees_[_i_]); \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering *_p_ = 0; \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _d_; \
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering })
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *strstrip(char *s);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *delete_chars(char *s, const char *bad);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *truncate_nl(char *s);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
b577e3d589ec00f6d96e90b0d4bf344dbd40cd76Lennart Poetteringchar ascii_tolower(char x);
b577e3d589ec00f6d96e90b0d4bf344dbd40cd76Lennart Poetteringchar *ascii_strlower(char *s);
b577e3d589ec00f6d96e90b0d4bf344dbd40cd76Lennart Poetteringchar *ascii_strlower_n(char *s, size_t n);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
522d85ae0a3dd80ec58033289c4f63ba7dfc63a8Lennart Poetteringint ascii_strcasecmp_n(const char *a, const char *b, size_t n);
c174983474d4a010a18e3bb9a59e351a442480f5Lennart Poetteringint ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m);
522d85ae0a3dd80ec58033289c4f63ba7dfc63a8Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringbool chars_intersect(const char *a, const char *b) _pure_;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic inline bool _pure_ in_charset(const char *s, const char* charset) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering assert(s);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering assert(charset);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return s[strspn(s, charset)] == '\0';
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering}
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringbool string_has_cc(const char *p, const char *ok) _pure_;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *ellipsize(const char *s, size_t length, unsigned percent);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringbool nulstr_contains(const char*nulstr, const char *needle);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar* strshorten(char *s, size_t l);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *strreplace(const char *text, const char *old_string, const char *new_string);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *strip_tab_ansi(char **p, size_t *l);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *strextend(char **x, ...) _sentinel_;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *strrep(const char *s, unsigned n);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringint split_pair(const char *s, const char *sep, char **l, char **r);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringint free_and_strdup(char **p, const char *s);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering if (needlelen <= 0)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return (void*) haystack;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering if (haystacklen < needlelen)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return NULL;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering assert(haystack);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering assert(needle);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return memmem(haystack, haystacklen, needle, needlelen);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering}
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
9fe4ea21bec739bfe0ebac5565f0539b0e25b317Lennart Poetteringvoid* memory_erase(void *p, size_t l);
9fe4ea21bec739bfe0ebac5565f0539b0e25b317Lennart Poetteringchar *string_erase(char *x);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringchar *string_free_erase(char *s);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart PoetteringDEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define _cleanup_string_free_erase_ _cleanup_(string_free_erasep)
f3e2e81d5385b9ffd84ed110d00eb347ec0e14f1Lennart Poettering
f3e2e81d5385b9ffd84ed110d00eb347ec0e14f1Lennart Poetteringbool string_is_safe(const char *p) _pure_;