Qucs-core  0.0.19
csv_producer.cpp
Go to the documentation of this file.
00001 /*
00002  * csv_producer.cpp - the CSV data file producer
00003  *
00004  * Copyright (C) 2006, 2007 Stefan Jahn <stefan@lkcc.org>
00005  *
00006  * This is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2, or (at your option)
00009  * any later version.
00010  *
00011  * This software is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this package; see the file COPYING.  If not, write to
00018  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  * $Id$
00022  *
00023  */
00024 
00025 #if HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <time.h>
00032 #include <string.h>
00033 #include "dataset.h"
00034 
00035 #include "csv_producer.h"
00036 
00037 using namespace qucs;
00038 
00039 /* Global variables. */
00040 qucs::dataset * qucs_data = NULL;
00041 /* FILE * csv_out = NULL; -- already defined in CSV lexer */
00042 
00043 struct csv_data {
00044   char type;  // type of variable
00045   vector * v; // appropriate data vector
00046   int idx;    // index into vector
00047   int skip;   // skip length
00048   int len;    // length of vector
00049 };
00050 
00051 /* Definition of line separator. */
00052 #ifdef __MINGW32__
00053 #define csv_crlf "\n"
00054 #else
00055 #define csv_crlf "\r\n"
00056 #endif
00057 
00058 /* The CSV data printer. */
00059 void csv_print (struct csv_data * data, int vectors, const char * sep) {
00060 
00061   int len = 0;
00062 
00063   // print header
00064   for (int i = 0; i < vectors; i++) {
00065     if (data[i].type == 'c')
00066       fprintf (csv_out, "\"r %s\"%s\"i %s\"", data[i].v->getName (),
00067                sep, data[i].v->getName ());
00068     else
00069       fprintf (csv_out, "\"%s\"", data[i].v->getName ());
00070     fprintf (csv_out, "%s", i != vectors - 1 ? sep : csv_crlf);
00071     // find longest vector
00072     if (len < data[i].len) len = data[i].len;
00073   }
00074 
00075   // print data
00076   for (int k = 0; k < len; k++) {
00077     for (int i = 0; i < vectors; i++) {
00078       if (data[i].type == 'c')
00079         fprintf (csv_out, "%+." "20" "e%s%+." "20" "e",
00080                  (double) real (data[i].v->get (data[i].idx)), sep,
00081                  (double) imag (data[i].v->get (data[i].idx)));
00082       else
00083         fprintf (csv_out, "%+." "20" "e",
00084                  (double) real (data[i].v->get (data[i].idx)));
00085       fprintf (csv_out, "%s", i != vectors - 1 ? sep : csv_crlf);
00086       data[i].idx = ((k + 1) / data[i].skip) % data[i].len;
00087     }
00088   }
00089 }
00090 
00091 /* This is the overall CSV producer. */
00092 void csv_producer (char * variable, const char * sep) {
00093   vector * v;
00094   // save variable including its dependencies
00095   if (variable && (v = qucs_data->findVariable (variable)) != NULL) {
00096 
00097     // prepare variable + dependency structures
00098     strlist * deps = v->getDependencies ();
00099     int vectors = 1 + (deps ? deps->length () : 0);
00100     struct csv_data * data = new struct csv_data[vectors];
00101     int i = vectors - 1;
00102     data[i].type = real (sum (norm (imag (*v)))) > 0.0 ? 'c' : 'r';
00103     data[i].v = v;
00104     data[i].idx = 0;
00105     data[i].skip = 1;
00106     data[i].len = v->getSize ();
00107 
00108     int a = v->getSize ();
00109     for (i = vectors - 2; i >= 0; i--) {
00110       vector * d = qucs_data->findDependency (deps->get (i));
00111       data[i].type = real (sum (norm (imag (*d)))) > 0.0 ? 'c' : 'r';
00112       data[i].v = d;
00113       data[i].idx = 0;
00114       a /= d->getSize ();
00115       data[i].skip = a;
00116       data[i].len = d->getSize ();
00117     }
00118 
00119     csv_print (data, vectors, sep);
00120     delete[] data;
00121   }
00122   // save dependency + all variable depending on it
00123   else if (variable && (v = qucs_data->findDependency (variable)) != NULL) {
00124 
00125     // prepare dependency + variables structures
00126     vector * vars;
00127     int vectors = 1;
00128     for (vars = qucs_data->getVariables (); vars != NULL;
00129          vars = (vector *) vars->getNext ()) {
00130       strlist * deps = vars->getDependencies ();
00131       if (deps->contains (v->getName ()))
00132         vectors++;
00133     }
00134     struct csv_data * data = new struct csv_data[vectors];
00135 
00136     data[0].type = real (sum (norm (imag (*v)))) > 0.0 ? 'c' : 'r';
00137     data[0].v = v;
00138     data[0].idx = 0;
00139     data[0].skip = 1;
00140     data[0].len = v->getSize ();
00141     int i = 1;
00142     for (vars = qucs_data->getVariables (); vars != NULL;
00143          vars = (vector *) vars->getNext ()) {
00144       strlist * deps = vars->getDependencies ();
00145       if (deps->contains (v->getName ())) {
00146         vector * d = vars;
00147         data[i].type = real (sum (norm (imag (*d)))) > 0.0 ? 'c' : 'r';
00148         data[i].v = d;
00149         data[i].idx = 0;
00150         data[i].skip = 1;
00151         data[i].len = d->getSize ();
00152         i++;
00153       }
00154     }
00155 
00156     csv_print (data, vectors, sep);
00157     delete[] data;
00158   }
00159   // no such data found
00160   else {
00161     fprintf (stderr, "no such data variable `%s' found\n", variable);
00162   }
00163 }