LCOV - code coverage report
Current view: top level - libsd - mdl.c (source / functions) Hit Total Coverage
Test: app.info Lines: 57 62 91.9 %
Date: 2015-08-29 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // Copyright 2014 Bobby Powers. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style
       3             : // license that can be found in the LICENSE file.
       4             : 
       5             : #include <stdarg.h>
       6             : #include <stdio.h>
       7             : #include <stdlib.h>
       8             : #include <string.h>
       9             : 
      10             : #include "sd.h"
      11             : 
      12             : 
      13             : typedef struct {
      14             :         double *series;
      15             : } Result;
      16             : 
      17             : 
      18             : static void die(const char *, ...);
      19             : static void usage(void);
      20             : 
      21             : static const char *argv0;
      22             : 
      23             : 
      24             : void __attribute__((noreturn))
      25           4 : die(const char *fmt, ...)
      26             : {
      27             :         va_list args;
      28             : 
      29           4 :         va_start(args, fmt);
      30           4 :         vfprintf(stderr, fmt, args);
      31           4 :         va_end(args);
      32             : 
      33           4 :         exit(EXIT_FAILURE);
      34             : }
      35             : 
      36             : void
      37           4 : usage(void)
      38             : {
      39           4 :         die("Usage: %s [OPTION...] PATH\n" \
      40             :             "Simulate system dynamics models.\n\n" \
      41             :             "Options:\n" \
      42             :             "  -help:\tshow this message\n",
      43             :             argv0);
      44             : }
      45             : 
      46             : int
      47          17 : main(int argc, char *const argv[])
      48             : {
      49          17 :         int err = 0;
      50             :         SDProject *p;
      51             :         SDSim *s;
      52             :         int nvars, nsteps, n;
      53             :         Result *results;
      54             :         const char *fmt;
      55          17 :         const char **names = NULL;
      56          17 :         const char *path = NULL;
      57             : 
      58          31 :         for (argv0 = argv[0], argv++, argc--; argc > 0; argv++, argc--) {
      59          17 :                 char const* arg = argv[0];
      60          17 :                 if (strcmp("-help", arg) == 0) {
      61           1 :                         usage();
      62          16 :                 } else if (arg[0] == '-') {
      63           1 :                         fprintf(stderr, "unknown arg '%s'\n", arg);
      64           1 :                         usage();
      65             :                 } else {
      66          15 :                         if (!path) {
      67          14 :                                 path = arg;
      68             :                         } else {
      69           1 :                                 fprintf(stderr, "specify a single path to a model\n");
      70           1 :                                 usage();
      71             :                         }
      72             :                 }
      73             :         }
      74             : 
      75          14 :         if (!path) {
      76           1 :                 fprintf(stderr, "specify a single path to a model\n");
      77           1 :                 usage();
      78             :         }
      79             : 
      80          13 :         p = sd_project_open(path, &err);
      81          13 :         if (err)
      82           0 :                 die("error opening project: %s\n", sd_error_str(err));
      83             : 
      84          13 :         s = sd_sim_new(p, NULL);
      85          13 :         if (!s)
      86           0 :                 die("couldn't create simulation context\n");
      87             : 
      88          13 :         sd_sim_run_to_end(s);
      89             : 
      90          13 :         nsteps = sd_sim_get_stepcount(s);
      91          13 :         nvars = sd_sim_get_varcount(s);
      92          13 :         names = calloc(nvars, sizeof(*names));
      93          13 :         results = calloc(nvars, sizeof(*results));
      94          13 :         if (!names || !results)
      95           0 :                 die("out of memory\n");
      96             : 
      97          13 :         if (sd_sim_get_varnames(s, names, nvars) != nvars)
      98           0 :                 die("get_varnames unexpected result != %d\n", nvars);
      99             : 
     100          82 :         for (int v = 0; v < nvars; v++) {
     101          69 :                 Result *result = results + v;
     102          69 :                 result->series = calloc(nsteps, sizeof(double));
     103          69 :                 n = sd_sim_get_series(s, names[v], result->series, nsteps);
     104          69 :                 if (n != nsteps)
     105           0 :                         die("short series read of %d for '%s' (%d/%d)\n", n, names[v], v, nvars);
     106          69 :                 fmt = v == nvars-1 ? "%s\n" : "%s\t";
     107          69 :                 printf(fmt, names[v]);
     108             :         }
     109             : 
     110        3995 :         for (int i = 0; i < nsteps; i++) {
     111       36567 :                 for (int v = 0; v < nvars; v++) {
     112       32585 :                         Result *result = results + v;
     113       32585 :                         fmt = v == nvars-1 ? "%f\n" : "%f\t";
     114       32585 :                         printf(fmt, result->series[i]);
     115             :                 }
     116             :         }
     117             : 
     118          82 :         for (int i = 0; i < nvars; i++) {
     119          69 :                 Result *r = results + i;
     120          69 :                 free(r->series);
     121             :         }
     122          13 :         free(results);
     123          13 :         free(names);
     124             : 
     125          13 :         sd_sim_unref(s);
     126          13 :         sd_project_unref(p);
     127             : 
     128          13 :         fflush(stdout);
     129             : 
     130          13 :         return 0;
     131             : }

Generated by: LCOV version 1.10