Commit 61f58ff9 authored by David Gibson's avatar David Gibson

Merge Makefile rewrite into master

# Conflicts:
#	.travis.yml
#	Makefile
#	Makefile-ccan
parents 68c74ffd 9dbf8b3f
......@@ -8,7 +8,11 @@ compiler:
addons:
apt:
packages:
- libjudy-dev libvorbis-dev libportaudio-dev libtalloc-dev
- libjudy-dev
- libvorbis-dev
- libportaudio-dev
- libtalloc-dev
script:
- make -j2 -k check quiet=1
- make -j2 -k quiet=1
- make -k check quiet=1
......@@ -11,6 +11,7 @@ WARN_CFLAGS := -Wall -Wstrict-prototypes -Wold-style-definition -Wundef \
-Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wwrite-strings
DEP_CFLAGS = -MMD -MP -MF$(@:%=%.d) -MT$@
CCAN_CFLAGS := -g3 -ggdb $(WARN_CFLAGS) -DCCAN_STR_DEBUG=1 -I. $(CFLAGS)
CFLAGS_FORCE_C_SOURCE := -x c
# Anything with an _info file is a module ...
INFO_SRCS := $(wildcard ccan/*/_info ccan/*/*/_info)
......@@ -32,7 +33,7 @@ DEPS := $(OBJS:%=%.d)
# _info files are compiled into executables and don't need dependencies
%info : %_info config.h
$(PRE)$(CC) $(CCAN_CFLAGS) -I. -o $@ -x c $<
$(PRE)$(CC) $(CCAN_CFLAGS) -I. -o $@ $(CFLAGS_FORCE_C_SOURCE) $<
# config.h is built by configurator which has no ccan dependencies
CONFIGURATOR := tools/configurator/configurator
......
# AppVeyor CI Configuration
#
# Current build status can be viewed at
# https://ci.appveyor.com/project/dgibson/ccan
#
# To build test a fork of this repository using AppVeyor:
# 1. Visit appveyor.com and create a free account.
# 2. On the Projects tab, select "New Project" then the project hosting site.
# 3. Grant OAuth permissions to your project git host.
# 4. Select the repository for your project fork.
# 5. Review build results and push updates until the desired result is reached.
version: 0.0.{build}
platform:
- x86
- amd64
build_script:
# Reset %PATH% to avoid msys/cygwin DLL conflicts which cause
# *** fatal error - cygheap base mismatch detected
- set PATH=C:\Windows\System32;C:\Windows;C:\Windows\System32\Wbem;C:\msys64\usr\bin
# Set environment variables for chosen compiler
- "\"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat\" %Platform%"
# Ensure config.h can be generated.
# Note: Dash options avoid POSIX path conversion by msys
- "make config.h CC=cl CCAN_CFLAGS=\"-nologo -Zi -FS -W4 -wd4200 -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS\" CFLAGS_FORCE_C_SOURCE=-TC OUTPUT_OPTION=-Fo:$@ DEPGEN= LD=link SHELL=bash"
# FIXME: Work in progress. Disabled due to unfixed compile errors.
# FIXME: -j%NUMBER_OF_PROCESSORS% won't work without DEPGEN for config.h
# It may be possible to generate .d from cl using /showIncludes
# See https://stackoverflow.com/q/37685069
#- "make tools CC=cl CCAN_CFLAGS=\"-nologo -Zi -FS -W4 -wd4200 -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS\" CFLAGS_FORCE_C_SOURCE=-TC OUTPUT_OPTION=-Fo:$@ DEPGEN= LD=link SHELL=bash"
#- "make -k CC=cl CCAN_CFLAGS=\"-nologo -Zi -FS -W4 -wd4200 -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS\" CFLAGS_FORCE_C_SOURCE=-TC OUTPUT_OPTION=-Fo:$@ DEPGEN= LD=link SHELL=bash"
test_script:
# FIXME: Work in progress. Disabled due to unfixed compile errors.
#- "make -k check CC=cl CCAN_CFLAGS=\"-nologo -Zi -FS -W4 -wd4200 -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS\" CFLAGS_FORCE_C_SOURCE=-TC OUTPUT_OPTION=-Fo:$@ DEPGEN= LD=link SHELL=bash"
......@@ -165,6 +165,12 @@ struct aga_node {
bool complete;
struct lpq_link pqlink;
} dijkstra;
struct {
aga_icost_t distance;
struct aga_node *prev;
const void *prevedge;
struct aga_node *list;
} bellman_ford;
} u;
};
......@@ -177,6 +183,11 @@ struct aga_graph {
aga_edge_info_fn edge_info;
union {
LPQ(struct aga_node, u.dijkstra.pqlink) dijkstra;
struct {
struct aga_node *nodelist;
int nnodes;
int npasses;
} bellman_ford;
} state;
};
......@@ -347,7 +358,7 @@ struct aga_node *aga_bfs_explore(struct aga_graph *g, struct aga_node *n);
*
* Performs a breadth first search. The block following this macro is
* executed with @_n set first to @_start, then to each node reachable
* from @_start in depth first search order.
* from @_start in breadth-first search order.
*
* aga_bfs_start() must be called before this macro is used.
*/
......@@ -416,15 +427,74 @@ bool aga_dijkstra_path(struct aga_graph *g, struct aga_node *dest,
struct aga_node **prev, const void **prevedge);
/**
* aga_dijkstra_all_paths - Find shortest paths to all reachable nodes
* aga_dijkstra_complete - Find shortest paths to all reachable nodes
* @g: graph
*
* Finds shortest paths from the source node (specified in
* aga_dijkstra_start()) to all other reachable nodes in @g. No
* results are returned directly, but between calling
* aga_dijkstra_all_paths() and aga_finish, aga_dijkstra_path() is
* aga_dijkstra_all_paths() and aga_finish(), aga_dijkstra_path() is
* guaranteed to complete in O(1) time for all destinations.
*/
void aga_dijkstra_all_paths(struct aga_graph *g);
void aga_dijkstra_complete(struct aga_graph *g);
/*
* Bellman-Ford algorithm
*/
/**
* aga_bellman_ford_start - Start Bellman-Ford algorithm
* @g: graph
* @source: source node
*
* Start's the Bellman-Ford algorithm on @g to find shortest paths
* from node @source, to other nodes in @g.
*/
int aga_bellman_ford_start(struct aga_graph *g, struct aga_node *source);
/**
* aga_bellman_ford_path - Find the shortest path to a node
* @g: graph
* @dest: destination node
* @prev: Second last node in the path *output)
* @prevedge: Last edge in the path
*
* Finds the shortest path from the source node (specified in
* aga_bellman_ford_start() to @dest using Bellman_Ford's algorithm.
*
* If no path exists, return false.
*
* If a path does exist, returns true. Additionally if @total_cost is
* non-NULL, store the total cost of the path in *@total_cost, if
* @prev is non-NULL, store the node in the path immediately before
* @dest in *@prev and if @prevedge is non-NULL stores the edge which
* leads from *@prev to @dest in *@prevedge.
*
* If @dest is the same as source, 0 will be stored in @cost, and NULL
* will be stored in *@prev and *@prevedge.
*
* The full path from source to @dest can be determined by repeatedly
* calling aga_bellman_ford_path() on *@prev.
*
* NOTE: Bellman_Ford's algorithm will not work correctly on a graph
* which contains a cycle with (total) negative cost. If aga detects
* this case, it will set aga_error() to AGA_ERR_NEGATIVE_COST.
*/
bool aga_bellman_ford_path(struct aga_graph *g, struct aga_node *dest,
aga_icost_t *total_cost,
struct aga_node **prev, const void **prevedge);
/**
* aga_bellman_ford_complete - Run Bellman-Ford algorithm to completion
* @g: graph
*
* Finds shortest paths from the source node (specified in
* aga_bellman_ford_start()) to all other reachable nodes in @g. No
* results are returned directly, but between calling
* aga_bellman_ford_complete() and aga_finish(),
* aga_bellman_ford_path() is guaranteed to complete in O(1) time for
* all destinations.
*/
void aga_bellman_ford_complete(struct aga_graph *g);
#endif /* CCAN_AGA_H */
/* Licensed under LGPLv2+ - see LICENSE file for details */
#include "config.h"
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <ccan/build_assert/build_assert.h>
#include <ccan/check_type/check_type.h>
#include <ccan/order/order.h>
#include <ccan/aga/aga.h>
#include "private.h"
/*
* The Bellman-Ford algorithm
*/
static bool candidate_path(struct aga_graph *g, struct aga_node *node,
aga_icost_t distance,
struct aga_node *prev, const void *prevedge)
{
if (aga_update_node(g, node)) {
/* New node, treat as having infinite distance */
node->u.bellman_ford.distance = distance;
node->u.bellman_ford.prev = prev;
node->u.bellman_ford.prevedge = prevedge;
node->u.bellman_ford.list = g->state.bellman_ford.nodelist;
g->state.bellman_ford.nodelist = node;
g->state.bellman_ford.nnodes++;
return true;
} else if (distance < node->u.bellman_ford.distance) {
node->u.bellman_ford.distance = distance;
node->u.bellman_ford.prev = prev;
node->u.bellman_ford.prevedge = prevedge;
}
return false;
}
int aga_bellman_ford_start(struct aga_graph *g, struct aga_node *source)
{
int rc;
/* Make sure we're actually using the right ordering for
* aga_icost_t */
BUILD_ASSERT(check_types_match(long, aga_icost_t) == 0);
rc = aga_start(g);
if (rc < 0)
return rc;
g->state.bellman_ford.nodelist = NULL;
g->state.bellman_ford.nnodes = 0;
g->state.bellman_ford.npasses = 0;
candidate_path(g, source, 0, NULL, NULL);
return 0;
}
static bool aga_bellman_ford_step(struct aga_graph *g)
{
struct aga_node *n;
const void *e;
struct aga_edge_info ei;
int err;
bool newnode = false;
if (!aga_check_state(g))
return false;
for (n = g->state.bellman_ford.nodelist;
n; n = n->u.bellman_ford.list) {
aga_for_each_edge_info(e, ei, err, g, n) {
aga_icost_t dist = n->u.bellman_ford.distance
+ ei.icost;
newnode = newnode || candidate_path(g, ei.to, dist, n, e);
}
if (err) {
aga_fail(g, err);
return false;
}
}
g->state.bellman_ford.npasses++;
return newnode || (g->state.bellman_ford.npasses
< g->state.bellman_ford.nnodes);
}
void aga_bellman_ford_complete(struct aga_graph *g)
{
struct aga_node *n;
const void *e;
struct aga_edge_info ei;
int err;
if (!aga_check_state(g))
return;
while (aga_bellman_ford_step(g))
;
/* Check for negative cycles */
for (n = g->state.bellman_ford.nodelist;
n; n = n->u.bellman_ford.list) {
aga_for_each_edge_info(e, ei, err, g, n) {
if ((n->u.bellman_ford.distance + ei.icost)
< ei.to->u.bellman_ford.distance) {
aga_fail(g, AGA_ERR_NEGATIVE_COST);
return;
}
}
if (err) {
aga_fail(g, err);
return;
}
}
}
bool aga_bellman_ford_path(struct aga_graph *g, struct aga_node *node,
aga_icost_t *total_cost,
struct aga_node **prev, const void **prevedge)
{
aga_bellman_ford_complete(g);
if (!aga_check_state(g))
return false;
if (aga_node_needs_update(g, node))
return false;
if (total_cost)
*total_cost = node->u.bellman_ford.distance;
if (prev)
*prev = node->u.bellman_ford.prev;
if (prevedge)
*prevedge = node->u.bellman_ford.prevedge;
return true;
}
......@@ -114,7 +114,7 @@ bool aga_dijkstra_path(struct aga_graph *g, struct aga_node *node,
return true;
}
void aga_dijkstra_all_paths(struct aga_graph *g)
void aga_dijkstra_complete(struct aga_graph *g)
{
if (!aga_check_state(g))
return;
......
......@@ -63,8 +63,9 @@ int main(void)
struct traversal1_graph t1g;
struct shortcut1_graph s1g;
struct shortcut2_graph s2g;
struct negacycle_graph ng;
plan_tests(2 + 7 + 35 + 30 + 30 + 42 + 9 + 30 + 9 + 9);
plan_tests(2 + 7 + 35 + 30 + 30 + 42 + 9 + 30 + 9 + 9 + 9);
trivial_graph_init(&tg);
test_adjacency("trivial", &tg.sg, trivial_adjacency);
......@@ -99,5 +100,8 @@ int main(void)
shortcut2_graph_init(&s2g);
test_adjacency("shortcut2 graph", &s2g.sg, shortcut2_adjacency);
negacycle_graph_init(&ng);
test_adjacency("negacycle graph", &ng.sg, negacycle_adjacency);
return exit_status();
}
#include "config.h"
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
#include <ccan/tap/tap.h>
#include <ccan/array_size/array_size.h>
#include <ccan/aga/aga.h>
#include "simple-graph.h"
static void test_trivial(void)
{
struct trivial_graph tg;
aga_icost_t cost;
struct aga_node *node;
const void *edge;
trivial_graph_init(&tg);
ok1(aga_bellman_ford_start(&tg.sg.g, &tg.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&tg.sg.g, &tg.sg.nodes[1], &cost, &node, &edge));
ok1(cost == 0);
ok1(node == NULL);
ok1(edge == NULL);
aga_finish(&tg.sg.g);
}
static void test_parallel(void)
{
struct parallel_graph pg;
aga_icost_t cost;
struct aga_node *node;
const void *edge;
parallel_graph_init(&pg, 3, 0);
ok1(aga_bellman_ford_start(&pg.sg.g, &pg.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[1], &cost, NULL, NULL));
ok1(cost == 0);
ok1(aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[2], &cost, &node, NULL));
ok1(cost == 2);
ok1(node == &pg.sg.nodes[1]);
aga_finish(&pg.sg.g);
ok1(aga_bellman_ford_start(&pg.sg.g, &pg.sg.nodes[2]) == 0);
ok1(aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[2], &cost, NULL, NULL));
ok1(cost == 0);
ok1(!aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[1], NULL, NULL, NULL));
aga_finish(&pg.sg.g);
parallel_graph_init(&pg, 3, 2);
ok1(aga_bellman_ford_start(&pg.sg.g, &pg.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[2], &cost, &node, &edge));
ok1(cost == 1);
ok1(node == &pg.sg.nodes[1]);
ok1(ptr2int(edge) == 2);
aga_finish(&pg.sg.g);
}
#define FULL_LEN 4
static void test_full(void)
{
struct full_graph fg;
int i, j;
full_graph_init(&fg, FULL_LEN);
for (i = 1; i <= FULL_LEN; i++) {
ok1(aga_bellman_ford_start(&fg.sg.g, &fg.sg.nodes[i]) == 0);
for (j = 1; j <= FULL_LEN; j++) {
aga_icost_t cost;
struct aga_node *node;
const void *edge;
ok1(aga_bellman_ford_path(&fg.sg.g, &fg.sg.nodes[j],
&cost, &node, &edge));
if (i == j) {
ok1(cost == 0);
ok1(node == NULL);
ok1(edge == NULL);
} else {
ok1(cost == 1);
ok1(node == &fg.sg.nodes[i]);
ok1(edge == &fg.sg.nodes[j]);
}
}
aga_finish(&fg.sg.g);
}
}
#define CHAIN_LEN 8
static void test_chain(void)
{
struct chain_graph cg;
int i, j;
chain_graph_init(&cg, CHAIN_LEN);
for (i = 1; i <= CHAIN_LEN; i++) {
ok1(aga_bellman_ford_start(&cg.fg.sg.g, &cg.fg.sg.nodes[i]) == 0);
for (j = 1; j <= CHAIN_LEN; j++) {
aga_icost_t cost;
ok1(aga_bellman_ford_path(&cg.fg.sg.g, &cg.fg.sg.nodes[j],
&cost, NULL, NULL));
ok1(cost == labs(i - j));
}
aga_finish(&cg.fg.sg.g);
}
}
static void test_error(void)
{
struct error_graph eg;
aga_icost_t cost;
error_graph_init(&eg);
ok1(aga_bellman_ford_start(&eg.sg.g, &eg.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[1], &cost, NULL, NULL));
ok1(cost == 0);
ok1(aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[2], &cost, NULL, NULL));
ok1(cost == 1);
ok1(!aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[3], &cost, NULL, NULL));
ok1(!aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[4], &cost, NULL, NULL));
aga_finish(&eg.sg.g);
ok1(aga_bellman_ford_start(&eg.sg.g, &eg.sg.nodes[3]) == 0);
aga_bellman_ford_complete(&eg.sg.g);
ok1(!aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[4], &cost, NULL, NULL));
ok1(aga_error(&eg.sg.g) == -1);
aga_finish(&eg.sg.g);
}
static void test_traversal1(void)
{
struct traversal1_graph t1g;
aga_icost_t cost;
/* This is mostly about testing we correctly handle
* non-reachable nodes */
traversal1_graph_init(&t1g);
ok1(aga_bellman_ford_start(&t1g.sg.g, &t1g.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[1],
&cost, NULL, NULL));
ok1(cost == 0);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[2],
&cost, NULL, NULL));
ok1(cost == 1);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[3],
&cost, NULL, NULL));
ok1(cost == 1);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[4],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[5],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[6],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[7],
NULL, NULL, NULL));
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[8],
NULL, NULL, NULL));
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[9],
NULL, NULL, NULL));
aga_finish(&t1g.sg.g);
ok1(aga_bellman_ford_start(&t1g.sg.g, &t1g.sg.nodes[9]) == 0);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[9],
&cost, NULL, NULL));
ok1(cost == 0);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[8],
&cost, NULL, NULL));
ok1(cost == 1);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[7],
&cost, NULL, NULL));
ok1(cost == 1);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[6],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[5],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[4],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[3],
NULL, NULL, NULL));
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[2],
NULL, NULL, NULL));
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[1],
NULL, NULL, NULL));
aga_finish(&t1g.sg.g);
}
static void test_shortcut1(void)
{
struct shortcut1_graph s1g;
aga_icost_t cost;
struct aga_node *node;
shortcut1_graph_init(&s1g);
ok1(aga_bellman_ford_start(&s1g.sg.g, &s1g.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&s1g.sg.g, &s1g.sg.nodes[3],
&cost, &node, NULL));
ok1(cost == 2);
ok1(node == &s1g.sg.nodes[2]);
ok1(aga_bellman_ford_path(&s1g.sg.g, &s1g.sg.nodes[2],
&cost, &node, NULL));
ok1(cost == 1);
ok1(node == &s1g.sg.nodes[1]);
aga_finish(&s1g.sg.g);
}
static void test_shortcut2(void)
{
struct shortcut2_graph s2g;
aga_icost_t cost;
struct aga_node *node;
shortcut2_graph_init(&s2g);
ok1(aga_bellman_ford_start(&s2g.sg.g, &s2g.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&s2g.sg.g, &s2g.sg.nodes[3],
&cost, &node, NULL));
ok1(cost == 1);
ok1(node == &s2g.sg.nodes[2]);
ok1(aga_bellman_ford_path(&s2g.sg.g, &s2g.sg.nodes[2],
&cost, &node, NULL));
ok1(cost == 2);
ok1(node == &s2g.sg.nodes[1]);
aga_finish(&s2g.sg.g);
}
static void test_negacycle(void)
{
struct negacycle_graph ng;
negacycle_graph_init(&ng);
ok1(aga_bellman_ford_start(&ng.sg.g, &ng.sg.nodes[1]) == 0);
aga_bellman_ford_complete(&ng.sg.g);
ok1(aga_error(&ng.sg.g) == AGA_ERR_NEGATIVE_COST);
aga_finish(&ng.sg.g);
}
int main(void)
{
plan_tests(5 + 15
+ FULL_LEN * (1 + FULL_LEN * 4)
+ CHAIN_LEN * (1 + CHAIN_LEN * 2)
+ 10 + 32 + 7 + 7 + 2);
test_trivial();
test_parallel();
test_full();
test_chain();
test_error();
test_traversal1();
test_shortcut1();
test_shortcut2();
test_negacycle();
return exit_status();
}
......@@ -42,9 +42,10 @@ int main(void)
struct grid_graph gg1, gg2;
struct error_graph eg;
struct traversal1_graph t1g;
struct negacycle_graph ng;
struct aga_node *node;
plan_tests(2 * 13 + 10 + 10);
plan_tests(2 * 13 + 10 + 10 + 6);
trivial_graph_init(&tg);
test_bfs(&tg.sg, 1, 1);
......@@ -100,5 +101,10 @@ int main(void)
test_bfs_partial(&t1g.sg, 1, 1, 2, 3);
aga_finish(&t1g.sg.g);
negacycle_graph_init(&ng);
test_bfs(&ng.sg, 1, 1, 2, 3);
test_bfs(&ng.sg, 2, 2, 3, 1);
test_bfs(&ng.sg, 3, 3, 1, 2);
return exit_status();
}
......@@ -42,9 +42,10 @@ int main(void)
struct grid_graph gg1, gg2;
struct error_graph eg;
struct traversal1_graph t1g;
struct negacycle_graph ng;
struct aga_node *node;
plan_tests(2 * 13 + 10 + 10);
plan_tests(2 * 13 + 10 + 10 + 6);
trivial_graph_init(&tg);
test_dfs(&tg.sg, 1, 1);
......@@ -100,5 +101,10 @@ int main(void)
test_dfs_partial(&t1g.sg, 1, 1, 2, 3);
aga_finish(&t1g.sg.g);
negacycle_graph_init(&ng);
test_dfs(&ng.sg, 1, 1, 2, 3);
test_dfs(&ng.sg, 2, 2, 3, 1);
test_dfs(&ng.sg, 3, 3, 1, 2);
return exit_status();
}
......@@ -241,17 +241,29 @@ static void test_shortcut2(void)
shortcut2_graph_init(&s2g);
ok1(aga_dijkstra_start(&s2g.sg.g, &s2g.sg.nodes[1]) == 0);
aga_dijkstra_all_paths(&s2g.sg.g);
aga_dijkstra_complete(&s2g.sg.g);
ok1(aga_error(&s2g.sg.g) == AGA_ERR_NEGATIVE_COST);
aga_finish(&s2g.sg.g);
}
static void test_negacycle(void)
{
struct negacycle_graph ng;
negacycle_graph_init(&ng);
ok1(aga_dijkstra_start(&ng.sg.g, &ng.sg.nodes[1]) == 0);
aga_dijkstra_complete(&ng.sg.g);
ok1(aga_error(&ng.sg.g) == AGA_ERR_NEGATIVE_COST);
aga_finish(&ng.sg.g);
}
int main(void)
{
plan_tests(7 + 20
+ FULL_LEN * (1 + FULL_LEN*4)
+ CHAIN_LEN * (1 + CHAIN_LEN*2)
+ 12 + 32 + 7 + 2);
+ 12 + 32 + 7 + 2 + 2);
test_trivial();
test_parallel();
......@@ -261,6 +273,7 @@ int main(void)
test_traversal1();
test_shortcut1();
test_shortcut2();
test_negacycle();
return exit_status();
}
#include "config.h"
#include <assert.h>
#include <ccan/container_of/container_of.h>
#include <ccan/ptrint/ptrint.h>
#include <ccan/aga/aga.h>
#include "simple-graph.h"
static ptrint_t *negacycle_first_edge(const struct aga_graph *g,
const struct aga_node *n)
{
return int2ptr(1);
}
static ptrint_t *negacycle_next_edge(const struct aga_graph *g,
const struct aga_node *n,
ptrint_t *e)
{
assert(ptr2int(e) == 1);
return NULL;
}
static int negacycle_edge_info(const struct aga_graph *g,
const struct aga_node *n,
ptrint_t *e, struct aga_edge_info *ei)
{
struct negacycle_graph *ng = container_of(g, struct negacycle_graph,
sg.g);
int ni = n - ng->sg.nodes;
assert(ptr2int(e) == 1);
ei->to = &ng->sg.nodes[(ni % 3) + 1];
if (ni == 3)
ei->icost = -3;
return 0;
}
void negacycle_graph_init(struct negacycle_graph *ng)
{
simple_graph_init(&ng->sg, negacycle_first_edge,
negacycle_next_edge,
negacycle_edge_info);
}
......@@ -256,4 +256,23 @@ static const struct adjacency_list shortcut2_adjacency[] = {
{},
};
/* Negacycle graph
*
* A <---- (-3) ----- C
* \ ^
* (1)-> B -- (1)-/
*
* Graph with a negative length cycle, and so lacking well-defined shortest paths.
*/
struct negacycle_graph {
struct simple_graph sg;
};
void negacycle_graph_init(struct negacycle_graph *ng);
static const struct adjacency_list negacycle_adjacency[] = {
{1, {2}},
{2, {3}},
{3, {1}},
{},
};
#endif /* _TEST_GRAPHS_H */
......@@ -286,8 +286,53 @@ bool agar_dijkstra_path(struct agar_state *sr, const void *destr,
return true;
}
void agar_dijkstra_all_paths(struct agar_state *sr)
void agar_dijkstra_complete(struct agar_state *sr)
{
aga_dijkstra_all_paths(&sr->g);
aga_dijkstra_complete(&sr->g);
}
/*
* Bellman-Ford algorithm
*/
struct agar_state *agar_bellman_ford_new(void *ctx, struct agar_graph *gr,
const void *nr)
{
struct agar_state *sr = agar_new(ctx, gr);
if (aga_bellman_ford_start(&sr->g, nr_to_n(sr, nr)) < 0) {
tal_free(sr);
return NULL;
}
return sr;
}
bool agar_bellman_ford_path(struct agar_state *sr, const void *destr,
aga_icost_t *total_cost,
const void **prevr, const void **prevedge)
{
struct aga_node *dest = nr_to_n(sr, destr);
struct aga_node *prev;
if (!aga_bellman_ford_path(&sr->g, dest, total_cost, &prev, prevedge))
return false;
/*
* When destr is the same as the source node, there obviously
* isn't a previous node or edge. In that case aga sets them
* to NULL. But for agar, NULL could be a valid node
* references (particularly if using ptrint). So we don't
* have much choice here but to leave *prevr as undefined when
* destr is the source node. */
if (prevr && prev)
*prevr = n_to_nr(sr, prev);
return true;
}
void agar_bellman_ford_complete(struct agar_state *sr)
{
aga_bellman_ford_complete(&sr->g);
}
......@@ -84,6 +84,18 @@ bool agar_dijkstra_step(struct agar_state *sr, const void **nextr);
bool agar_dijkstra_path(struct agar_state *sr, const void *destr,
aga_icost_t *total_cost,
const void **prevr, const void **prevedge);
void agar_dijkstra_all_paths(struct agar_state *sr);
void agar_dijkstra_complete(struct agar_state *sr);
/*
* Bellman-Ford algorithm
*/
struct agar_state *agar_bellman_ford_new(void *ctx, struct agar_graph *gr,
const void *nr);
bool agar_bellman_ford_path(struct agar_state *sr, const void *destr,
aga_icost_t *total_cost,
const void **prevr, const void **prevedge);
void agar_bellman_ford_complete(struct agar_state *sr);
#endif /* CCAN_AGAR_H */
#include "config.h"
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
#include <ccan/tap/tap.h>
#include <ccan/tal/tal.h>
#include <ccan/array_size/array_size.h>
#include <ccan/agar/agar.h>
#include "simple-graphr.h"
static void test_trivial(void)
{
struct agar_state *sr;
aga_icost_t cost;
ok1(sr = agar_bellman_ford_new(NULL, &trivial_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(1), &cost, NULL, NULL));
ok1(cost == 0);
tal_free(sr);
}
static void test_parallel(void)
{
struct parallel_graphr pgr;
struct agar_state *sr;
aga_icost_t cost;
const void *node, *edge;
parallel_graphr_init(&pgr, 3, 0);
ok1(sr = agar_bellman_ford_new(NULL, &pgr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(1), &cost, NULL, NULL));
ok1(cost == 0);
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, &node, NULL));
ok1(cost == 2);
ok1(node == int2ptr(1));
tal_free(sr);
ok1(sr = agar_bellman_ford_new(NULL, &pgr.gr, int2ptr(2)));
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, NULL, NULL));
ok1(cost == 0);
ok1(!agar_bellman_ford_path(sr, int2ptr(1), NULL, NULL, NULL));
tal_free(sr);
parallel_graphr_init(&pgr, 3, 2);
ok1(sr = agar_bellman_ford_new(NULL, &pgr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, &node, &edge));
ok1(cost == 1);
ok1(ptr2int(node) == 1);
ok1(ptr2int(edge) == 2);
tal_free(sr);
}
#define FULL_LEN 4
static void test_full(void)
{
struct full_graphr fgr;
int i, j;
full_graphr_init(&fgr, FULL_LEN);
for (i = 1; i <= FULL_LEN; i++) {
struct agar_state *sr;
ok1(sr = agar_bellman_ford_new(NULL, &fgr.gr, int2ptr(i)));
for (j = 1; j <= FULL_LEN; j++) {
aga_icost_t cost;
const void *node, *edge;
ok1(agar_bellman_ford_path(sr, int2ptr(j),
&cost, &node, &edge));
if (i == j) {
ok1(cost == 0);
} else {
ok1(cost == 1);
ok1(node == int2ptr(i));
ok1(edge == int2ptr(j));
}
}
tal_free(sr);
}
}
#define CHAIN_LEN 8
static void test_chain(void)
{
struct chain_graphr cgr;
int i, j;
chain_graphr_init(&cgr, CHAIN_LEN);
for (i = 1; i <= CHAIN_LEN; i++) {
struct agar_state *sr;
ok1(sr = agar_bellman_ford_new(NULL, &cgr.fgr.gr, int2ptr(i)));
for (j = 1; j <= CHAIN_LEN; j++) {
aga_icost_t cost;
ok1(agar_bellman_ford_path(sr, int2ptr(j),
&cost, NULL, NULL));
ok1(cost == labs(i - j));
}
tal_free(sr);
}
}
static void test_error(void)
{
struct agar_state *sr;
aga_icost_t cost;
ok1(sr = agar_bellman_ford_new(NULL, &error_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(1), &cost, NULL, NULL));
ok1(cost == 0);
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, NULL, NULL));
ok1(cost == 1);
ok1(!agar_bellman_ford_path(sr, int2ptr(3), &cost, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(4), &cost, NULL, NULL));
tal_free(sr);
ok1(sr = agar_bellman_ford_new(NULL, &error_graphr.gr, int2ptr(3)));
agar_bellman_ford_complete(sr);
ok1(!agar_bellman_ford_path(sr, int2ptr(4), &cost, NULL, NULL));
ok1(agar_error(sr) == -1);
tal_free(sr);
}
static void test_traversal1(void)
{
struct agar_state *sr;
aga_icost_t cost;
/* This is mostly about testing we correctly handle
* non-reachable nodes */
ok1(sr = agar_bellman_ford_new(NULL, &traversal1_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(1),
&cost, NULL, NULL));
ok1(cost == 0);
ok1(agar_bellman_ford_path(sr, int2ptr(2),
&cost, NULL, NULL));
ok1(cost == 1);
ok1(agar_bellman_ford_path(sr, int2ptr(3),
&cost, NULL, NULL));
ok1(cost == 1);
ok1(agar_bellman_ford_path(sr, int2ptr(4),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(agar_bellman_ford_path(sr, int2ptr(5),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(agar_bellman_ford_path(sr, int2ptr(6),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(!agar_bellman_ford_path(sr, int2ptr(7),
NULL, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(8),
NULL, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(9),
NULL, NULL, NULL));
tal_free(sr);
ok1(sr = agar_bellman_ford_new(NULL, &traversal1_graphr.gr, int2ptr(9)));
ok1(agar_bellman_ford_path(sr, int2ptr(9),
&cost, NULL, NULL));
ok1(cost == 0);
ok1(agar_bellman_ford_path(sr, int2ptr(8),
&cost, NULL, NULL));
ok1(cost == 1);
ok1(agar_bellman_ford_path(sr, int2ptr(7),
&cost, NULL, NULL));
ok1(cost == 1);
ok1(agar_bellman_ford_path(sr, int2ptr(6),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(agar_bellman_ford_path(sr, int2ptr(5),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(agar_bellman_ford_path(sr, int2ptr(4),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(!agar_bellman_ford_path(sr, int2ptr(3),
NULL, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(2),
NULL, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(1),
NULL, NULL, NULL));
tal_free(sr);
}
static void test_shortcut1(void)
{
struct agar_state *sr;
aga_icost_t cost;
const void *node;
ok1(sr = agar_bellman_ford_new(NULL, &shortcut1_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(3), &cost, &node, NULL));
ok1(cost == 2);
ok1(node == int2ptr(2));
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, &node, NULL));
ok1(cost == 1);
ok1(node == int2ptr(1));
tal_free(sr);
}
static void test_shortcut2(void)
{
struct agar_state *sr;
aga_icost_t cost;
const void *node;
ok1(sr = agar_bellman_ford_new(NULL, &shortcut2_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(3), &cost, &node, NULL));
ok1(cost == 1);
ok1(node == int2ptr(2));
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, &node, NULL));
ok1(cost == 2);
ok1(node == int2ptr(1));
tal_free(sr);
}
static void test_negacycle(void)
{
struct agar_state *sr;
ok1(sr = agar_bellman_ford_new(NULL, &negacycle_graphr.gr, int2ptr(1)));
agar_bellman_ford_complete(sr);
ok1(agar_error(sr) == AGA_ERR_NEGATIVE_COST);
tal_free(sr);
}
int main(void)
{
plan_tests(3 + 15
+ FULL_LEN * (FULL_LEN*4 - 1)
+ CHAIN_LEN * (1 + CHAIN_LEN*2)
+ 10 + 32 + 7 + 7 + 2);
test_trivial();
test_parallel();
test_full();
test_chain();
test_error();
test_traversal1();
test_shortcut1();
test_shortcut2();
test_negacycle();
return exit_status();
}
......@@ -45,7 +45,7 @@ int main(void)
struct agar_state *sr;
const void *nr;
plan_tests(2 * 13 + 12 + 10);
plan_tests(2 * 13 + 12 + 10 + 6);
test_bfs(&trivial_graphr.gr, 1, 1);
......@@ -97,5 +97,9 @@ int main(void)
test_bfs_partial(sr, 1, 1, 2, 3);
tal_free(sr);
test_bfs(&negacycle_graphr.gr, 1, 1, 2, 3);
test_bfs(&negacycle_graphr.gr, 2, 2, 3, 1);
test_bfs(&negacycle_graphr.gr, 3, 3, 1, 2);
return exit_status();
}
......@@ -45,7 +45,7 @@ int main(void)
struct agar_state *sr;
const void *nr;
plan_tests(2 * 13 + 12 + 10);
plan_tests(2 * 13 + 12 + 10 + 6);
test_dfs(&trivial_graphr.gr, 1, 1);
......@@ -97,5 +97,9 @@ int main(void)
test_dfs_partial(sr, 1, 1, 2, 3);
tal_free(sr);
test_dfs(&negacycle_graphr.gr, 1, 1, 2, 3);
test_dfs(&negacycle_graphr.gr, 2, 2, 3, 1);
test_dfs(&negacycle_graphr.gr, 3, 3, 1, 2);
return exit_status();
}
......@@ -231,7 +231,17 @@ static void test_shortcut2(void)
struct agar_state *sr;
ok1(sr = agar_dijkstra_new(NULL, &shortcut2_graphr.gr, int2ptr(1)));
agar_dijkstra_all_paths(sr);
agar_dijkstra_complete(sr);
ok1(agar_error(sr) == AGA_ERR_NEGATIVE_COST);
tal_free(sr);
}
static void test_negacycle(void)
{
struct agar_state *sr;
ok1(sr = agar_dijkstra_new(NULL, &negacycle_graphr.gr, int2ptr(1)));
agar_dijkstra_complete(sr);
ok1(agar_error(sr) == AGA_ERR_NEGATIVE_COST);
tal_free(sr);
}
......@@ -241,7 +251,7 @@ int main(void)
plan_tests(6 + 23
+ FULL_LEN * (FULL_LEN*4 - 1)
+ CHAIN_LEN * (1 + CHAIN_LEN*2)
+ 12 + 32 + 7 + 2);
+ 12 + 32 + 7 + 2 + 2);
test_trivial();
test_parallel();
......@@ -251,6 +261,7 @@ int main(void)
test_traversal1();
test_shortcut1();
test_shortcut2();
test_negacycle();
return exit_status();
}
#include "config.h"
#include <assert.h>
#include <ccan/container_of/container_of.h>
#include <ccan/ptrint/ptrint.h>
#include <ccan/agar/agar.h>
#include "simple-graphr.h"
static const void *negacycle_first_edge_r(const struct agar_graph *gr,
const void *nr)
{
return int2ptr(1);
}
static const void *negacycle_next_edge_r(const struct agar_graph *gr,
const void *nr, const void *e)
{
assert(ptr2int(e) == 1);
return NULL;
}
static int negacycle_edge_info_r(const struct agar_graph *gr,
const void *nr, const void *e,
struct agar_edge_info *eir)
{
int ni = ptr2int(nr);
assert(ptr2int(e) == 1);
eir->to = int2ptr((ni % 3) + 1);
if (ni == 3)
eir->icost = -3;
return 0;
}
struct negacycle_graphr negacycle_graphr = {
AGAR_INIT_GRAPH(negacycle_first_edge_r,
negacycle_next_edge_r,
negacycle_edge_info_r),
};
......@@ -240,4 +240,23 @@ static const struct adjacency_listr shortcut2_adjacencyr[] = {
{},
};
/* Negacycle graph
*
* A <---- (-3) ----- C
* \ ^
* (1)-> B -- (1)-/
*
* Graph with a negative length cycle, and so lacking well-defined shortest paths.
*/
struct negacycle_graphr {
struct agar_graph gr;
};
extern struct negacycle_graphr negacycle_graphr;
static const struct adjacency_listr negacycle_adjacencyr[] = {
{1, {2}},
{2, {3}},
{3, {1}},
{},
};
#endif /* _SIMPLE_GRAPHR_H */
......@@ -21,7 +21,7 @@
*
* // Output contains "ALIGNOF(char) == 1"
* // Will also print out whether an onstack char array can hold a long.
* int main(int argc, char *argv[])
* int main(void)
* {
* char arr[sizeof(int)];
*
......
......@@ -24,7 +24,7 @@ struct lots_of_types
char c5;
};
int main(int argc, char *argv[])
int main(void)
{
struct lots_of_types lots_of_types, *lp = malloc(sizeof(*lp));
char c;
......
......@@ -18,7 +18,7 @@ int check_parameter(const struct foo *array)
#endif
}
int main(int argc, char *argv[])
int main(void)
{
return check_parameter(NULL);
}
......@@ -2,6 +2,8 @@
int main(int argc, char *argv[8])
{
(void)argc;
(void)argv;
char array[100];
#ifdef FAIL
return ARRAY_SIZE(argv) + ARRAY_SIZE(array);
......
......@@ -16,7 +16,7 @@ static int array2_size = ARRAY_SIZE(array2);
static int array3_size = ARRAY_SIZE(array3);
static int array4_size = ARRAY_SIZE(array4);
int main(int argc, char *argv[])
int main(void)
{
plan_tests(8);
ok1(array1_size == 1);
......
......@@ -31,7 +31,7 @@
* int main(int argc, char *argv[])
* {
* bool casefold = false;
* unsigned int i;
* int i;
*
* if (argc < 2) {
* fprintf(stderr, "Usage: %s [-i] <list>...\n"
......
#include <ccan/asort/asort.h>
#include <ccan/asort/asort.c>
static int cmp(char *const *a, char *const *b, int *flag)
static int cmp(char *const *a UNNEEDED, char *const *b UNNEEDED, int *flag UNNEEDED)
{
return 0;
}
......
......@@ -11,7 +11,7 @@ void *autodata_get_section(void *start, void *stop, size_t *nump)
return start;
}
void autodata_free(void *table)
void autodata_free(void *table UNNEEDED)
{
}
#else
......
#include <ccan/build_assert/build_assert.h>
int main(int argc, char *argv[])
int main(void)
{
#ifdef FAIL
return BUILD_ASSERT_OR_ZERO(1 == 0);
......
#include <ccan/build_assert/build_assert.h>
int main(int argc, char *argv[])
int main(void)
{
#ifdef FAIL
BUILD_ASSERT(1 == 0);
......
#include <ccan/build_assert/build_assert.h>
int main(int argc, char *argv[])
int main(void)
{
BUILD_ASSERT(1 == 1);
return 0;
......
#include <ccan/build_assert/build_assert.h>
#include <ccan/tap/tap.h>
int main(int argc, char *argv[])
int main(void)
{
plan_tests(1);
ok1(BUILD_ASSERT_OR_ZERO(1 == 1) == 0);
......
......@@ -24,6 +24,7 @@
* #include <ccan/cast/cast.h>
* #include <stdint.h>
* #include <stdio.h>
* #include <stdlib.h>
*
* // Find char @orig in @str, if @repl, replace them. Return number.
* static size_t find_chars(char *str, char orig, char repl)
......@@ -53,6 +54,9 @@
* {
* uint64_t hash;
*
* if (argc != 2) {
* fprintf(stderr, "Needs argument\n"); exit(1);
* }
* // find_chars wants a non-const string, but doesn't
* // need it if repl == 0.
* printf("%zu %c's in 'test string'\n",
......
......@@ -6,7 +6,7 @@ struct char_struct {
char c;
};
int main(int argc, char *argv[])
int main(void)
{
char *uc;
const
......
......@@ -6,7 +6,7 @@ struct char_struct {
char c;
};
int main(int argc, char *argv[])
int main(void)
{
char **uc;
const
......
......@@ -6,7 +6,7 @@ struct char_struct {
char c;
};
int main(int argc, char *argv[])
int main(void)
{
char ***uc;
const
......
#include <ccan/cast/cast.h>
#include <stdlib.h>
int main(int argc, char *argv[])
int main(void)
{
unsigned char *uc;
#ifdef FAIL
......
......@@ -6,7 +6,7 @@ struct char_struct {
char c;
};
int main(int argc, char *argv[])
int main(void)
{
unsigned char *uc;
#ifdef FAIL
......
#include <ccan/cast/cast.h>
#include <stdlib.h>
int main(int argc, char *argv[])
int main(void)
{
unsigned char *uc;
#ifdef FAIL
......
#include <ccan/cast/cast.h>
#include <stdlib.h>
int main(int argc, char *argv[])
int main(void)
{
char *c;
#ifdef FAIL
......
#include <ccan/cast/cast.h>
#include <stdlib.h>
int main(int argc, char *argv[])
int main(void)
{
char *c;
#ifdef FAIL
......
#include <ccan/cast/cast.h>
#include <stdlib.h>
int main(int argc, char *argv[])
int main(void)
{
long c;
#ifdef FAIL
......
......@@ -6,5 +6,6 @@ static char *p = cast_const(char *, (const char *)"hello");
int main(int argc, char *argv[])
{
(void)argc;
return p[0] == argv[0][0];
}
......@@ -29,7 +29,8 @@
* {
* char *code, *problems;
* struct cdump_definitions *defs;
* int i, j;
* int i;
* size_t j;
*
* // Read code from stdin.
* code = grab_file(NULL, NULL);
......
......@@ -213,7 +213,7 @@ static struct cdump_type *get_type(struct cdump_definitions *defs,
enum cdump_type_kind kind,
const char *name)
{
cdump_map_t *m;
cdump_map_t *m = (void *)0x1L; /* Shouldn't be used */
struct cdump_type *t;
switch (kind) {
......
......@@ -2,6 +2,8 @@
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
#ifdef FAIL
check_type(argc, char);
#endif
......
......@@ -2,6 +2,8 @@
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
#ifdef FAIL
#if HAVE_TYPEOF
check_type(argc, unsigned int);
......
......@@ -3,6 +3,7 @@
int main(int argc, char *argv[])
{
unsigned char x = argc;
(void)argv;
#ifdef FAIL
check_types_match(argc, x);
#endif
......
......@@ -5,6 +5,7 @@ int main(int argc, char *argv[])
{
int x = 0, y = 0;
(void)argv;
plan_tests(9);
ok1(check_type(argc, int) == 0);
......
......@@ -41,7 +41,7 @@
* va_end(ap);
* }
*
* int main(int argc, char *argv[])
* int main(int argc, char *argv[] UNNEEDED)
* {
* if (argc != 1) {
* logger(3, "Don't want %i arguments!\n", argc-1);
......
......@@ -2,9 +2,11 @@
static void PRINTF_FMT(2,3) my_printf(int x, const char *fmt, ...)
{
(void)x;
(void)fmt;
}
int main(int argc, char *argv[])
int main(void)
{
unsigned int i = 0;
......
......@@ -3,6 +3,8 @@
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
plan_tests(2);
ok1(!IS_COMPILE_CONSTANT(argc));
......
......@@ -26,17 +26,19 @@
* struct timer timer;
* };
*
* static void register_timer(struct timer *timer)
* {
* //...
* }
*
* static void my_timer_callback(struct timer *timer)
* {
* struct info *info = container_of(timer, struct info, timer);
* printf("my_stuff is %u\n", info->my_stuff);
* }
*
* static void register_timer(struct timer *timer)
* {
* (void)timer;
* (void)my_timer_callback;
* //...
* }
*
* int main(void)
* {
* struct info info = { .my_stuff = 1 };
......
......@@ -6,7 +6,7 @@ struct foo {
char b;
};
int main(int argc, char *argv[])
int main(void)
{
struct foo foo = { .a = 1, .b = 2 };
int *intp = &foo.a;
......
......@@ -6,7 +6,7 @@ struct foo {
char b;
};
int main(int argc, char *argv[])
int main(void)
{
struct foo foo = { .a = 1, .b = 2 }, *foop;
int *intp = &foo.a;
......
......@@ -6,7 +6,7 @@ struct foo {
char b;
};
int main(int argc, char *argv[])
int main(void)
{
struct foo foo = { .a = 1, .b = 2 }, *foop;
int *intp = &foo.a;
......
......@@ -6,7 +6,7 @@ struct foo {
char b;
};
int main(int argc, char *argv[])
int main(void)
{
struct foo foo = { .a = 1, .b = 2 };
int *intp = &foo.a;
......
......@@ -237,7 +237,7 @@ cputype_t cpuid_get_cpu_type(void)
uint32_t i;
get_cpuid(CPUID_VENDORID, &i, &u.bufu32[0], &u.bufu32[2], &u.bufu32[1]);
for (i = 0; i < sizeof(c_cpunames) / sizeof(c_cpunames); ++i) {
for (i = 0; i < sizeof(c_cpunames) / sizeof(c_cpunames[0]); ++i) {
if (strncmp(c_cpunames[i], u.buf, 12) == 0) {
cputype = (cputype_t)i;
break;
......
......@@ -45,6 +45,7 @@ static void check_siphash24(struct siphash24_ctx *ctx)
static bool alignment_ok(const void *p, size_t n)
{
#if HAVE_UNALIGNED_ACCESS
(void)p; (void)n;
return true;
#else
return ((size_t)p % n == 0);
......
......@@ -3,7 +3,7 @@
#include <stddef.h>
#include <ccan/tap/tap.h>
int main(int argc, char *argv[])
int main(void)
{
union {
uint64_t u64;
......
......@@ -15,6 +15,7 @@ int main(int argc, char *argv[])
int pfd[2];
const char *base;
(void)argc;
plan_tests(24);
err_set_progname(argv[0]);
......@@ -27,7 +28,8 @@ int main(int argc, char *argv[])
base = argv[0];
/* Test err() in child */
pipe(pfd);
if (pipe(pfd))
abort();
fflush(stdout);
if (fork()) {
char buffer[BUFFER_MAX+1];
......@@ -59,7 +61,8 @@ int main(int argc, char *argv[])
}
/* Test errx() in child */
pipe(pfd);
if (pipe(pfd))
abort();
fflush(stdout);
if (fork()) {
char buffer[BUFFER_MAX+1];
......@@ -89,7 +92,8 @@ int main(int argc, char *argv[])
/* Test warn() in child */
pipe(pfd);
if (pipe(pfd))
abort();
fflush(stdout);
if (fork()) {
char buffer[BUFFER_MAX+1];
......@@ -121,7 +125,8 @@ int main(int argc, char *argv[])
}
/* Test warnx() in child */
pipe(pfd);
if (pipe(pfd))
abort();
fflush(stdout);
if (fork()) {
char buffer[BUFFER_MAX+1];
......
......@@ -44,7 +44,7 @@ static int count_iters(void)
int main(void)
{
int i, j, sum, max_iters;
int i, j, sum, max_iters = 0 /* keep gcc happy */;
const char *istr, *jstr;
plan_tests(13);
......
......@@ -36,6 +36,7 @@
* // Wrapper for rehash function pointer.
* static size_t rehash(const void *e, void *unused)
* {
* (void)unused;
* return hash_string(((struct name_to_digit *)e)->name);
* }
*
......@@ -64,7 +65,7 @@
* int main(int argc, char *argv[])
* {
* struct htable ht;
* unsigned int i;
* int i;
* unsigned long val;
*
* if (argc < 2)
......@@ -73,7 +74,7 @@
*
* // Create and populate hash table.
* htable_init(&ht, rehash, NULL);
* for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
* for (i = 0; i < (int)(sizeof(map)/sizeof(map[0])); i++)
* htable_add(&ht, hash_string(map[i].name), &map[i]);
*
* // Add any aliases to the hash table.
......
......@@ -35,6 +35,7 @@ struct htable {
* // For simplicity's sake, say hash value is contents of elem.
* static size_t rehash(const void *elem, void *unused)
* {
* (void)unused;
* return *(size_t *)elem;
* }
* static struct htable ht = HTABLE_INITIALIZER(ht, rehash, NULL);
......
......@@ -6,7 +6,7 @@
#define NUM_VALS 512
static size_t hash(const void *elem, void *unused)
static size_t hash(const void *elem, void *unused UNNEEDED)
{
size_t h = *(uint64_t *)elem / 2;
return h;
......@@ -17,7 +17,7 @@ static bool cmp(const void *candidate, void *ptr)
return *(const uint64_t *)candidate == *(const uint64_t *)ptr;
}
int main(int argc, char *argv[])
int main(void)
{
struct htable ht, ht2;
uint64_t val[NUM_VALS], i;
......
......@@ -8,13 +8,13 @@
/* We use the number divided by two as the hash (for lots of
collisions). */
static size_t hash(const void *elem, void *unused)
static size_t hash(const void *elem, void *unused UNNEEDED)
{
size_t h = *(uint64_t *)elem / 2;
return h;
}
int main(int argc, char *argv[])
int main(void)
{
struct htable ht;
uint64_t val[NUM_VALS];
......
......@@ -88,7 +88,7 @@ static void del_vals(struct htable_obj *ht,
}
static void del_vals_bykey(struct htable_obj *ht,
const struct obj val[], unsigned int num)
const struct obj val[] UNNEEDED, unsigned int num)
{
unsigned int i;
......@@ -112,7 +112,7 @@ static bool check_mask(struct htable *ht, const struct obj val[], unsigned num)
return true;
}
int main(int argc, char *argv[])
int main(void)
{
unsigned int i;
struct htable_obj ht, ht2;
......
......@@ -83,7 +83,7 @@ static void del_vals(struct htable_obj *ht,
}
static void del_vals_bykey(struct htable_obj *ht,
const struct obj val[], unsigned int num)
const struct obj val[] UNNEEDED, unsigned int num)
{
unsigned int i;
......@@ -107,7 +107,7 @@ static bool check_mask(struct htable *ht, const struct obj val[], unsigned num)
return true;
}
int main(int argc, char *argv[])
int main(void)
{
unsigned int i;
struct htable_obj ht, ht2;
......
......@@ -8,7 +8,7 @@ struct data {
};
/* Hash is simply key itself. */
static size_t hash(const void *e, void *unused)
static size_t hash(const void *e, void *unused UNNEEDED)
{
struct data *d = (struct data *)e;
......
......@@ -10,7 +10,7 @@
/* We use the number divided by two as the hash (for lots of
collisions), plus set all the higher bits so we can detect if they
don't get masked out. */
static size_t hash(const void *elem, void *unused)
static size_t hash(const void *elem, void *unused UNNEEDED)
{
size_t h = *(uint64_t *)elem / 2;
h |= -1UL << NUM_BITS;
......@@ -95,7 +95,7 @@ static bool check_mask(struct htable *ht, uint64_t val[], unsigned num)
return true;
}
int main(int argc, char *argv[])
int main(void)
{
unsigned int i, weight;
uintptr_t perfect_bit;
......
......@@ -19,7 +19,7 @@ static int test_ilog64(uint64_t _v){
#define NTRIALS (64)
int main(int _argc,const char *_argv[]){
int main(void){
int i;
int j;
int (*il32)(uint32_t) = ilog32;
......
......@@ -19,7 +19,7 @@ static int test_ilog64(uint64_t _v){
#define NTRIALS (64)
int main(int _argc,const char *_argv[]){
int main(void){
int i;
int j;
/*This is how many tests you plan to run.*/
......
......@@ -47,7 +47,8 @@ struct io_conn;
* int fd[2];
* struct io_conn *conn;
*
* pipe(fd);
* if (pipe(fd) != 0)
* exit(1);
* conn = io_new_conn(NULL, fd[0], conn_init, (const char *)"hi!");
* if (!conn)
* exit(1);
......@@ -653,11 +654,11 @@ int io_conn_fd(const struct io_conn *conn);
* io_time_override - override the normal call for time.
* @nowfn: the function to call.
*
* io usually uses time_now() internally, but this forces it
* io usually uses time_mono() internally, but this forces it
* to use your function (eg. for debugging). Returns the old
* one.
*/
struct timeabs (*io_time_override(struct timeabs (*now)(void)))(void);
struct timemono (*io_time_override(struct timemono (*now)(void)))(void);
/**
* io_set_debug - set synchronous mode on a connection.
......
......@@ -16,11 +16,11 @@ static struct pollfd *pollfds = NULL;
static struct fd **fds = NULL;
static LIST_HEAD(closing);
static LIST_HEAD(always);
static struct timeabs (*nowfn)(void) = time_now;
static struct timemono (*nowfn)(void) = time_mono;
struct timeabs (*io_time_override(struct timeabs (*now)(void)))(void)
struct timemono (*io_time_override(struct timemono (*now)(void)))(void)
{
struct timeabs (*old)(void) = nowfn;
struct timemono (*old)(void) = nowfn;
nowfn = now;
return old;
}
......@@ -262,7 +262,7 @@ void *io_loop(struct timers *timers, struct timer **expired)
assert(num_waiting);
if (timers) {
struct timeabs now, first;
struct timemono now, first;
now = nowfn();
......@@ -274,7 +274,7 @@ void *io_loop(struct timers *timers, struct timer **expired)
/* Now figure out how long to wait for the next one. */
if (timer_earliest(timers, &first)) {
uint64_t next;
next = time_to_msec(time_between(first, now));
next = time_to_msec(timemono_between(first, now));
if (next < INT_MAX)
ms_timeout = next;
else
......
......@@ -69,7 +69,7 @@ static int make_listen_fd(const char *port, struct addrinfo **info)
int main(void)
{
int state = 0;
struct addrinfo *addrinfo;
struct addrinfo *addrinfo = NULL;
struct io_listener *l;
int fd;
......
......@@ -71,7 +71,7 @@ static int make_listen_fd(const char *port, struct addrinfo **info)
int main(void)
{
struct data *d = malloc(sizeof(*d));
struct addrinfo *addrinfo;
struct addrinfo *addrinfo = NULL;
struct io_listener *l;
int fd, status;
......
......@@ -47,8 +47,7 @@ static struct io_plan *init_conn(struct io_conn *conn, struct data *d)
d->conn = conn;
io_set_finish(conn, finish_ok, d);
timer_add(&d->timers, &d->timer,
timeabs_add(time_now(), time_from_usec(d->timeout_usec)));
timer_addrel(&d->timers, &d->timer, time_from_usec(d->timeout_usec));
return io_read(conn, d->buf, sizeof(d->buf), no_timeout, d);
}
......@@ -97,7 +96,7 @@ int main(void)
plan_tests(21);
d->state = 0;
d->timeout_usec = 100000;
timers_init(&d->timers, time_now());
timers_init(&d->timers, time_mono());
timer_init(&d->timer);
fd = make_listen_fd(PORT, &addrinfo);
ok1(fd >= 0);
......@@ -131,7 +130,7 @@ int main(void)
/* One element, d->timer. */
ok1(expired == &d->timer);
ok1(!timers_expire(&d->timers, time_now()));
ok1(!timers_expire(&d->timers, time_mono()));
ok1(d->state == 1);
io_close(d->conn);
......
......@@ -45,9 +45,9 @@ static int make_listen_fd(const char *port, struct addrinfo **info)
return fd;
}
static struct timeabs fake_time;
static struct timemono fake_time;
static struct timeabs get_fake_time(void)
static struct timemono get_fake_time(void)
{
return fake_time;
}
......@@ -63,12 +63,12 @@ int main(void)
/* This is how many tests you plan to run */
plan_tests(7);
fake_time = time_now();
fake_time = time_mono();
timers_init(&timers, fake_time);
timer_init(&timer);
timer_add(&timers, &timer,
timeabs_add(fake_time, time_from_sec(1000)));
timer_addmono(&timers, &timer,
timemono_add(fake_time, time_from_sec(1000)));
fd = make_listen_fd(PORT, &addrinfo);
freeaddrinfo(addrinfo);
......@@ -77,12 +77,12 @@ int main(void)
ok1(l);
fake_time.ts.tv_sec += 1000;
ok1(io_time_override(get_fake_time) == time_now);
ok1(io_time_override(get_fake_time) == time_mono);
ok1(io_loop(&timers, &expired) == NULL);
ok1(expired == &timer);
ok1(!timers_expire(&timers, fake_time));
ok1(io_time_override(time_now) == get_fake_time);
ok1(io_time_override(time_mono) == get_fake_time);
io_close_listener(l);
timers_cleanup(&timers);
......
......@@ -134,7 +134,7 @@ static const uint32_t STATEVEC[ISAAC_SZ<<1]={
0x46D95CA5, 0xC54CD95B, 0x9D855E89, 0x4BB5AF29
};
int main(int _argc,const char *_argv[]){
int main(void){
isaac_ctx isaac;
int i;
int j;
......
......@@ -262,7 +262,7 @@ static const uint64_t STATEVEC64[ISAAC64_SZ<<1]={
0x1877B51E57A764D5ULL, 0x001F837CC7350524ULL
};
int main(int _argc,const char *_argv[]){
int main(void){
isaac64_ctx isaac64;
int i;
int j;
......
CFLAGS=-Wall -Werror -O3 -I../../..
LDFLAGS=-lJudy
LDLIBS=-lJudy
speed: speed.o
speed.o: speed.c ../jmap.h ../jmap_type.h ../jmap.c
speed.o: speed.c ../jmap.h
/* Simple speed tests for jmap. */
#include <ccan/jmap/jmap_type.h>
#include <ccan/jmap/jmap.c>
#include <ccan/time/time.c>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
struct object {
/* Some contents. Doubles as consistency check. */
struct object *self;
};
struct jmap_obj {
JMAP_MEMBERS(unsigned int, struct object *);
};
/* Nanoseconds per operation */
static size_t normalize(const struct timeval *start,
const struct timeval *stop,
static size_t normalize(const struct timeabs *start,
const struct timeabs *stop,
unsigned int num)
{
struct timeval diff;
timersub(stop, start, &diff);
/* Floating point is more accurate here. */
return (double)(diff.tv_sec * 1000000 + diff.tv_usec)
/ num * 1000;
return time_to_nsec(time_divide(time_between(*stop, *start), num));
}
JMAP_DEFINE_UINTIDX_TYPE(struct object, obj);
int main(int argc, char *argv[])
{
struct object *objs;
size_t i, j, num;
struct timeval start, stop;
unsigned int i, j;
size_t num;
struct timeabs start, stop;
struct jmap_obj *jmap;
num = argv[1] ? atoi(argv[1]) : 1000000;
......@@ -42,110 +37,110 @@ int main(int argc, char *argv[])
objs[i].self = &objs[i];
}
jmap = jmap_obj_new();
jmap = jmap_new(struct jmap_obj);
printf("Initial insert: ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i++)
jmap_obj_add(jmap, i, objs[i].self);
gettimeofday(&stop, NULL);
jmap_add(jmap, i, objs[i].self);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Initial lookup (match): ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, i)->self != objs[i].self)
if (jmap_get(jmap, i)->self != objs[i].self)
abort();
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Initial lookup (miss): ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, i+num))
if (jmap_get(jmap, i+num))
abort();
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
/* Lookups in order are very cache-friendly for judy; try random */
printf("Initial lookup (random): ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num)
if (jmap_obj_get(jmap, j)->self != &objs[j])
if (jmap_get(jmap, j)->self != &objs[j])
abort();
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Initial delete all: ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i++)
jmap_obj_del(jmap, i);
gettimeofday(&stop, NULL);
jmap_del(jmap, i);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Initial re-inserting: ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i++)
jmap_obj_add(jmap, i, objs[i].self);
gettimeofday(&stop, NULL);
jmap_add(jmap, i, objs[i].self);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Deleting first half: ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i+=2)
jmap_obj_del(jmap, i);
gettimeofday(&stop, NULL);
jmap_del(jmap, i);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Adding (a different) half: ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i+=2)
jmap_obj_add(jmap, num+i, objs[i].self);
gettimeofday(&stop, NULL);
jmap_add(jmap, num+i, objs[i].self);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after half-change (match): ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 1; i < num; i+=2)
if (jmap_obj_get(jmap, i)->self != objs[i].self)
if (jmap_get(jmap, i)->self != objs[i].self)
abort();
for (i = 0; i < num; i+=2)
if (jmap_obj_get(jmap, i+num)->self != objs[i].self)
if (jmap_get(jmap, i+num)->self != objs[i].self)
abort();
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after half-change(miss): ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, i+num*2))
if (jmap_get(jmap, i+num*2))
abort();
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
/* Hashtables with delete markers can fill with markers over time.
* so do some changes to see how it operates in long-term. */
printf("Details: churning first time\n");
for (i = 1; i < num; i+=2) {
if (!jmap_obj_del(jmap, i))
if (!jmap_del(jmap, i))
abort();
jmap_obj_add(jmap, i, objs[i].self);
jmap_add(jmap, i, objs[i].self);
}
for (i = 0; i < num; i+=2) {
if (!jmap_obj_del(jmap, i+num))
if (!jmap_del(jmap, i+num))
abort();
jmap_obj_add(jmap, i, objs[i].self);
jmap_add(jmap, i, objs[i].self);
}
for (i = 1; i < 5; i++) {
printf("Churning %s time: ",
......@@ -154,84 +149,88 @@ int main(int argc, char *argv[])
: i == 3 ? "fourth"
: "fifth");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (j = 0; j < num; j++) {
if (!jmap_obj_del(jmap, num*(i-1)+j))
if (!jmap_del(jmap, num*(i-1)+j))
abort();
jmap_obj_add(jmap, num*i+j, &objs[j]);
jmap_add(jmap, num*i+j, &objs[j]);
}
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
}
/* Spread out the keys more to try to make it harder. */
printf("Details: reinserting with spread\n");
for (i = 0; i < num; i++) {
if (!jmap_obj_del(jmap, num*4 + i))
if (!jmap_del(jmap, num*4 + i))
abort();
jmap_obj_add(jmap, num * 5 + i * 9, objs[i].self);
jmap_add(jmap, num * 5 + i * 9, objs[i].self);
}
if (jmap_obj_popcount(jmap, 0, -1) != num)
if (jmap_popcount(jmap, 0, -1) != num)
abort();
printf("Lookup after churn & spread (match): ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, num * 5 + i * 9)->self != objs[i].self) {
if (jmap_get(jmap, num * 5 + i * 9)->self != objs[i].self) {
printf("i =%u\n", i);
abort();
}
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after churn & spread (miss): ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, num * 6 + i * 9))
if (jmap_get(jmap, num * 6 + i * 9))
abort();
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after churn & spread (random): ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num)
if (jmap_obj_get(jmap, num * 5 + j * 9)->self != &objs[j])
if (jmap_get(jmap, num * 5 + j * 9)->self != &objs[j])
abort();
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after churn & spread (half-random): ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0, j = 0; i < num/2; i++, j = (j + 10007) % num) {
if (jmap_obj_get(jmap, num * 5 + j * 9)->self != &objs[j])
if (jmap_get(jmap, num * 5 + j * 9)->self != &objs[j])
abort();
if (jmap_obj_get(jmap, num * 5 + (j + 1) * 9)->self != &objs[j+1])
if (jmap_get(jmap, num * 5 + (j + 1) * 9)->self != &objs[j+1])
abort();
}
gettimeofday(&stop, NULL);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Deleting half after churn & spread: ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i+=2)
jmap_obj_del(jmap, num * 5 + i * 9);
gettimeofday(&stop, NULL);
jmap_del(jmap, num * 5 + i * 9);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Adding (a different) half after churn & spread: ");
fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (i = 0; i < num; i+=2)
jmap_obj_add(jmap, num * 6 + i * 9, objs[i].self);
gettimeofday(&stop, NULL);
jmap_add(jmap, num * 6 + i * 9, objs[i].self);
stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num));
jmap_free(jmap);
free (objs);
return 0;
}
......@@ -26,7 +26,7 @@ static bool likely_one_unlikely_two(unsigned int val1, unsigned int val2)
return false;
}
int main(int argc, char *argv[])
int main(void)
{
char *bad;
......
......@@ -17,7 +17,7 @@ static bool one_seems_unlikely(unsigned int val)
return false;
}
int main(int argc, char *argv[])
int main(void)
{
plan_tests(4);
......
......@@ -31,7 +31,7 @@
* {
* struct parent p;
* struct child *c;
* unsigned int i;
* int i;
*
* if (argc < 2)
* errx(1, "Usage: %s parent children...", argv[0]);
......
......@@ -291,6 +291,21 @@ static inline bool list_empty_nodebug(const struct list_head *h)
}
#endif
/**
* list_empty_nocheck - is a list empty?
* @h: the list_head
*
* If the list is empty, returns true. This doesn't perform any
* debug check for list consistency, so it can be called without
* locks, racing with the list being modified. This is ok for
* checks where an incorrect result is not an issue (optimized
* bail out path for example).
*/
static inline bool list_empty_nocheck(const struct list_head *h)
{
return h->n.next == &h->n;
}
/**
* list_del - delete an entry from an (unknown) linked list.
* @n: the list_node to delete from the list.
......@@ -701,12 +716,12 @@ static inline void list_prepend_list_(struct list_head *to,
* so you can break and continue as normal.
*
* WARNING! Being the low-level macro that it is, this wrapper doesn't know
* nor care about the type of @i. The only assumtion made is that @i points
* nor care about the type of @i. The only assumption made is that @i points
* to a chunk of memory that at some @offset, relative to @i, contains a
* properly filled `struct node_list' which in turn contains pointers to
* memory chunks and it's turtles all the way down. Whith all that in mind
* properly filled `struct list_node' which in turn contains pointers to
* memory chunks and it's turtles all the way down. With all that in mind
* remember that given the wrong pointer/offset couple this macro will
* happilly churn all you memory untill SEGFAULT stops it, in other words
* happily churn all you memory until SEGFAULT stops it, in other words
* caveat emptor.
*
* It is worth mentioning that one of legitimate use-cases for that wrapper
......
......@@ -17,6 +17,7 @@ static int my_fprintf(FILE *stream, const char *format, ...)
{
va_list ap;
int ret;
(void)stream;
va_start(ap, format);
ret = vsprintf(printf_buffer, format, ap);
va_end(ap);
......@@ -28,7 +29,7 @@ static int my_fprintf(FILE *stream, const char *format, ...)
#include <ccan/tap/tap.h>
#include <ccan/list/list.c>
int main(int argc, char *argv[])
int main(void)
{
struct list_head list;
struct list_node n1;
......@@ -44,7 +45,7 @@ int main(int argc, char *argv[])
list.n.prev = &n1;
/* Aborting version. */
sprintf(expect, "run-CCAN_LIST_DEBUG.c:50: prev corrupt in node %p (0) of %p\n",
sprintf(expect, "run-CCAN_LIST_DEBUG.c:51: prev corrupt in node %p (0) of %p\n",
&list, &list);
if (setjmp(aborted) == 0) {
assert(list_empty(&list));
......
......@@ -16,6 +16,7 @@ static int my_fprintf(FILE *stream, const char *format, ...)
{
va_list ap;
int ret;
(void)stream;
va_start(ap, format);
ret = vsprintf(printf_buffer, format, ap);
va_end(ap);
......@@ -26,7 +27,7 @@ static int my_fprintf(FILE *stream, const char *format, ...)
#include <ccan/tap/tap.h>
#include <ccan/list/list.c>
int main(int argc, char *argv[])
int main(void)
{
struct list_head list;
struct list_node n1;
......
......@@ -8,7 +8,7 @@ struct child {
struct list_node list;
};
int main(int argc, char *argv[])
int main(void)
{
struct child c1, c2;
struct list_head list = LIST_HEAD_INIT(list);
......
......@@ -7,7 +7,7 @@
#include <unistd.h>
#include <signal.h>
int main(int argc, char *argv[])
int main(void)
{
struct list_head list1, list2;
struct list_node n1, n2, n3;
......
......@@ -14,7 +14,7 @@ struct child {
struct list_node list;
};
int main(int argc, char *argv[])
int main(void)
{
struct parent parent;
struct child c1, c2, c3;
......
......@@ -17,7 +17,7 @@ static bool list_expect(struct list_head *h, ...)
return (n->next == &h->n);
}
int main(int argc, char *argv[])
int main(void)
{
struct list_head h1, h2;
struct list_node n[4];
......
......@@ -19,7 +19,7 @@ static LIST_HEAD(static_list);
#define ref(obj, counter) ((counter)++, (obj))
int main(int argc, char *argv[])
int main(void)
{
struct parent parent;
struct child c1, c2, c3, *c, *n;
......
......@@ -16,7 +16,7 @@ struct child {
static LIST_HEAD(static_list);
int main(int argc, char *argv[])
int main(void)
{
struct parent parent;
struct child c1, c2, c3, x1, *c, *n;
......
......@@ -250,6 +250,7 @@ static inline void *memcheck_(const void *data, size_t len)
#else
static inline void *memcheck_(const void *data, size_t len)
{
(void)len;
return (void *)data;
}
#endif
......
......@@ -37,7 +37,7 @@
* return false;
* }
* // A short write means out of space.
* if (ret < strlen(string)) {
* if (ret < (int)strlen(string)) {
* unlink(file);
* errno = ENOSPC;
* return false;
......
......@@ -7,7 +7,7 @@
#include <stdio.h>
#include <assert.h>
int main(int argc, char *argv[])
int main(void)
{
const char *name = "noerr.file";
int fd;
......
......@@ -185,7 +185,7 @@ void opt_register_table(const struct opt_table *table, const char *desc);
* string (or see opt_set_alloc) and return false.
*
* Example:
* static char *explode(const char *optarg, void *unused)
* static char *explode(const char *optarg, void *unused UNNEEDED)
* {
* errx(1, "BOOM! %s", optarg);
* }
......
......@@ -4,7 +4,7 @@
#include <ccan/opt/parse.c>
#include <ccan/opt/usage.c>
int main(int argc, char *argv[])
int main(void)
{
opt_register_noarg("-v", opt_version_and_exit,
(const char *)"1.2.3",
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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