summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/utilities/util_misc.c
blob: f45f6b339f2da99da22f0329e72d6eae8629433f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*-
 * Copyright (c) 2014-2016 MongoDB, Inc.
 * Copyright (c) 2008-2014 WiredTiger, Inc.
 *	All rights reserved.
 *
 * See the file LICENSE for redistribution information.
 */

#include "util.h"

int
util_cerr(WT_CURSOR *cursor, const char *op, int ret)
{
	return (
	    util_err(cursor->session, ret, "%s: cursor.%s", cursor->uri, op));
}

/*
 * util_err --
 * 	Report an error.
 */
int
util_err(WT_SESSION *session, int e, const char *fmt, ...)
{
	va_list ap;

	(void)fprintf(stderr, "%s: ", progname);
	if (fmt != NULL) {
		va_start(ap, fmt);
		(void)vfprintf(stderr, fmt, ap);
		va_end(ap);
		if (e != 0)
			(void)fprintf(stderr, ": ");
	}
	if (e != 0)
		(void)fprintf(stderr, "%s", session == NULL ?
		    wiredtiger_strerror(e) : session->strerror(session, e));
	(void)fprintf(stderr, "\n");
	return (1);
}

/*
 * util_read_line --
 *	Read a line from stdin into a ULINE.
 */
int
util_read_line(WT_SESSION *session, ULINE *l, bool eof_expected, bool *eofp)
{
	static uint64_t line = 0;
	size_t len;
	int ch;

	++line;
	*eofp = false;

	if (l->memsize == 0) {
		if ((l->mem = realloc(l->mem, l->memsize + 1024)) == NULL)
			return (util_err(session, errno, NULL));
		l->memsize = 1024;
	}
	for (len = 0;; ++len) {
		if ((ch = getchar()) == EOF) {
			if (len == 0) {
				if (eof_expected) {
					*eofp = true;
					return (0);
				}
				return (util_err(session, 0,
				    "line %" PRIu64 ": unexpected end-of-file",
				    line));
			}
			return (util_err(session, 0,
			    "line %" PRIu64 ": no newline terminator", line));
		}
		if (ch == '\n')
			break;
		/*
		 * We nul-terminate the string so it's easier to convert the
		 * line into a record number, that means we always need one
		 * extra byte at the end.
		 */
		if (len >= l->memsize - 1) {
			if ((l->mem =
			    realloc(l->mem, l->memsize + 1024)) == NULL)
				return (util_err(session, errno, NULL));
			l->memsize += 1024;
		}
		((uint8_t *)l->mem)[len] = (uint8_t)ch;
	}

	((uint8_t *)l->mem)[len] = '\0';		/* nul-terminate */

	return (0);
}

/*
 * util_str2recno --
 *	Convert a string to a record number.
 */
int
util_str2recno(WT_SESSION *session, const char *p, uint64_t *recnop)
{
	uint64_t recno;
	char *endptr;

	/*
	 * strtouq takes lots of things like hex values, signs and so on and so
	 * forth -- none of them are OK with us.  Check the string starts with
	 * digit, that turns off the special processing.
	 */
	if (!isdigit(p[0]))
		goto format;

	errno = 0;
	recno = __wt_strtouq(p, &endptr, 0);
	if (recno == ULLONG_MAX && errno == ERANGE)
		return (
		    util_err(session, ERANGE, "%s: invalid record number", p));

	if (endptr[0] != '\0')
format:		return (
		    util_err(session, EINVAL, "%s: invalid record number", p));

	*recnop = recno;
	return (0);
}

/*
 * util_flush --
 *	Flush the file successfully, or drop it.
 */
int
util_flush(WT_SESSION *session, const char *uri)
{
	WT_DECL_RET;
	size_t len;
	char *buf;

	len = strlen(uri) + 100;
	if ((buf = malloc(len)) == NULL)
		return (util_err(session, errno, NULL));

	(void)snprintf(buf, len, "target=(\"%s\")", uri);
	if ((ret = session->checkpoint(session, buf)) != 0) {
		ret = util_err(session, ret, "%s: session.checkpoint", uri);
		(void)session->drop(session, uri, NULL);
	}

	free(buf);
	return (ret);
}