Commit 9965fc25 authored by Rusty Russell's avatar Rusty Russell

Rename string to str, and split into three modules.

parent 963fa5ca
#include <stdio.h>
#include <string.h>
#include "config.h"
/**
* grab_file - file helper routines
*
* This contains simple functions for getting the contents of a file.
*
* Example:
* #include "grab_file/grab_file.h"
* #include <err.h>
* #include <stdio.h>
* #include <string.h>
*
* int main(int argc, char *argv[])
* {
* size_t len;
* char *file;
*
* file = grab_file(NULL, argv[1], &len);
* if (!file)
* err(1, "Could not read file %s", argv[1]);
* if (strlen(file) != len)
* printf("File contains NUL characters\n");
* else if (len == 0)
* printf("File contains nothing\n");
* else if (strchr(file, '\n'))
* printf("File contains multiple lines\n");
* else
* printf("File contains one line\n");
* talloc_free(file);
*
* return 0;
* }
*
* Licence: LGPL (2 or any later version)
*/
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/talloc\n");
printf("ccan/noerr\n");
return 0;
}
return 1;
}
#include "grab_file.h"
#include "talloc/talloc.h"
#include "noerr/noerr.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void *grab_fd(const void *ctx, int fd, size_t *size)
{
int ret;
size_t max = 16384, s;
char *buffer;
if (!size)
size = &s;
*size = 0;
buffer = talloc_array(ctx, char, max+1);
while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
*size += ret;
if (*size == max)
buffer = talloc_realloc(ctx, buffer, char, max*=2 + 1);
}
if (ret < 0) {
talloc_free(buffer);
buffer = NULL;
} else
buffer[*size] = '\0';
return buffer;
}
void *grab_file(const void *ctx, const char *filename, size_t *size)
{
int fd;
char *buffer;
if (!filename)
fd = dup(STDIN_FILENO);
else
fd = open(filename, O_RDONLY, 0);
if (fd < 0)
return NULL;
buffer = grab_fd(ctx, fd, size);
close_noerr(fd);
return buffer;
}
#ifndef CCAN_GRAB_FILE_H
#define CCAN_GRAB_FILE_H
#include <stdio.h> // For size_t
/**
* grab_fd - read all of a file descriptor into memory
* @ctx: the context to tallocate from (often NULL)
* @fd: the file descriptor to read from
* @size: the (optional) size of the file
*
* This function reads from the given file descriptor until no more
* input is available. The content is talloced off @ctx, and the size
* of the file places in @size if it's non-NULL. For convenience, the
* byte after the end of the content will always be NUL.
*
* Example:
* // Return all of standard input, as lines.
* char **read_as_lines(void)
* {
* char **lines, *all;
*
* all = grab_fd(NULL, 0, NULL);
* if (!all)
* return NULL;
* lines = strsplit(NULL, all, "\n", NULL);
* talloc_free(all);
* return lines;
* }
*/
void *grab_fd(const void *ctx, int fd, size_t *size);
/**
* grab_file - read all of a file (or stdin) into memory
* @ctx: the context to tallocate from (often NULL)
* @filename: the file to read (NULL for stdin)
* @size: the (optional) size of the file
*
* This function reads from the given file until no more input is
* available. The content is talloced off @ctx, and the size of the
* file places in @size if it's non-NULL. For convenience, the byte
* after the end of the content will always be NUL.
*
* Example:
* // Return all of a given file, as lines.
* char **read_as_lines(const char *filename)
* {
* char **lines, *all;
*
* all = grab_file(NULL, filename, NULL);
* if (!all)
* return NULL;
* lines = strsplit(NULL, all, "\n", NULL);
* talloc_free(all);
* return lines;
* }
*/
void *grab_file(const void *ctx, const char *filename, size_t *size);
#endif /* CCAN_GRAB_FILE_H */
......@@ -3,13 +3,13 @@
#include "config.h"
/**
* string - string helper routines
* str - string helper routines
*
* This is a grab bag of modules for string operations, designed to enhance
* This is a grab bag of functions for string operations, designed to enhance
* the standard string.h.
*
* Example:
* #include "string/string.h"
* #include "str/str.h"
*
* int main(int argc, char *argv[])
* {
......@@ -30,8 +30,6 @@ int main(int argc, char *argv[])
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/talloc\n");
printf("ccan/noerr\n");
return 0;
}
......
#ifndef CCAN_STR_H
#define CCAN_STR_H
#include <string.h>
#include <stdbool.h>
/**
* streq - Are two strings equal?
* @a: first string
* @b: first string
*
* This macro is arguably more readable than "!strcmp(a, b)".
*
* Example:
* if (streq(str, ""))
* printf("String is empty!\n");
*/
#define streq(a,b) (strcmp((a),(b)) == 0)
/**
* strstarts - Does this string start with this prefix?
* @str: string to test
* @prefix: prefix to look for at start of str
*
* Example:
* if (strstarts(str, "foo"))
* printf("String %s begins with 'foo'!\n", str);
*/
#define strstarts(str,prefix) (strncmp((str),(prefix),strlen(prefix)) == 0)
/**
* strends - Does this string end with this postfix?
* @str: string to test
* @postfix: postfix to look for at end of str
*
* Example:
* if (strends(str, "foo"))
* printf("String %s end with 'foo'!\n", str);
*/
static inline bool strends(const char *str, const char *postfix)
{
if (strlen(str) < strlen(postfix))
return false;
return streq(str + strlen(str) - strlen(postfix), postfix);
}
#endif /* CCAN_STR_H */
......@@ -38,7 +38,7 @@ int main(int argc, char *argv[])
}
}
plan_tests(n * n * 5 + 19);
plan_tests(n * n * 5);
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
unsigned int k, identical = 0;
......@@ -79,41 +79,5 @@ int main(int argc, char *argv[])
}
}
split = strsplit(NULL, "hello world", " ", &n);
ok1(n == 3);
ok1(streq(split[0], "hello"));
ok1(streq(split[1], ""));
ok1(streq(split[2], "world"));
ok1(split[3] == NULL);
talloc_free(split);
split = strsplit(NULL, "hello world", " ", NULL);
ok1(streq(split[0], "hello"));
ok1(streq(split[1], ""));
ok1(streq(split[2], "world"));
ok1(split[3] == NULL);
talloc_free(split);
split = strsplit(NULL, "hello world", "o ", NULL);
ok1(streq(split[0], "hell"));
ok1(streq(split[1], ""));
ok1(streq(split[2], ""));
ok1(streq(split[3], "w"));
ok1(streq(split[4], "rld"));
ok1(split[5] == NULL);
ctx = split;
split = strsplit(ctx, "hello world", "o ", NULL);
ok1(talloc_parent(split) == ctx);
talloc_free(ctx);
str = strjoin(NULL, substrings, ", ");
ok1(streq(str, "far, bar, baz, b, ba, z, ar, "));
ctx = str;
str = strjoin(ctx, substrings, "");
ok1(streq(str, "farbarbazbbazar"));
ok1(talloc_parent(str) == ctx);
talloc_free(ctx);
return exit_status();
}
#include <stdio.h>
#include <string.h>
#include "config.h"
/**
* str_talloc - string helper routines which use talloc
*
* This is a grab bag of fnctions for string operations, designed to enhance
* the standard string.h; these are separated from the non-talloc-needing
* string utilities in "str.h".
*
* Example:
* #include "str_talloc/str_talloc.h"
* #include "talloc/talloc.h"
* #include "grab_file/grab_file.h"
* #include <err.h>
*
* // Dumb demo program to double-linespace a file.
* int main(int argc, char *argv[])
* {
* char *textfile;
* char **lines;
*
* // Grab lines in file.
* textfile = grab_file(NULL, argv[1], NULL);
* if (!textfile)
* err(1, "Failed reading %s", argv[1]);
* lines = strsplit(textfile, textfile, "\n", NULL);
*
* // Join them back together with two linefeeds.
* printf("%s", strjoin(textfile, lines, "\n\n"));
*
* // Free everything, just because we can.
* talloc_free(textfile);
* return 0;
* }
*
* Licence: LGPL (2 or any later version)
*/
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/talloc\n");
printf("ccan/noerr\n");
return 0;
}
return 1;
}
......@@ -2,15 +2,9 @@
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#include <stdlib.h>
#include "string.h"
#include "str_talloc.h"
#include "talloc/talloc.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "noerr/noerr.h"
char **strsplit(const void *ctx, const char *string, const char *delims,
unsigned int *nump)
......@@ -47,46 +41,3 @@ char *strjoin(const void *ctx, char *strings[], const char *delim)
}
return ret;
}
void *grab_fd(const void *ctx, int fd, size_t *size)
{
int ret;
size_t max = 16384, s;
char *buffer;
if (!size)
size = &s;
*size = 0;
buffer = talloc_array(ctx, char, max+1);
while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
*size += ret;
if (*size == max)
buffer = talloc_realloc(ctx, buffer, char, max*=2 + 1);
}
if (ret < 0) {
talloc_free(buffer);
buffer = NULL;
} else
buffer[*size] = '\0';
return buffer;
}
void *grab_file(const void *ctx, const char *filename, size_t *size)
{
int fd;
char *buffer;
if (!filename)
fd = dup(STDIN_FILENO);
else
fd = open(filename, O_RDONLY, 0);
if (fd < 0)
return NULL;
buffer = grab_fd(ctx, fd, size);
close_noerr(fd);
return buffer;
}
#ifndef CCAN_STRING_H
#define CCAN_STRING_H
#ifndef CCAN_STR_TALLOC_H
#define CCAN_STR_TALLOC_H
#include <string.h>
#include <stdbool.h>
/**
* streq - Are two strings equal?
* @a: first string
* @b: first string
*
* This macro is arguably more readable than "!strcmp(a, b)".
*
* Example:
* if (streq(str, ""))
* printf("String is empty!\n");
*/
#define streq(a,b) (strcmp((a),(b)) == 0)
/**
* strstarts - Does this string start with this prefix?
* @str: string to test
* @prefix: prefix to look for at start of str
*
* Example:
* if (strstarts(str, "foo"))
* printf("String %s begins with 'foo'!\n", str);
*/
#define strstarts(str,prefix) (strncmp((str),(prefix),strlen(prefix)) == 0)
/**
* strends - Does this string end with this postfix?
* @str: string to test
* @postfix: postfix to look for at end of str
*
* Example:
* if (strends(str, "foo"))
* printf("String %s end with 'foo'!\n", str);
*/
static inline bool strends(const char *str, const char *postfix)
{
if (strlen(str) < strlen(postfix))
return false;
return streq(str + strlen(str) - strlen(postfix), postfix);
}
/**
* strsplit - Split string into an array of substrings
* @ctx: the context to tallocate from (often NULL)
......@@ -102,58 +61,4 @@ char **strsplit(const void *ctx, const char *string, const char *delims,
* }
*/
char *strjoin(const void *ctx, char *strings[], const char *delim);
/**
* grab_fd - read all of a file descriptor into memory
* @ctx: the context to tallocate from (often NULL)
* @fd: the file descriptor to read from
* @size: the (optional) size of the file
*
* This function reads from the given file descriptor until no more
* input is available. The content is talloced off @ctx, and the size
* of the file places in @size if it's non-NULL. For convenience, the
* byte after the end of the content will always be NUL.
*
* Example:
* // Return all of standard input, as lines.
* char **read_as_lines(void)
* {
* char **lines, *all;
*
* all = grab_fd(NULL, 0, NULL);
* if (!all)
* return NULL;
* lines = strsplit(NULL, all, "\n", NULL);
* talloc_free(all);
* return lines;
* }
*/
void *grab_fd(const void *ctx, int fd, size_t *size);
/**
* grab_file - read all of a file (or stdin) into memory
* @ctx: the context to tallocate from (often NULL)
* @filename: the file to read (NULL for stdin)
* @size: the (optional) size of the file
*
* This function reads from the given file until no more input is
* available. The content is talloced off @ctx, and the size of the
* file places in @size if it's non-NULL. For convenience, the byte
* after the end of the content will always be NUL.
*
* Example:
* // Return all of a given file, as lines.
* char **read_as_lines(const char *filename)
* {
* char **lines, *all;
*
* all = grab_file(NULL, filename, NULL);
* if (!all)
* return NULL;
* lines = strsplit(NULL, all, "\n", NULL);
* talloc_free(all);
* return lines;
* }
*/
void *grab_file(const void *ctx, const char *filename, size_t *size);
#endif /* CCAN_STRING_H */
#endif /* CCAN_STR_TALLOC_H */
#include "str_talloc/str_talloc.h"
#include <stdlib.h>
#include <stdio.h>
#include "str_talloc/str_talloc.c"
#include "tap/tap.h"
/* FIXME: ccanize */
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
int main(int argc, char *argv[])
{
unsigned int i, j, n;
plan_tests(19);
split = strsplit(NULL, "hello world", " ", &n);
ok1(n == 3);
ok1(streq(split[0], "hello"));
ok1(streq(split[1], ""));
ok1(streq(split[2], "world"));
ok1(split[3] == NULL);
talloc_free(split);
split = strsplit(NULL, "hello world", " ", NULL);
ok1(streq(split[0], "hello"));
ok1(streq(split[1], ""));
ok1(streq(split[2], "world"));
ok1(split[3] == NULL);
talloc_free(split);
split = strsplit(NULL, "hello world", "o ", NULL);
ok1(streq(split[0], "hell"));
ok1(streq(split[1], ""));
ok1(streq(split[2], ""));
ok1(streq(split[3], "w"));
ok1(streq(split[4], "rld"));
ok1(split[5] == NULL);
ctx = split;
split = strsplit(ctx, "hello world", "o ", NULL);
ok1(talloc_parent(split) == ctx);
talloc_free(ctx);
str = strjoin(NULL, substrings, ", ");
ok1(streq(str, "far, bar, baz, b, ba, z, ar, "));
ctx = str;
str = strjoin(ctx, substrings, "");
ok1(streq(str, "farbarbazbbazar"));
ok1(talloc_parent(str) == ctx);
talloc_free(ctx);
return exit_status();
}
......@@ -27,7 +27,7 @@
#include <stdio.h>
#include <stdarg.h>
#include "config.h"
#include "ccan/typesafe_cb/typesafe_cb.h"
#include "typesafe_cb/typesafe_cb.h"
/*
this uses a little trick to allow __LINE__ to be stringified
......
......@@ -2,7 +2,7 @@
#include <err.h>
#include <stdlib.h>
#include <stdio.h>
#include "string/string.h"
#include "str/str.h"
#include "talloc/talloc.h"
int main(int argc, char *argv[])
......
......@@ -23,7 +23,8 @@ tools/ccanlint/ccanlint: \
$(OBJS) \
tools/ccanlint/ccanlint.o \
tools/ccanlint/file_analysis.o \
ccan/string/string.o ccan/talloc/talloc.o ccan/noerr/noerr.o
ccan/str_talloc/str_talloc.o ccan/grab_file/grab_file.o \
ccan/talloc/talloc.o ccan/noerr/noerr.o
ccanlint-clean:
$(RM) tools/ccanlint/generated-init-tests
......
#include "ccanlint.h"
#include "get_file_lines.h"
#include <talloc/talloc.h>
#include <string/string.h>
#include <str/str.h>
#include <str_talloc/str_talloc.h>
#include <grab_file/grab_file.h>
#include <noerr/noerr.h>
#include <unistd.h>
#include <sys/types.h>
......
......@@ -8,7 +8,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <string/string.h>
#include <str/str.h>
#include <talloc/talloc.h>
#include <noerr/noerr.h>
......
......@@ -8,9 +8,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <string/string.h>
#include <talloc/talloc.h>
#include <noerr/noerr.h>
static char test_is_not_dir[] = "test is not a directory";
......
#include "ccanlint.h"
#include <talloc/talloc.h>
#include <string/string.h>
#include <str/str.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
......
/* Trailing whitespace test. Almost embarrassing, but trivial. */
#include "ccanlint.h"
#include <talloc/talloc.h>
#include <string/string.h>
#include <str/str.h>
static char *report_on_trailing_whitespace(const char *line)
{
......
......@@ -4,7 +4,8 @@
#include <stdio.h>
#include <string.h>
#include <sqlite3.h>
#include "ccan/string/string.h"
#include "ccan/grab_file/grab_file.h"
#include "ccan/str_talloc/str_talloc.h"
#include "ccan/talloc/talloc.h"
#include "tools/_infotojson/database.h"
......
#include "talloc/talloc.h"
#include "string/string.h"
#include "str/str.h"
#include "grab_file/grab_file.h"
#include "str_talloc/str_talloc.h"
#include "tools.h"
#include <err.h>
#include <stdbool.h>
......
......@@ -9,7 +9,9 @@
#include <fcntl.h>
#include <stdbool.h>
#include "talloc/talloc.h"
#include "string/string.h"
#include "str/str.h"
#include "str_talloc/str_talloc.h"
#include "grab_file/grab_file.h"
static char **grab_doc(const char *fname)
{
......
......@@ -10,7 +10,9 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "ccan/string/string.h"
#include "ccan/str/str.h"
#include "ccan/str_talloc/str_talloc.h"
#include "ccan/grab_file/grab_file.h"
#include "ccan/talloc/talloc.h"
#include "tools.h"
......
......@@ -6,7 +6,7 @@
#include <unistd.h>
#include "ccan/tap/tap.h"
#include "ccan/talloc/talloc.h"
#include "ccan/string/string.h"
#include "ccan/str/str.h"
#include "tools.h"
/* FIXME: Use build bug later. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment