summaryrefslogtreecommitdiffstats
path: root/source3/lib/replace/test/strptime.c
blob: fade3ecc57567d73ea5dc37ad902384f990f4f70 (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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define true 1
#define false 0

#ifndef __STRING
#define __STRING(x)    #x
#endif

/* make printf a no-op */
#define printf if(0) printf

#else /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */

#include "replace.h"
#include "system/time.h"

#endif /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */

int libreplace_test_strptime(void)
{
	const char *s = "20070414101546Z";
	char *ret;
	struct tm t, t2;

	memset(&t, 0, sizeof(t));
	memset(&t2, 0, sizeof(t2));

	printf("test: strptime\n");

	ret = strptime(s, "%Y%m%d%H%M%S", &t);
	if ( ret == NULL ) {
		printf("failure: strptime [\n"
		       "returned NULL\n"
		       "]\n");
		return false;
	}

	if ( *ret != 'Z' ) {
		printf("failure: strptime [\n"
		       "ret doesn't point to 'Z'\n"
		       "]\n");
		return false;
	}

	ret = strptime(s, "%Y%m%d%H%M%SZ", &t2);
	if ( ret == NULL ) {
		printf("failure: strptime [\n"
		       "returned NULL with Z\n"
		       "]\n");
		return false;
	}

	if ( *ret != '\0' ) {
		printf("failure: strptime [\n"
		       "ret doesn't point to '\\0'\n"
		       "]\n");
		return false;
	}

#define CMP_TM_ELEMENT(t1,t2,elem) \
	if (t1.elem != t2.elem) { \
		printf("failure: strptime [\n" \
		       "result differs if the format string has a 'Z' at the end\n" \
		       "element: %s %d != %d\n" \
		       "]\n", \
		       __STRING(elen), t1.elem, t2.elem); \
		return false; \
	}

	CMP_TM_ELEMENT(t,t2,tm_sec);
	CMP_TM_ELEMENT(t,t2,tm_min);
	CMP_TM_ELEMENT(t,t2,tm_hour);
	CMP_TM_ELEMENT(t,t2,tm_mday);
	CMP_TM_ELEMENT(t,t2,tm_mon);
	CMP_TM_ELEMENT(t,t2,tm_year);
	CMP_TM_ELEMENT(t,t2,tm_wday);
	CMP_TM_ELEMENT(t,t2,tm_yday);
	CMP_TM_ELEMENT(t,t2,tm_isdst);

	if (t.tm_sec != 46) {
		printf("failure: strptime [\n"
		       "tm_sec: expected: 46, got: %d\n"
		       "]\n",
		       t.tm_sec);
		return false;
	}

	if (t.tm_min != 15) {
		printf("failure: strptime [\n"
		       "tm_min: expected: 15, got: %d\n"
		       "]\n",
		       t.tm_min);
		return false;
	}

	if (t.tm_hour != 10) {
		printf("failure: strptime [\n"
		       "tm_hour: expected: 10, got: %d\n"
		       "]\n",
		       t.tm_hour);
		return false;
	}

	if (t.tm_mday != 14) {
		printf("failure: strptime [\n"
		       "tm_mday: expected: 14, got: %d\n"
		       "]\n",
		       t.tm_mday);
		return false;
	}

	if (t.tm_mon != 3) {
		printf("failure: strptime [\n"
		       "tm_mon: expected: 3, got: %d\n"
		       "]\n",
		       t.tm_mon);
		return false;
	}

	if (t.tm_year != 107) {
		printf("failure: strptime [\n"
		       "tm_year: expected: 107, got: %d\n"
		       "]\n",
		       t.tm_year);
		return false;
	}

	if (t.tm_wday != 6) { /* saturday */
		printf("failure: strptime [\n"
		       "tm_wday: expected: 6, got: %d\n"
		       "]\n",
		       t.tm_wday);
		return false;
	}

	if (t.tm_yday != 103) {
		printf("failure: strptime [\n"
		       "tm_yday: expected: 103, got: %d\n"
		       "]\n",
		       t.tm_yday);
		return false;
	}

	/* we don't test this as it depends on the host configuration
	if (t.tm_isdst != 0) {
		printf("failure: strptime [\n"
		       "tm_isdst: expected: 0, got: %d\n"
		       "]\n",
		       t.tm_isdst);
		return false;
	}*/

	printf("success: strptime\n");

	return true;
}

#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME
int main (void)
{
	int ret;
	ret = libreplace_test_strptime();
	if (ret == false) return 1;
	return 0;
}
#endif
s2/jffs2.h> #include <nand.h> #if defined(CONFIG_CMD_MTDPARTS) /* parition handling routines */ int mtdparts_init(void); int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); int find_dev_and_part(const char *id, struct mtd_device **dev, u8 *part_num, struct part_info **part); #endif static int nand_dump(nand_info_t *nand, ulong off, int only_oob) { int i; u_char *datbuf, *oobbuf, *p; datbuf = malloc(nand->writesize + nand->oobsize); oobbuf = malloc(nand->oobsize); if (!datbuf || !oobbuf) { puts("No memory for page buffer\n"); return 1; } off &= ~(nand->writesize - 1); loff_t addr = (loff_t) off; struct mtd_oob_ops ops; memset(&ops, 0, sizeof(ops)); ops.datbuf = datbuf; ops.oobbuf = oobbuf; /* must exist, but oob data will be appended to ops.datbuf */ ops.len = nand->writesize; ops.ooblen = nand->oobsize; ops.mode = MTD_OOB_RAW; i = nand->read_oob(nand, addr, &ops); if (i < 0) { printf("Error (%d) reading page %08lx\n", i, off); free(datbuf); free(oobbuf); return 1; } printf("Page %08lx dump:\n", off); i = nand->writesize >> 4; p = datbuf; while (i--) { if (!only_oob) printf("\t%02x %02x %02x %02x %02x %02x %02x %02x" " %02x %02x %02x %02x %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); p += 16; } puts("OOB:\n"); i = nand->oobsize >> 3; while (i--) { printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); p += 8; } free(datbuf); free(oobbuf); return 0; } /* ------------------------------------------------------------------------- */ static inline int str2long(char *p, ulong *num) { char *endptr; *num = simple_strtoul(p, &endptr, 16); return (*p != '\0' && *endptr == '\0') ? 1 : 0; } static int arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, size_t *size) { int idx = nand_curr_device; #if defined(CONFIG_CMD_MTDPARTS) struct mtd_device *dev; struct part_info *part; u8 pnum; if (argc >= 1 && !(str2long(argv[0], off))) { if ((mtdparts_init() == 0) && (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) { if (dev->id->type != MTD_DEV_TYPE_NAND) { puts("not a NAND device\n"); return -1; } *off = part->offset; if (argc >= 2) { if (!(str2long(argv[1], (ulong *)size))) { printf("'%s' is not a number\n", argv[1]); return -1; } if (*size > part->size) *size = part->size; } else { *size = part->size; } idx = dev->id->num; *nand = nand_info[idx]; goto out; } } #endif if (argc >= 1) { if (!(str2long(argv[0], off))) { printf("'%s' is not a number\n", argv[0]); return -1; } } else { *off = 0; } if (argc >= 2) { if (!(str2long(argv[1], (ulong *)size))) { printf("'%s' is not a number\n", argv[1]); return -1; } } else { *size = nand->size - *off; } #if defined(CONFIG_CMD_MTDPARTS) out: #endif printf("device %d ", idx); if (*size == nand->size) puts("whole chip\n"); else printf("offset 0x%lx, size 0x%zx\n", *off, *size); return 0; } #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK static void print_status(ulong start, ulong end, ulong erasesize, int status) { printf("%08lx - %08lx: %08lx blocks %s%s%s\n", start, end - 1, (end - start) / erasesize, ((status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), ((status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); } static void do_nand_status(nand_info_t *nand) { ulong block_start = 0; ulong off; int last_status = -1; struct nand_chip *nand_chip = nand->priv; /* check the WP bit */ nand_chip->cmdfunc(nand, NAND_CMD_STATUS, -1, -1); printf("device is %swrite protected\n", (nand_chip->read_byte(nand) & 0x80 ? "NOT " : "")); for (off = 0; off < nand->size; off += nand->erasesize) { int s = nand_get_lock_status(nand, off); /* print message only if status has changed */ if (s != last_status && off != 0) { print_status(block_start, off, nand->erasesize, last_status); block_start = off; } last_status = s; } /* Print the last block info */ print_status(block_start, off, nand->erasesize, last_status); } #endif static void nand_print_info(int idx) { nand_info_t *nand = &nand_info[idx]; struct nand_chip *chip = nand->priv; printf("Device %d: ", idx); if (chip->numchips > 1) printf("%dx ", chip->numchips); printf("%s, sector size %u KiB\n", nand->name, nand->erasesize >> 10); } int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int i, dev, ret = 0; ulong addr, off; size_t size; char *cmd, *s; nand_info_t *nand; #ifdef CONFIG_SYS_NAND_QUIET int quiet = CONFIG_SYS_NAND_QUIET; #else int quiet = 0; #endif const char *quiet_str = getenv("quiet"); /* at least two arguments please */ if (argc < 2) goto usage; if (quiet_str) quiet = simple_strtoul(quiet_str, NULL, 0) != 0; cmd = argv[1]; if (strcmp(cmd, "info") == 0) { putc('\n'); for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) { if (nand_info[i].name) nand_print_info(i); } return 0; } if (strcmp(cmd, "device") == 0) { if (argc < 3) { putc('\n'); if ((nand_curr_device < 0) || (nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE)) puts("no devices available\n"); else nand_print_info(nand_curr_device); return 0; } dev = (int)simple_strtoul(argv[2], NULL, 10); if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[dev].name) { puts("No such device\n"); return 1; } printf("Device %d: %s", dev, nand_info[dev].name); puts("... is now current device\n"); nand_curr_device = dev; #ifdef CONFIG_SYS_NAND_SELECT_DEVICE /* * Select the chip in the board/cpu specific driver */ board_nand_select_device(nand_info[dev].priv, dev); #endif return 0; } if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && strncmp(cmd, "dump", 4) != 0 && strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 && strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 && strcmp(cmd, "biterr") != 0 && strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 ) goto usage; /* the following commands operate on the current device */ if (nand_curr_device < 0 || nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[nand_curr_device].name) { puts("\nno devices available\n"); return 1; } nand = &nand_info[nand_curr_device]; if (strcmp(cmd, "bad") == 0) { printf("\nDevice %d bad blocks:\n", nand_curr_device); for (off = 0; off < nand->size; off += nand->erasesize) if (nand_block_isbad(nand, off)) printf(" %08lx\n", off); return 0; } /* * Syntax is: * 0 1 2 3 4 * nand erase [clean] [off size] */ if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) { nand_erase_options_t opts; /* "clean" at index 2 means request to write cleanmarker */ int clean = argc > 2 && !strcmp("clean", argv[2]); int o = clean ? 3 : 2; int scrub = !strcmp(cmd, "scrub"); printf("\nNAND %s: ", scrub ? "scrub" : "erase"); /* skip first two or three arguments, look for offset and size */ if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0) return 1; memset(&opts, 0, sizeof(opts)); opts.offset = off; opts.length = size; opts.jffs2 = clean; opts.quiet = quiet; if (scrub) { puts("Warning: " "scrub option will erase all factory set " "bad blocks!\n" " " "There is no reliable way to recover them.\n" " " "Use this command only for testing purposes " "if you\n" " " "are sure of what you are doing!\n" "\nReally scrub this NAND flash? <y/N>\n"); if (getc() == 'y' && getc() == '\r') { opts.scrub = 1; } else { puts("scrub aborted\n"); return -1; } } ret = nand_erase_opts(nand, &opts); printf("%s\n", ret ? "ERROR" : "OK"); return ret == 0 ? 0 : 1; } if (strncmp(cmd, "dump", 4) == 0) { if (argc < 3) goto usage; s = strchr(cmd, '.'); off = (int)simple_strtoul(argv[2], NULL, 16); if (s != NULL && strcmp(s, ".oob") == 0) ret = nand_dump(nand, off, 1); else ret = nand_dump(nand, off, 0); return ret == 0 ? 1 : 0; } if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { int read; if (argc < 4) goto usage; addr = (ulong)simple_strtoul(argv[2], NULL, 16); read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ printf("\nNAND %s: ", read ? "read" : "write"); if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) return 1; s = strchr(cmd, '.'); if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")) { if (read) ret = nand_read_skip_bad(nand, off, &size, (u_char *)addr); else ret = nand_write_skip_bad(nand, off, &size, (u_char *)addr); } else if (!strcmp(s, ".oob")) { /* out-of-band data */ mtd_oob_ops_t ops = { .oobbuf = (u8 *)addr, .ooblen = size, .mode = MTD_OOB_RAW }; if (read) ret = nand->read_oob(nand, off, &ops); else ret = nand->write_oob(nand, off, &ops); } else { printf("Unknown nand command suffix '%s'.\n", s); return 1; } printf(" %zu bytes %s: %s\n", size, read ? "read" : "written", ret ? "ERROR" : "OK"); return ret == 0 ? 0 : 1; } if (strcmp(cmd, "markbad") == 0) { argc -= 2; argv += 2; if (argc <= 0) goto usage; while (argc > 0) { addr = simple_strtoul(*argv, NULL, 16); if (nand->block_markbad(nand, addr)) { printf("block 0x%08lx NOT marked " "as bad! ERROR %d\n", addr, ret); ret = 1; } else { printf("block 0x%08lx successfully " "marked as bad\n", addr); } --argc; ++argv; } return ret; } if (strcmp(cmd, "biterr") == 0) { /* todo */ return 1; } #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK if (strcmp(cmd, "lock") == 0) { int tight = 0; int status = 0;