3 * @author Sam Moore (20503628) - 2012
4 * @purpose Contains main function, argument handling
5 * NOTE: This file is identical for both the single-threaded and multi-threaded versions of the program
16 // --- Variable definitions --- //
17 System universe; // global variable declared in "nbody.h" - The universe of bodies
18 Options options; // global variable declared in "nbody.h" - Options passed to program through arguments
21 // --- Function forward declarations --- //
22 void HandleArguments(int argc, char ** argv); //Interprets program arguments and sets up the "options" variable
23 void UnsignedArgument(unsigned * i, int argc, char ** argv, unsigned * store); //Helper function to get switch value for unsigned
24 void FloatArgument(unsigned * i, int argc, char ** argv, float * store); //Helper function to get switch value for float
25 void DisplayStatistics(); //Called on exit of program, displays information about computation time, steps computed, etc
26 void Interrupt(int dummy); // Interrupt handler function, called when SIGINT (Ctrl-C) is sent to program
28 // --- Function implementations --- //
32 * @purpose The main function. Calls HandleArguments to set up options,
33 * sets up functions to call at exit, starts simulation and graphics loops
34 * @param argc - Number of arguments
35 * @param argv - The argument strings
37 int main(int argc, char** argv)
39 //Set default options values here
40 options.program = argv[0];
42 options.output = NULL;
43 options.num_threads = 0;
44 options.num_steps = 0;
46 options.draw_graphics = true;
47 options.print_positions = false;
48 options.verbosity = 0;
50 //If there are no arguments, print information about usage
53 printf("Usage: %s [OPTIONS] field\n", argv[0]);
54 printf("Controls:\n X - exit\n I, J, K, M - rotate\n W, Z, A, S - move to view"
55 " point\n ./, - zoom in/out\n +/- - scaled zoom in/out\n");
60 HandleArguments(argc, argv);
62 //Check there is an initial field.
63 if (options.input == NULL)
65 fprintf(stderr, "Usage: %s [OPTIONS] field\n", argv[0]);
66 fprintf(stderr, " (You did not provide a file for the initial field of bodies)\n");
70 signal(SIGINT, Interrupt); //Handle SIGINT signals
71 atexit(Universe_Cleanup); //On exit, cleanup universe (and write positions of bodies to file if supplied).
72 atexit(DisplayStatistics); //On exit, print information about the computations done
73 System_Init(&universe,options.input); //Initialise the universe from the initial field
75 //Setup the time of day at which the simulation starts
76 if (gettimeofday(&(options.start_time), NULL) != 0)
78 perror("Couldn't get time of day");
82 options.start_clock = clock(); //Get CPU cycles executed before simulation starts
83 Simulation_Run(); // Start the simulation
84 Graphics_Run(argc, argv); //Start the graphics loop
86 exit(EXIT_FAILURE); //Should never get to this line
91 * @function HandleArguments
92 * @purpose Fill the "options" variable by parsing command line arguments
93 * @param argc - Number of arguments
94 * @param argv - Argument strings
96 void HandleArguments(int argc, char ** argv)
98 for (unsigned i = 1; i < argc; ++i) //For all arguments
100 if (argv[i][0] != '-') //If the argument is not a switch value...
102 //Interpret first non switch as input file, and second as output file.
103 //If there are too many non switch arguments, give an error.
104 if (options.input == NULL)
105 options.input = argv[i];
106 else if (options.output == NULL)
107 options.output = argv[i];
110 fprintf(stderr,"Usage: %s [OPTIONS] field [output]\n", argv[0]);
111 fprintf(stderr," (You provided too many file names)\n");
116 switch (argv[i][1]) //The argument is a switch if we get here
118 case 'n': //Number of threads switch
119 UnsignedArgument(&i, argc, argv, &(options.num_threads));
120 #ifdef SINGLE_THREADED
121 fprintf(stderr, "Warning: -%c switch has no effect in the single-threaded program.\n", argv[i][1]);
122 options.num_threads = 1;
123 #endif //SINGLE_THREADED
125 case 's': //Number of steps switch
126 UnsignedArgument(&i, argc, argv, &(options.num_steps));
128 case 't': //Timeout switch (in seconds)
129 UnsignedArgument(&i, argc, argv, &(options.timeout));
131 case 'g': //Graphics switch
132 options.draw_graphics = !options.draw_graphics;
134 case 'v': //Verbosity switch
135 UnsignedArgument(&i, argc, argv, &(options.verbosity));
139 fprintf(stderr, "Unrecognised switch -%c\n", argv[i][1]);
148 * @function UnsignedArgument
149 * @purpose Helper function to get an unsigned integer following a argument switch
150 * @param i - position in the argument array, will be updated after this function
151 * @param argc - number of arguments
152 * @param argv - argument strings
153 * @param store - pointer to unsigned to store result in
155 void UnsignedArgument(unsigned * i, int argc, char ** argv, unsigned * store)
159 fprintf(stderr,"Supply a positive integer for the -%c switch.\n", argv[*i][1]);
162 int val = atoi(argv[*i+1]);
165 fprintf(stderr,"Supply a positive integer for the -%c switch. %s is invalid.\n", argv[*i][1], argv[*i+1]);
172 * @function FloatArgument
173 * @purpose Helper function to get a float following a argument switch
174 * @param i - position in the argument array, will be updated after this function
175 * @param argc - number of arguments
176 * @param argv - argument strings
177 * @param store - pointer to float to store result in
179 void FloatArgument(unsigned * i, int argc, char ** argv, float * store)
183 fprintf(stderr,"Supply a float for the -%c switch.\n", argv[*i][1]);
186 *store = atof(argv[*i+1]);
187 if (*store == 0.0 && argv[*i+1][0] != '0')
189 fprintf(stderr,"Supply a float for the -%c switch.\n", argv[*i][1]);
198 * @function Interrupt
199 * @purpose Handle SIGINT signal; quit the program gracefully, so that statistics are still displayed
200 * @param dummy - a dummy
203 void Interrupt(int dummy)