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>
1719#define CONFIG_USE_NUMERIC_NAMES 1
1820#endif
1921
22+ #define DEFAULT_RANGE 25
23+ #define DELIM "\t ;,"
24+
2025struct 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+
247328int 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