Compare commits
7 commits
devel
...
dev/compsi
Author | SHA1 | Date | |
---|---|---|---|
c8d23eec67 | |||
ce31dc1c08 | |||
84b49246a4 | |||
2aead46fac | |||
2222d18dae | |||
614ea40d2f | |||
7fd2e51c72 |
14
Makefile
14
Makefile
|
@ -499,6 +499,16 @@ test-json: json-formatter-test
|
|||
done \
|
||||
}
|
||||
|
||||
test-string-table: string-table-test
|
||||
@echo " [TEST] string-table formatting"
|
||||
@{ \
|
||||
max=`./string-table-test`; \
|
||||
for testno in `seq 1 $$max`; do \
|
||||
echo " [TEST/s-t] $$testno"; \
|
||||
./string-table-test $$testno ; \
|
||||
done \
|
||||
}
|
||||
|
||||
test: test-check test-check-lowmem test-mkfs test-misc test-cli test-convert test-fuzz
|
||||
|
||||
testsuite: btrfs-corrupt-block btrfs-find-root btrfs-select-super fssum fsstress
|
||||
|
@ -748,6 +758,10 @@ json-formatter-test: tests/json-formatter-test.c $(objects) libbtrfsutil.a
|
|||
@echo " [LD] $@"
|
||||
$(Q)$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
|
||||
|
||||
string-table-test: tests/string-table-test.c $(objects) libbtrfsutil.a
|
||||
@echo " [LD] $@"
|
||||
$(Q)$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
|
||||
|
||||
test-build: test-build-pre test-build-real
|
||||
|
||||
test-build-pre:
|
||||
|
|
1198
cmds/inspect.c
1198
cmds/inspect.c
File diff suppressed because it is too large
Load diff
|
@ -18,15 +18,17 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "common/messages.h"
|
||||
#include "common/string-table.h"
|
||||
#include "common/internal.h"
|
||||
|
||||
/*
|
||||
* This function create an array of char * which will represent a table
|
||||
* Create an array of char* which will point to table cell strings
|
||||
*/
|
||||
struct string_table *table_create(int columns, int rows)
|
||||
struct string_table *table_create(unsigned int columns, unsigned int rows)
|
||||
{
|
||||
struct string_table *tab;
|
||||
int size;
|
||||
size_t size;
|
||||
|
||||
size = sizeof(struct string_table) + rows * columns * sizeof(char*);
|
||||
tab = calloc(1, size);
|
||||
|
@ -36,27 +38,30 @@ struct string_table *table_create(int columns, int rows)
|
|||
|
||||
tab->ncols = columns;
|
||||
tab->nrows = rows;
|
||||
tab->spacing = STRING_TABLE_SPACING_1;
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is like a vprintf, but store the results in a cell of
|
||||
* the table.
|
||||
* If fmt starts with '<', the text is left aligned; if fmt starts with
|
||||
* '>' the text is right aligned. If fmt is equal to '=' the text will
|
||||
* be replaced by a '=====' dimensioned on the basis of the column width
|
||||
* This is like a vprintf, but stores the results in a cell of the table.
|
||||
*/
|
||||
__attribute__ ((format (printf, 4, 0)))
|
||||
char *table_vprintf(struct string_table *tab, int column, int row,
|
||||
char *table_vprintf(struct string_table *tab, unsigned int column, unsigned int row,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
int idx = tab->ncols * row + column;
|
||||
unsigned int idx = tab->ncols * row + column;
|
||||
char *msg = calloc(100, 1);
|
||||
|
||||
if (!msg)
|
||||
return NULL;
|
||||
|
||||
if (column >= tab->ncols || row >= tab->nrows) {
|
||||
error("attempt to write outside of table: col %u row %u fmt %s",
|
||||
column, row, fmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tab->cells[idx])
|
||||
free(tab->cells[idx]);
|
||||
tab->cells[idx] = msg;
|
||||
|
@ -66,12 +71,11 @@ char *table_vprintf(struct string_table *tab, int column, int row,
|
|||
}
|
||||
|
||||
/*
|
||||
* This function is like a printf, but store the results in a cell of
|
||||
* the table.
|
||||
* This is like a printf, but stores the results in a cell of the table.
|
||||
*/
|
||||
__attribute__ ((format (printf, 4, 5)))
|
||||
char *table_printf(struct string_table *tab, int column, int row,
|
||||
const char *fmt, ...)
|
||||
char *table_printf(struct string_table *tab, unsigned int column, unsigned int row,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *ret;
|
||||
|
@ -84,17 +88,36 @@ char *table_printf(struct string_table *tab, int column, int row,
|
|||
}
|
||||
|
||||
/*
|
||||
* This function dumps the table. Every "=" string will be replaced by
|
||||
* a "=======" length as the column
|
||||
* Print the table to stdout, interpret the alignment and expand specifiers.
|
||||
* @from: row from which to start
|
||||
* @to: upper row limit (not inclusive), 0 for the whole table
|
||||
*
|
||||
* Formatting:
|
||||
* <TEXT - the TEXT is left aligned
|
||||
* >TEXT - the TEXT is right aligned
|
||||
* = - the cell text will be filled by ===== (column width)
|
||||
* *C - the cell text will be filled by character C (column width)
|
||||
*/
|
||||
void table_dump(struct string_table *tab)
|
||||
void table_dump_range(struct string_table *tab, unsigned int from, unsigned int to)
|
||||
{
|
||||
int sizes[tab->ncols];
|
||||
int i, j;
|
||||
unsigned int sizes[tab->ncols];
|
||||
unsigned int i, j;
|
||||
unsigned int prescan;
|
||||
|
||||
if (to == 0)
|
||||
to = tab->nrows;
|
||||
|
||||
if (from > to) {
|
||||
error("invalid range for table dump %u > %u", from, to);
|
||||
return;
|
||||
}
|
||||
|
||||
prescan = max_t(unsigned int, 100, to);
|
||||
prescan = min_t(unsigned int, tab->nrows, prescan);
|
||||
|
||||
for (i = 0; i < tab->ncols; i++) {
|
||||
sizes[i] = 0;
|
||||
for (j = 0; j < tab->nrows; j++) {
|
||||
for (j = 0; j < prescan; j++) {
|
||||
int idx = i + j * tab->ncols;
|
||||
int len;
|
||||
|
||||
|
@ -110,7 +133,7 @@ void table_dump(struct string_table *tab)
|
|||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < tab->nrows; j++) {
|
||||
for (j = from; j < to; j++) {
|
||||
for (i = 0; i < tab->ncols; i++) {
|
||||
int idx = i + j * tab->ncols;
|
||||
char *cell = tab->cells[idx];
|
||||
|
@ -127,8 +150,11 @@ void table_dump(struct string_table *tab)
|
|||
cell[0] == '<' ? -sizes[i] : sizes[i],
|
||||
cell + 1);
|
||||
}
|
||||
if (i != (tab->ncols - 1))
|
||||
if (i != (tab->ncols - 1)) {
|
||||
putchar(' ');
|
||||
if (tab->spacing == STRING_TABLE_SPACING_2)
|
||||
putchar(' ');
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
@ -139,7 +165,7 @@ void table_dump(struct string_table *tab)
|
|||
*/
|
||||
void table_free(struct string_table *tab)
|
||||
{
|
||||
int i, count;
|
||||
unsigned int i, count;
|
||||
|
||||
count = tab->ncols * tab->nrows;
|
||||
|
||||
|
@ -149,3 +175,20 @@ void table_free(struct string_table *tab)
|
|||
|
||||
free(tab);
|
||||
}
|
||||
|
||||
void table_clear_range(struct string_table *tab, unsigned int from, unsigned int to)
|
||||
{
|
||||
unsigned int row, col;
|
||||
|
||||
if (to == 0)
|
||||
to = tab->nrows;
|
||||
|
||||
for (row = from; row < to; row++) {
|
||||
char **rowstart = &tab->cells[row * tab->ncols];
|
||||
|
||||
for (col = 0; col < tab->ncols; col++) {
|
||||
free(rowstart[col]);
|
||||
rowstart[col] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,18 +19,55 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
enum string_table_spacing {
|
||||
STRING_TABLE_SPACING_1,
|
||||
STRING_TABLE_SPACING_2,
|
||||
};
|
||||
|
||||
struct string_table {
|
||||
int ncols;
|
||||
int nrows;
|
||||
unsigned int ncols;
|
||||
unsigned int nrows;
|
||||
/* How many rows are header (names and separators). */
|
||||
unsigned int hrows;
|
||||
enum string_table_spacing spacing;
|
||||
char *cells[];
|
||||
};
|
||||
|
||||
struct string_table *table_create(int columns, int rows);
|
||||
char *table_printf(struct string_table *tab, int column, int row,
|
||||
struct string_table *table_create(unsigned int columns, unsigned int rows);
|
||||
__attribute__ ((format (printf, 4, 0)))
|
||||
char *table_printf(struct string_table *tab, unsigned int column, unsigned int row,
|
||||
const char *fmt, ...);
|
||||
char *table_vprintf(struct string_table *tab, int column, int row,
|
||||
char *table_vprintf(struct string_table *tab, unsigned int column, unsigned int row,
|
||||
const char *fmt, va_list ap);
|
||||
void table_dump(struct string_table *tab);
|
||||
void table_free(struct string_table *);
|
||||
void table_free(struct string_table *tab);
|
||||
|
||||
void table_dump_range(struct string_table *tab, unsigned int from, unsigned int to);
|
||||
|
||||
static inline void table_dump(struct string_table *tab)
|
||||
{
|
||||
table_dump_range(tab, 0, 0);
|
||||
}
|
||||
|
||||
static inline void table_dump_header(struct string_table *tab)
|
||||
{
|
||||
table_dump_range(tab, 0, tab->hrows);
|
||||
}
|
||||
|
||||
static inline void table_dump_body(struct string_table *tab)
|
||||
{
|
||||
table_dump_range(tab, tab->hrows, 0);
|
||||
}
|
||||
|
||||
void table_clear_range(struct string_table *tab, unsigned int from, unsigned int to);
|
||||
|
||||
static inline void table_clear_header(struct string_table *tab)
|
||||
{
|
||||
table_clear_range(tab, 0, tab->hrows);
|
||||
}
|
||||
|
||||
static inline void table_clear_body(struct string_table *tab)
|
||||
{
|
||||
table_clear_range(tab, tab->hrows, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
132
tests/string-table-test.c
Normal file
132
tests/string-table-test.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License v2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 021110-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "common/utils.h"
|
||||
#include "common/string-table.h"
|
||||
|
||||
void test_simple_create_free()
|
||||
{
|
||||
struct string_table *tab;
|
||||
|
||||
tab = table_create(2, 2);
|
||||
if (!tab) {
|
||||
fprintf(stderr, "ERROR: cannot alocate table\n");
|
||||
return;
|
||||
}
|
||||
table_printf(tab, 0, 0, ">00");
|
||||
table_printf(tab, 0, 1, "<01");
|
||||
table_printf(tab, 1, 0, ">10");
|
||||
table_printf(tab, 1, 1, "<11");
|
||||
|
||||
table_dump(tab);
|
||||
|
||||
table_free(tab);
|
||||
}
|
||||
|
||||
void test_simple_header()
|
||||
{
|
||||
struct string_table *tab;
|
||||
int i;
|
||||
|
||||
tab = table_create(2, 6);
|
||||
if (!tab) {
|
||||
fprintf(stderr, "ERROR: cannot alocate table\n");
|
||||
return;
|
||||
}
|
||||
tab->hrows = 2;
|
||||
table_printf(tab, 0, 0, ">Id");
|
||||
table_printf(tab, 1, 0, ">Name");
|
||||
table_printf(tab, 0, 1, "*-");
|
||||
table_printf(tab, 1, 1, "*-");
|
||||
|
||||
for (i = tab->hrows; i < tab->nrows; i++) {
|
||||
table_printf(tab, 0, i, ">%d", 1U << i);
|
||||
table_printf(tab, 1, i, "<%d", 100 * i);
|
||||
}
|
||||
|
||||
puts("start");
|
||||
table_dump_header(tab);
|
||||
puts("separator");
|
||||
table_dump_body(tab);
|
||||
puts("end");
|
||||
|
||||
table_free(tab);
|
||||
}
|
||||
|
||||
void test_simple_paginate()
|
||||
{
|
||||
struct string_table *tab;
|
||||
unsigned int page_size = 4;
|
||||
unsigned int pages = 4;
|
||||
int i;
|
||||
|
||||
tab = table_create(2, 2 + page_size * pages);
|
||||
if (!tab) {
|
||||
fprintf(stderr, "ERROR: cannot alocate table\n");
|
||||
return;
|
||||
}
|
||||
tab->hrows = 2;
|
||||
table_printf(tab, 0, 0, ">Id");
|
||||
table_printf(tab, 1, 0, ">Name");
|
||||
table_printf(tab, 0, 1, "*-");
|
||||
table_printf(tab, 1, 1, "*-");
|
||||
|
||||
for (i = tab->hrows; i < tab->nrows; i++) {
|
||||
table_printf(tab, 0, i, ">%d", 10 * (i - tab->hrows + 1));
|
||||
table_printf(tab, 1, i, "<Text %d", 100 * i);
|
||||
}
|
||||
|
||||
puts("start");
|
||||
for (i = 0; i < pages; i++) {
|
||||
unsigned int start = tab->hrows + i * page_size;
|
||||
|
||||
table_dump_header(tab);
|
||||
table_dump_range(tab, start, start + page_size - 1);
|
||||
puts("paginator");
|
||||
}
|
||||
puts("end");
|
||||
|
||||
table_free(tab);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int testno;
|
||||
static void (*tests[])() = {
|
||||
test_simple_create_free,
|
||||
test_simple_header,
|
||||
test_simple_paginate,
|
||||
};
|
||||
|
||||
/* Without arguments, print the number of tests available */
|
||||
if (argc == 1) {
|
||||
printf("%zu\n", ARRAY_SIZE(tests));
|
||||
return 0;
|
||||
}
|
||||
testno = atoi(argv[1]);
|
||||
testno--;
|
||||
|
||||
if (testno < 0 || testno >= ARRAY_SIZE(tests)) {
|
||||
fprintf(stderr, "ERROR: test number %d is out of range (max %zu)\n",
|
||||
testno + 1, ARRAY_SIZE(tests));
|
||||
return 1;
|
||||
}
|
||||
tests[testno]();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue