LCOV - code coverage report
Current view: top level - src - check_touchstone.cpp (source / functions) Hit Total Coverage
Test: qucs-core-0.0.19 Code Coverage Lines: 0 261 0.0 %
Date: 2015-01-05 16:01:02 Functions: 0 11 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 341 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * check_touchstone.cpp - checker for Touchstone files
       3                 :            :  *
       4                 :            :  * Copyright (C) 2003, 2004, 2005, 2006 Stefan Jahn <stefan@lkcc.org>
       5                 :            :  *
       6                 :            :  * This is free software; you can redistribute it and/or modify
       7                 :            :  * it under the terms of the GNU General Public License as published by
       8                 :            :  * the Free Software Foundation; either version 2, or (at your option)
       9                 :            :  * any later version.
      10                 :            :  *
      11                 :            :  * This software is distributed in the hope that it will be useful,
      12                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :            :  * GNU General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU General Public License
      17                 :            :  * along with this package; see the file COPYING.  If not, write to
      18                 :            :  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
      19                 :            :  * Boston, MA 02110-1301, USA.
      20                 :            :  *
      21                 :            :  * $Id$
      22                 :            :  *
      23                 :            :  */
      24                 :            : 
      25                 :            : #if HAVE_CONFIG_H
      26                 :            : # include <config.h>
      27                 :            : #endif
      28                 :            : 
      29                 :            : #include <stdio.h>
      30                 :            : #include <stdlib.h>
      31                 :            : #include <string.h>
      32                 :            : #include <ctype.h>
      33                 :            : #include <cmath>
      34                 :            : 
      35                 :            : #include "logging.h"
      36                 :            : #include "complex.h"
      37                 :            : #include "object.h"
      38                 :            : #include "vector.h"
      39                 :            : #include "matrix.h"
      40                 :            : #include "matvec.h"
      41                 :            : #include "dataset.h"
      42                 :            : #include "strlist.h"
      43                 :            : #include "constants.h"
      44                 :            : #include "check_touchstone.h"
      45                 :            : 
      46                 :            : #define ZREF 50.0 /* reference impedance */
      47                 :            : 
      48                 :            : using namespace qucs;
      49                 :            : 
      50                 :            : strlist * touchstone_idents = NULL;
      51                 :            : dataset * touchstone_result = NULL;
      52                 :            : qucs::vector  * touchstone_vector = NULL;
      53                 :            : 
      54                 :            : /* default touchstone options */
      55                 :            : struct touchstone_t touchstone_options = {
      56                 :            :   "GHz", 'S', "MA", 50.0, 1e9, 0, 0, 0 };
      57                 :            : 
      58                 :            : /* available touchstone options */
      59                 :            : static const char * touchstone_valid_options[] = {
      60                 :            :   "hz", "khz", "mhz", "ghz", "s", "y", "z", "g", "h", "ma", "db", "ri", NULL };
      61                 :            : 
      62                 :            : /* This subroutine is going to join vectors on multiple lines.  The
      63                 :            :    input and output list of vectors of this function is the
      64                 :            :    touchstone_vector variable. */
      65                 :          0 : static void touchstone_join (void) {
      66                 :          0 :   qucs::vector * yroot, * xroot, * next = NULL;
      67                 :            :   /* go through each vector */
      68         [ #  # ]:          0 :   for (yroot = touchstone_vector; yroot != NULL; yroot = next) {
      69                 :            :     /* go through each trailing vector */
      70                 :          0 :     next = (qucs::vector *) yroot->getNext ();
      71         [ #  # ]:          0 :     for (xroot = next; xroot != NULL; xroot = next) {
      72                 :          0 :       next = (qucs::vector *) xroot->getNext ();
      73                 :            :       /* append xroot vector to yroot vector (even no. of values) ? */
      74         [ #  # ]:          0 :       if ((xroot->getSize () & 1) == 0) {
      75                 :            :         /* yes, delete the xroot vector and adjust list */
      76                 :          0 :         yroot->add (xroot);
      77                 :          0 :         yroot->setNext (next);
      78         [ #  # ]:          0 :         delete xroot;
      79                 :            :       }
      80                 :            :       else {
      81                 :            :         /* no, handle next vectors */
      82                 :          0 :         next = xroot;
      83                 :          0 :         break;
      84                 :            :       }
      85                 :            :     }
      86                 :            :   }
      87                 :          0 : }
      88                 :            : 
      89                 :            : /* This subroutine checks the size and overall conformance of each
      90                 :            :    touchstone matrix at a given frequency derived from the first
      91                 :            :    matrix.  The function return zero on success and non-zero
      92                 :            :    otherwise. */
      93                 :          0 : static int touchstone_vector_check (void) {
      94                 :          0 :   qucs::vector * root = touchstone_vector, * next;
      95                 :          0 :   int even = 0, errors = 0, size = root->getSize (), noise = 0, lines = 1;
      96                 :          0 :   nr_double_t f = real (root->get (0));
      97                 :            : 
      98                 :            :   /* check size of first line */
      99         [ #  # ]:          0 :   if ((size & 1) == 0) {
     100                 :            :     logprint (LOG_ERROR, "checker error, first data line has %d (even) "
     101                 :          0 :               "values\n", size);
     102                 :          0 :     errors++;
     103                 :          0 :     even = 1;
     104                 :            :   }
     105                 :            :   /* first line determines the number of expected ports */
     106                 :          0 :   touchstone_options.ports = (int) std::sqrt ((size - 1) / 2.0);
     107                 :            : 
     108                 :            :   /* check first frequency value */
     109         [ #  # ]:          0 :   if (f < 0.0) {
     110                 :            :     logprint (LOG_ERROR, "checker error, negative data frequency "
     111                 :          0 :               "value %g\n", f);
     112                 :          0 :     errors++;
     113                 :            :   }
     114                 :            : 
     115                 :            :   /* go through each vector */
     116         [ #  # ]:          0 :   for (root = (qucs::vector *) root->getNext (); root != NULL; root = next) {
     117                 :          0 :     next = (qucs::vector *) root->getNext ();
     118                 :          0 :     nr_double_t freq = real (root->get (0));
     119                 :            : 
     120                 :            :     /* check increasing frequency value */
     121         [ #  # ]:          0 :     if (f >= freq) {
     122         [ #  # ]:          0 :       if (!noise) {
     123                 :            :         /* determined start of noise parameters */
     124                 :          0 :         noise++;
     125                 :          0 :         size = 5;
     126         [ #  # ]:          0 :         if (freq < 0.0) {
     127                 :            :           logprint (LOG_ERROR, "checker error, negative noise frequency "
     128                 :          0 :                     "value %g\n", freq);
     129                 :          0 :           errors++;
     130                 :            :         }
     131                 :            :       }
     132                 :            :       else {
     133                 :            :         logprint (LOG_ERROR, "checker error, %s line (f = %g) has "
     134                 :            :                   "decreasing frequency value\n", noise ? "noise" : "data",
     135         [ #  # ]:          0 :                   freq);
     136                 :          0 :         errors++;
     137                 :            :       }
     138                 :            :     }
     139                 :          0 :     f = freq;
     140                 :            : 
     141                 :            :     /* check size of vector */
     142 [ #  # ][ #  # ]:          0 :     if (!even && root->getSize () != size) {
                 [ #  # ]
     143                 :            :       logprint (LOG_ERROR, "checker error, %s line (f = %g) has %d values, "
     144                 :            :                 "%d required\n", noise ? "noise" : "data",
     145 [ #  # ][ #  # ]:          0 :                 real (root->get (0)), root->getSize (), size);
     146                 :          0 :       errors++;
     147                 :            :     }
     148                 :            : 
     149                 :            :     /* count number of data lines without noise entries */
     150         [ #  # ]:          0 :     if (!noise) lines++;
     151                 :            :   }
     152                 :          0 :   touchstone_options.noise = noise;
     153                 :          0 :   touchstone_options.lines = lines;
     154                 :          0 :   return errors;
     155                 :            : }
     156                 :            : 
     157                 :            : /* The function evaluates the identifiers in the option line and fills
     158                 :            :    the touchstone_options structure with appropriate values. */
     159                 :          0 : static void touchstone_options_eval (void) {
     160                 :            :   /* go through all identifiers */
     161         [ #  # ]:          0 :   for (int i = 0; i < touchstone_idents->length (); i++) {
     162                 :          0 :     char * str = touchstone_idents->get (i);
     163                 :            :     /* frequency unit */
     164         [ #  # ]:          0 :     if (!strcmp (str, "hz")) {
     165                 :          0 :       touchstone_options.factor = 1.0;
     166                 :          0 :       touchstone_options.unit = "Hz";
     167                 :            :     }
     168         [ #  # ]:          0 :     else if (!strcmp (str, "khz")) {
     169                 :          0 :       touchstone_options.factor = 1e3;
     170                 :          0 :       touchstone_options.unit = "kHz";
     171                 :            :     }
     172         [ #  # ]:          0 :     else if (!strcmp (str, "mhz")) {
     173                 :          0 :       touchstone_options.factor = 1e6;
     174                 :          0 :       touchstone_options.unit = "MHz";
     175                 :            :     }
     176         [ #  # ]:          0 :     else if (!strcmp (str, "ghz")) {
     177                 :          0 :       touchstone_options.factor = 1e9;
     178                 :          0 :       touchstone_options.unit = "GHz";
     179                 :            :     }
     180                 :            :     /* parameter type */
     181         [ #  # ]:          0 :     else if (!strcmp (str, "s")) {
     182                 :          0 :       touchstone_options.parameter = 'S';
     183                 :            :     }
     184         [ #  # ]:          0 :     else if (!strcmp (str, "y")) {
     185                 :          0 :       touchstone_options.parameter = 'Y';
     186                 :            :     }
     187         [ #  # ]:          0 :     else if (!strcmp (str, "z")) {
     188                 :          0 :       touchstone_options.parameter = 'Z';
     189                 :            :     }
     190         [ #  # ]:          0 :     else if (!strcmp (str, "g")) {
     191                 :          0 :       touchstone_options.parameter = 'G';
     192                 :            :     }
     193         [ #  # ]:          0 :     else if (!strcmp (str, "h")) {
     194                 :          0 :       touchstone_options.parameter = 'H';
     195                 :            :     }
     196                 :            :     /* value formats */
     197         [ #  # ]:          0 :     else if (!strcmp (str, "ma")) {
     198                 :          0 :       touchstone_options.format = "MA";
     199                 :            :     }
     200         [ #  # ]:          0 :     else if (!strcmp (str, "db")) {
     201                 :          0 :       touchstone_options.format = "dB";
     202                 :            :     }
     203         [ #  # ]:          0 :     else if (!strcmp (str, "ri")) {
     204                 :          0 :       touchstone_options.format = "RI";
     205                 :            :     }
     206                 :            :   }
     207                 :          0 : }
     208                 :            : 
     209                 :            : /* This little function returns a static string containing an
     210                 :            :    appropriate variable name. */
     211                 :          0 : static char * touchstone_create_set (int r, int c) {
     212                 :            :   char * text;
     213                 :          0 :   text = matvec::createMatrixString (touchstone_options.parameter, r, c);
     214                 :          0 :   return text;
     215                 :            : }
     216                 :            : 
     217                 :            : /* The function actually creates the resulting dataset. */
     218                 :          0 : static void touchstone_create (void) {
     219                 :          0 :   qucs::vector * f, * v, * root, * next, * nf = NULL;
     220                 :          0 :   int ports = touchstone_options.ports, n;
     221                 :          0 :   nr_complex_t val;
     222                 :            :   strlist * s;
     223                 :            : 
     224                 :            :   /* create dataset and frequency vector */
     225 [ #  # ][ #  # ]:          0 :   touchstone_result = new dataset ();
     226 [ #  # ][ #  # ]:          0 :   f = new qucs::vector ("frequency");
     227         [ #  # ]:          0 :   touchstone_result->appendDependency (f);
     228 [ #  # ][ #  # ]:          0 :   s = new strlist ();
     229         [ #  # ]:          0 :   s->add (f->getName ());
     230                 :            :   /* create variable vectors for the resulting dataset */
     231         [ #  # ]:          0 :   for (int r = 0; r < ports; r++) {
     232         [ #  # ]:          0 :     for (int c = 0; c < ports; c++) {
     233 [ #  # ][ #  # ]:          0 :       v = new qucs::vector ();
     234 [ #  # ][ #  # ]:          0 :       v->setName (touchstone_create_set (r, c));
     235 [ #  # ][ #  # ]:          0 :       v->setDependencies (new strlist (*s));
                 [ #  # ]
     236         [ #  # ]:          0 :       touchstone_result->appendVariable (v);
     237                 :            :     }
     238                 :            :   }
     239 [ #  # ][ #  # ]:          0 :   delete s;
     240                 :            : 
     241                 :            :   /* create noise vectors if necessary */
     242         [ #  # ]:          0 :   if (touchstone_options.noise) {
     243 [ #  # ][ #  # ]:          0 :     nf = new qucs::vector ("nfreq");
     244         [ #  # ]:          0 :     touchstone_result->appendDependency (nf);
     245 [ #  # ][ #  # ]:          0 :     s = new strlist ();
     246         [ #  # ]:          0 :     s->add (nf->getName ());
     247                 :            :     /* append noise parameters to dataset */
     248 [ #  # ][ #  # ]:          0 :     v = new qucs::vector ("Fmin");
     249 [ #  # ][ #  # ]:          0 :     v->setDependencies (new strlist (*s));
                 [ #  # ]
     250         [ #  # ]:          0 :     touchstone_result->appendVariable (v);
     251 [ #  # ][ #  # ]:          0 :     v = new qucs::vector ("Sopt");
     252 [ #  # ][ #  # ]:          0 :     v->setDependencies (new strlist (*s));
                 [ #  # ]
     253         [ #  # ]:          0 :     touchstone_result->appendVariable (v);
     254 [ #  # ][ #  # ]:          0 :     v = new qucs::vector ("Rn");
     255 [ #  # ][ #  # ]:          0 :     v->setDependencies (new strlist (*s));
                 [ #  # ]
     256         [ #  # ]:          0 :     touchstone_result->appendVariable (v);
     257 [ #  # ][ #  # ]:          0 :     delete s;
     258                 :            :   }
     259                 :            : 
     260                 :            :   /* go through each vector */
     261         [ #  # ]:          0 :   for (n = 0, root = touchstone_vector; root != NULL; root = next, n++) {
     262                 :          0 :     next = (qucs::vector *) root->getNext ();
     263                 :            :     // handle data lines
     264         [ #  # ]:          0 :     if (n < touchstone_options.lines) {
     265                 :            :       /* fill frequency vector */
     266 [ #  # ][ #  # ]:          0 :       f->add (real (root->get (0)) * touchstone_options.factor);
     267                 :            :       /* go through each variable vector */
     268                 :          0 :       v = touchstone_result->getVariables ();
     269         [ #  # ]:          0 :       for (int i = 0; i < ports; i++) {
     270         [ #  # ]:          0 :         for (int j = 0; j < ports; j++) {
     271                 :          0 :           int pos = 1 + j * 2 + i * 2 * ports;
     272                 :            :           /* handle special case for 2-port touchstone data, '21' data
     273                 :            :              precedes the '12' data */
     274 [ #  # ][ #  # ]:          0 :           if (ports == 2 && i != j) {
     275                 :          0 :             pos = 1 + i * 2 + j * 2 * ports;
     276                 :            :           }
     277                 :            :           /* depending on the touchstone data format */
     278         [ #  # ]:          0 :           if (!strcmp (touchstone_options.format, "RI")) {
     279                 :            :             val = nr_complex_t (real (root->get (pos + 0)),
     280 [ #  # ][ #  # ]:          0 :                         real (root->get (pos + 1)));
     281                 :            :           }
     282         [ #  # ]:          0 :           else if (!strcmp (touchstone_options.format, "MA")) {
     283                 :            :             val = qucs::polar (real (root->get (pos + 0)),
     284 [ #  # ][ #  # ]:          0 :                          rad (real (root->get (pos + 1))));
                 [ #  # ]
     285                 :            :           }
     286         [ #  # ]:          0 :           else if (!strcmp (touchstone_options.format, "dB")) {
     287         [ #  # ]:          0 :             val = qucs::polar (std::pow (10.0, real (root->get (pos + 0)) / 20.0),
     288 [ #  # ][ #  # ]:          0 :                          rad (real (root->get (pos + 1))));
     289                 :            :           }
     290         [ #  # ]:          0 :           v->add (val);
     291                 :          0 :           v = (qucs::vector *) v->getNext ();
     292                 :            :         }
     293                 :            :       }
     294                 :            :     }
     295                 :            :     // handle noise lines
     296         [ #  # ]:          0 :     else if (touchstone_options.noise) {
     297                 :            :       /* fill frequency vector */
     298 [ #  # ][ #  # ]:          0 :       nf->add (real (root->get (0)) * touchstone_options.factor);
     299                 :            :       /* fill minimum noise figure vector */
     300         [ #  # ]:          0 :       v = touchstone_result->findVariable ("Fmin");
     301         [ #  # ]:          0 :       val = std::pow (10.0, real (root->get (1)) / 10.0);
     302         [ #  # ]:          0 :       v->add (val);
     303                 :            :       /* fill optimal noise reflexion coefficient vector */
     304         [ #  # ]:          0 :       v = touchstone_result->findVariable ("Sopt");
     305 [ #  # ][ #  # ]:          0 :       val = qucs::polar (real (root->get (2)), rad (real (root->get (3))));
                 [ #  # ]
     306         [ #  # ]:          0 :       if (ZREF != touchstone_options.resistance) {
     307                 :            :         // re-normalize reflexion coefficient if necessary
     308                 :            :         nr_double_t r = (ZREF - touchstone_options.resistance) /
     309                 :          0 :           (ZREF + touchstone_options.resistance);
     310         [ #  # ]:          0 :         val = (val - r) / (1.0 - r * val);
     311                 :            :       }
     312         [ #  # ]:          0 :       v->add (val);
     313                 :            :       /* fill equivalent noise resistance vector */
     314         [ #  # ]:          0 :       v = touchstone_result->findVariable ("Rn");
     315         [ #  # ]:          0 :       val = real (root->get (4)) * touchstone_options.resistance;
     316         [ #  # ]:          0 :       v->add (val);
     317                 :            :     }
     318                 :            :   }
     319                 :          0 : }
     320                 :            : 
     321                 :            : /* The function re-normalizes S-parameters to the internal reference
     322                 :            :    impedance 50 Ohms. */
     323                 :          0 : static void touchstone_normalize_sp (void) {
     324                 :          0 :   int ports = touchstone_options.ports;
     325                 :          0 :   qucs::vector * v = touchstone_result->getVariables ();
     326         [ #  # ]:          0 :   int i, j, n, len = v->getSize ();
     327         [ #  # ]:          0 :   matrix s = matrix (ports);
     328                 :            : 
     329                 :            :   // go through each matrix entry
     330         [ #  # ]:          0 :   for (n = 0; n < len; n++) {
     331                 :          0 :     v = touchstone_result->getVariables ();
     332                 :            :     // save entries in a temporary matrix
     333         [ #  # ]:          0 :     for (i = 0; i < ports; i++) {
     334         [ #  # ]:          0 :       for (j = 0; j < ports; j++) {
     335 [ #  # ][ #  # ]:          0 :         s.set (i, j, v->get (n));
     336                 :          0 :         v = (qucs::vector *) v->getNext ();
     337                 :            :       }
     338                 :            :     }
     339                 :            :     // convert the temporary matrix
     340 [ #  # ][ #  # ]:          0 :     s = stos (s, touchstone_options.resistance, ZREF);
         [ #  # ][ #  # ]
                 [ #  # ]
     341                 :          0 :     v = touchstone_result->getVariables ();
     342                 :            :     // restore the results in the entries
     343         [ #  # ]:          0 :     for (i = 0; i < ports; i++) {
     344         [ #  # ]:          0 :       for (j = 0; j < ports; j++) {
     345 [ #  # ][ #  # ]:          0 :         v->set (s.get (i, j), n);
     346                 :          0 :         v = (qucs::vector *) v->getNext ();
     347                 :            :       }
     348                 :            :     }
     349         [ #  # ]:          0 :   }
     350                 :          0 : }
     351                 :            : 
     352                 :            : /* The function transforms the reference impedance given in the
     353                 :            :    touchstone file to the internal reference impedance 50 Ohms. */
     354                 :          0 : static void touchstone_normalize (void) {
     355                 :          0 :   qucs::vector * v = touchstone_result->getVariables ();
     356                 :          0 :   int ports = touchstone_options.ports;
     357                 :            : 
     358                 :            :   // transform S-parameters if necessary
     359         [ #  # ]:          0 :   if (touchstone_options.parameter == 'S') {
     360         [ #  # ]:          0 :     if (touchstone_options.resistance != ZREF)
     361                 :          0 :       touchstone_normalize_sp ();
     362                 :          0 :     return;
     363                 :            :   }
     364                 :            :   // transform any other X-parameters
     365         [ #  # ]:          0 :   for (int i = 1; i <= ports; i++) {
     366         [ #  # ]:          0 :     for (int j = 1; j <= ports; j++) {
     367   [ #  #  #  #  :          0 :       switch (touchstone_options.parameter) {
                      # ]
     368                 :            :       case 'Y': // Y-parameters
     369                 :          0 :         *v /= touchstone_options.resistance;
     370                 :          0 :         break;
     371                 :            :       case 'Z': // Z-parameters
     372                 :          0 :         *v *= touchstone_options.resistance;
     373                 :          0 :         break;
     374                 :            :       case 'G': // hybrid G-parameters
     375 [ #  # ][ #  # ]:          0 :         if (i == 1 && j == 1)
     376                 :          0 :           *v /= touchstone_options.resistance;
     377 [ #  # ][ #  # ]:          0 :         else if (i == 2 && j == 2)
     378                 :          0 :           *v *= touchstone_options.resistance;
     379                 :          0 :         break;
     380                 :            :       case 'H': // hybrid H-parameters
     381 [ #  # ][ #  # ]:          0 :         if (i == 1 && j == 1)
     382                 :          0 :           *v *= touchstone_options.resistance;
     383 [ #  # ][ #  # ]:          0 :         else if (i == 2 && j == 2)
     384                 :          0 :           *v /= touchstone_options.resistance;
     385                 :          0 :         break;
     386                 :            :       }
     387                 :          0 :       v = (qucs::vector *) v->getNext ();
     388                 :            :     }
     389                 :            :   }
     390                 :            : }
     391                 :            : 
     392                 :            : /* Removes temporary data items from memory if necessary. */
     393                 :          0 : static void touchstone_finalize (void) {
     394                 :            :   qucs::vector * root, * next;
     395         [ #  # ]:          0 :   for (root = touchstone_vector; root != NULL; root = next) {
     396                 :          0 :     next = (qucs::vector *) root->getNext ();
     397         [ #  # ]:          0 :     delete root;
     398                 :            :   }
     399                 :          0 :   touchstone_vector = NULL;
     400         [ #  # ]:          0 :   if (touchstone_idents != NULL) {
     401         [ #  # ]:          0 :     delete touchstone_idents;
     402                 :          0 :     touchstone_idents = NULL;
     403                 :            :   }
     404                 :          0 :   touchstone_lex_destroy ();
     405                 :            :   /* apply default values again */
     406                 :          0 :   touchstone_options.unit = "GHz";
     407                 :          0 :   touchstone_options.parameter = 'S';
     408                 :          0 :   touchstone_options.format = "MA";
     409                 :          0 :   touchstone_options.resistance = 50.0;
     410                 :          0 :   touchstone_options.factor = 1e9;
     411                 :          0 :   touchstone_options.ports = 0;
     412                 :          0 :   touchstone_options.noise = 0;
     413                 :          0 :   touchstone_options.lines = 0;
     414                 :          0 : }
     415                 :            : 
     416                 :            : 
     417                 :            : /* This function is the checker routine for a parsed touchstone.  It
     418                 :            :    returns zero on success or non-zero if the parsed touchstone
     419                 :            :    contained errors. */
     420                 :          0 : int touchstone_check (void) {
     421                 :            : 
     422                 :          0 :   int i, n, errors = 0;
     423                 :            : 
     424                 :            :   /* first checking the options */
     425         [ #  # ]:          0 :   if (touchstone_idents->length () > 3) {
     426                 :            :     logprint (LOG_ERROR, "checker error, found %d options\n",
     427                 :          0 :               touchstone_idents->length ());
     428                 :          0 :     errors++;
     429                 :            :   }
     430                 :            :   /* touchstone is case insensitive */
     431         [ #  # ]:          0 :   for (i = 0; i < touchstone_idents->length (); i++) {
     432         [ #  # ]:          0 :     for (char * p = touchstone_idents->get (i); *p != '\0'; p++)
     433                 :          0 :       *p = tolower (*p);
     434                 :            :   }
     435                 :            :   /* check duplicate options */
     436         [ #  # ]:          0 :   for (i = 0; i < touchstone_idents->length (); i++) {
     437                 :          0 :     char * str = touchstone_idents->get (i);
     438         [ #  # ]:          0 :     if ((n = touchstone_idents->contains (str)) != 1) {
     439                 :            :       logprint (LOG_ERROR, "checker error, option `%s' occurred %dx\n",
     440                 :          0 :                 str, n);
     441                 :          0 :       errors++;
     442                 :            :     }
     443                 :            :   }
     444                 :            :   /* check valid options */
     445         [ #  # ]:          0 :   for (i = 0; i < touchstone_idents->length (); i++) {
     446                 :          0 :     char * str = touchstone_idents->get (i);
     447                 :          0 :     int valid = 0;
     448         [ #  # ]:          0 :     for (int v = 0; touchstone_valid_options[v] != NULL; v++) {
     449         [ #  # ]:          0 :       if (!strcmp (touchstone_valid_options[v], str))
     450                 :          0 :         valid = 1;
     451                 :            :     }
     452         [ #  # ]:          0 :     if (!valid) {
     453                 :          0 :       logprint (LOG_ERROR, "checker error, invalid option `%s'\n", str);
     454                 :          0 :       errors++;
     455                 :            :     }
     456                 :            :   }
     457                 :            : 
     458                 :            :   /* evaluate the option line and put values into touchstone_options
     459                 :            :      structure */
     460                 :          0 :   touchstone_options_eval ();
     461                 :            : 
     462         [ #  # ]:          0 :   if (touchstone_vector == NULL) {
     463                 :          0 :     logprint (LOG_ERROR, "checker error, no data in touchstone file\n");
     464                 :          0 :     errors++;
     465                 :            :   }
     466                 :            :   else {
     467                 :            :     /* join vectors on multiple lines */
     468                 :          0 :     touchstone_join ();
     469                 :            : 
     470                 :            :     /* check each vector */
     471                 :          0 :     errors += touchstone_vector_check ();
     472                 :            : 
     473                 :            :     /* check validity of ports and parameters */
     474 [ #  # ][ #  # ]:          0 :     if ((touchstone_options.parameter == 'G' ||
                 [ #  # ]
     475                 :            :          touchstone_options.parameter == 'H') &&
     476                 :            :         touchstone_options.ports != 2) {
     477                 :            :       logprint (LOG_ERROR, "checker error, %c-parameters for %d-ports not "
     478                 :            :                 "defined\n", touchstone_options.parameter,
     479                 :          0 :                 touchstone_options.ports);
     480                 :          0 :       errors++;
     481                 :            :     }
     482                 :            : 
     483                 :            :     /* check noise parameter compatibility */
     484 [ #  # ][ #  # ]:          0 :     if (touchstone_options.noise && touchstone_options.ports != 2) {
     485                 :            :       logprint (LOG_ERROR, "checker error, noise parameters for %d-ports not "
     486                 :          0 :                 "defined\n", touchstone_options.ports);
     487                 :          0 :       errors++;
     488                 :            :     }
     489                 :            :   }
     490                 :            : 
     491                 :            :   /* finally create a dataset */
     492         [ #  # ]:          0 :   if (!errors) {
     493                 :          0 :     touchstone_create ();
     494                 :          0 :     touchstone_normalize ();
     495                 :            :   }
     496                 :            : 
     497                 :            : #if DEBUG
     498                 :            :   /* emit little notify message on successful loading */
     499         [ #  # ]:          0 :   if (!errors) {
     500                 :            :     logprint (LOG_STATUS, "NOTIFY: touchstone %d-port %c-data%s loaded\n",
     501                 :            :               touchstone_options.ports, touchstone_options.parameter,
     502         [ #  # ]:          0 :               touchstone_options.noise ? " including noise" : "");
     503                 :            :   }
     504                 :            : #endif
     505                 :            : 
     506                 :            :   /* free temporary memory */
     507                 :          0 :   touchstone_finalize ();
     508                 :            : 
     509         [ #  # ]:          0 :   return errors ? -1 : 0;
     510                 :            : }
     511                 :            : 
     512                 :            : // Destroys data used by the Touchstone file lexer, parser and checker.
     513                 :          0 : void touchstone_destroy (void) {
     514         [ #  # ]:          0 :   if (touchstone_result != NULL) {
     515                 :            :     // delete associated dataset
     516         [ #  # ]:          0 :     delete touchstone_result;
     517                 :          0 :     touchstone_result = NULL;
     518                 :            :   }
     519         [ #  # ]:          0 :   if (touchstone_vector != NULL) {
     520                 :          0 :     touchstone_finalize ();
     521                 :          0 :     touchstone_vector = NULL;
     522                 :            :   }
     523                 :          0 : }
     524                 :            : 
     525                 :            : // Initializes the Touchstone file checker.
     526                 :          0 : void touchstone_init (void) {
     527                 :          0 :   touchstone_result = NULL;
     528                 :          0 :   touchstone_vector = NULL;
     529                 :          0 :   touchstone_idents = NULL;
     530                 :          0 : }

Generated by: LCOV version 1.11