Skip to content

Commit 946f2b8

Browse files
committed
tools/zep_dispatch: topogen: allow to pass worldfile
A world file might look like ``` A 5 3 10 B 10 C 20 20 ```
1 parent 1f6a7b4 commit 946f2b8

File tree

1 file changed

+102
-3
lines changed

1 file changed

+102
-3
lines changed

dist/tools/zep_dispatch/topogen.c

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
* License v2. See the file LICENSE for more details.
66
*/
77

8+
#include <ctype.h>
89
#include <stdbool.h>
910
#include <stdio.h>
1011
#include <stdint.h>
1112
#include <stdlib.h>
13+
#include <string.h>
1214
#include <time.h>
1315
#include <math.h>
1416
#include <unistd.h>
@@ -17,6 +19,9 @@
1719
#define CONFIG_USE_NUMERIC_NAMES 1
1820
#endif
1921

22+
#define DEFAULT_RANGE 25
23+
#define DELIM "\t ;,"
24+
2025
struct node {
2126
char name[8];
2227
int x;
@@ -230,6 +235,7 @@ static void _print_help(const char *name)
230235
" [-r <range>]"
231236
" [-v <variance of range>]"
232237
" [-n <nodes>]"
238+
" [-f <file>]"
233239
" [-b][-g]"
234240
"\n", name);
235241

@@ -240,25 +246,101 @@ static void _print_help(const char *name)
240246
puts("\t-r <range>\tRadio range of the nodes");
241247
puts("\t-v <variance>\tmaximal random variance of radio range");
242248
puts("\t-n <nodes>\tnumber of nodes in the topology");
249+
puts("\t-f <file>\tread world from file instead of generating it randomly\n");
243250
puts("\t-b\t\tbinary links: link quality is rounded to 100% or 0%");
244251
puts("\t-g\t\tnodes are organized as a grid");
245252
}
246253

254+
static bool _is_empty(const char *line)
255+
{
256+
while (*line) {
257+
if (!isspace(*line++)) {
258+
return false;
259+
}
260+
}
261+
262+
return true;
263+
}
264+
265+
static int _from_file(struct world *w, FILE *file)
266+
{
267+
char *line = NULL;
268+
size_t len = 0;
269+
270+
/* count number of nodes */
271+
while (getline(&line, &len, file) >= 0) {
272+
/* skip comments & empty lines */
273+
if (*line == '#' || _is_empty(line)) {
274+
continue;
275+
}
276+
277+
w->num_nodes++;
278+
}
279+
fseek(file, 0, SEEK_SET);
280+
281+
w->nodes = calloc(w->num_nodes, sizeof(*w->nodes));
282+
struct node *n = w->nodes;
283+
284+
unsigned linenum = 0;
285+
while (getline(&line, &len, file) >= 0) {
286+
++linenum;
287+
288+
/* skip comments & empty lines */
289+
if (*line == '#' || _is_empty(line)) {
290+
continue;
291+
}
292+
char *name = strtok(line, DELIM);
293+
char *xpos = strtok(NULL, DELIM);
294+
char *ypos = strtok(NULL, DELIM);
295+
char *range = strtok(NULL, DELIM);
296+
297+
strncpy(n->name, name, sizeof(n->name) - 1);
298+
if (xpos) {
299+
n->x = atoi(xpos);
300+
} else {
301+
fprintf(stderr, "error on line %d: '%s' has no position\n", linenum, name);
302+
return -1;
303+
}
304+
if (ypos) {
305+
n->y = atoi(ypos);
306+
}
307+
if (range) {
308+
n->r = atoi(range);
309+
} else {
310+
n->r = DEFAULT_RANGE;
311+
}
312+
313+
if (n->x + n->r > w->w) {
314+
w->w = n->x + n->r;
315+
}
316+
if (n->y + n->r > w->h) {
317+
w->h = n->y + n->r;
318+
}
319+
320+
++n;
321+
}
322+
323+
free(line);
324+
325+
return 0;
326+
}
327+
247328
int main(int argc, char** argv)
248329
{
249330
const char *progname = argv[0];
331+
char *worldmap = NULL;
250332

251333
unsigned width = 100;
252334
unsigned height = 100;
253335
unsigned seed = time(NULL);
254-
unsigned range = 25;
336+
unsigned range = DEFAULT_RANGE;
255337
unsigned var = 0;
256338
unsigned num = 10;
257339
bool binary = false;
258340
bool grid = false;
259341
char c;
260342

261-
while ((c = getopt(argc, argv, "s:w:h:r:v:n:bg")) != -1) {
343+
while ((c = getopt(argc, argv, "s:w:h:r:v:n:f:bg")) != -1) {
262344
switch (c) {
263345
case 'b':
264346
binary = true;
@@ -284,6 +366,9 @@ int main(int argc, char** argv)
284366
case 'n':
285367
num = atoi(optarg);
286368
break;
369+
case 'f':
370+
worldmap = optarg;
371+
break;
287372
default:
288373
_print_help(progname);
289374
exit(1);
@@ -295,7 +380,21 @@ int main(int argc, char** argv)
295380
struct world w = {
296381
.grid = grid,
297382
};
298-
world_gen(&w, num, width, height, range, var);
383+
384+
if (worldmap) {
385+
FILE *file = fopen(worldmap, "r");
386+
if (!file) {
387+
fprintf(stderr, "can't open %s\n", worldmap);
388+
return -1;
389+
}
390+
int res = _from_file(&w, file);
391+
fclose(file);
392+
if (res) {
393+
return res;
394+
}
395+
} else {
396+
world_gen(&w, num, width, height, range, var);
397+
}
299398

300399
printf("# seed = %u\n", seed);
301400
puts("# Connections");

0 commit comments

Comments
 (0)