desc.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002 
00003     BUFR encoding and decoding software and library
00004     Copyright (c) 2007,  Institute of Broadband Communication, TU-Graz
00005     on behalf of EUMETNET OPERA, http://www.knmi.nl/opera
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; version 2.1 
00010     of the License.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
00020 
00021 ----------------------------------------------------------------------------
00022 
00023 FILE:          READDESC.C
00024 IDENT:         $Id: desc.c,v 1.14 2007/12/18 14:40:13 fuxi Exp $
00025 
00026 AUTHOR:        Konrad Koeck
00027                Institute of Communication and Wave Propagation, 
00028                Technical University Graz, Austria
00029 
00030 VERSION NUMBER:3.0
00031 
00032 DATE CREATED:  18-DEC-2001
00033 
00034 STATUS:        DEVELOPMENT FINISHED
00035 
00036 
00037 FUNCTIONAL DESCRIPTION:
00038 -----------------------
00039 Function(s) for reading the descriptor-file.
00040 
00041 AMENDMENT RECORD:
00042 
00043 ISSUE       DATE            SCNREF      CHANGE DETAILS
00044 -----       ----            ------      --------------
00045 V2.0        18-DEC-2001     Koeck       Initial Issue
00046 
00047 $Log: desc.c,v $
00048 Revision 1.14  2007/12/18 14:40:13  fuxi
00049 added licence header
00050 
00051 Revision 1.13  2007/12/07 08:39:15  fuxi
00052 update to version 3.0
00053 
00054 Revision 1.12  2005/04/04 15:31:35  helmutp
00055 update to version 2.3
00056 
00057 Revision 1.11  2004/09/28 12:14:00  helmutp
00058 fixed fclose and free
00059 
00060 Revision 1.10  2003/09/04 08:07:19  helmutp
00061 add / or \ to directory name
00062 
00063 Revision 1.9  2003/06/11 09:33:19  helmutp
00064 changed key calculation
00065 
00066 Revision 1.8  2003/06/11 09:02:57  helmutp
00067 remove duplicate entries from desc table (local table overruling)
00068 fixed read_tab_d EOF handling, changed name of master table
00069 
00070 Revision 1.7  2003/06/06 11:59:32  helmutp
00071 changed read_tables to support table versions
00072 
00073 Revision 1.6  2003/03/27 17:17:39  helmutp
00074 update to version 2.2
00075 
00076 Revision 1.5  2003/03/13 17:17:48  helmutp
00077 fixed argc and indentation
00078 
00079 Revision 1.4  2003/03/13 17:08:47  helmutp
00080 added search key, use sorted descriptors and bsearch instead of linear search
00081 allow tables to be specified on commndline
00082 
00083 Revision 1.3  2003/03/11 10:30:42  helmutp
00084 fixed memory leaks
00085 
00086 Revision 1.2  2003/03/06 17:12:32  helmutp
00087 update to version 2.1
00088 
00089 Revision 1.1  2003/02/28 13:41:12  helmutp
00090 Initial revision
00091 
00092 --------------------------------------------------------------------------- */
00093 
00101 #define READDESC_MAIN
00102 
00103 #define DESC_SORT
00104 
00105 #include <stdio.h>
00106 #include <stdlib.h>
00107 #include <string.h>
00108 #include <assert.h>
00109 #include <ctype.h>
00110 #include "desc.h"
00111 
00112 /*===========================================================================*/
00113 /* internal functions                                                        */
00114 /*===========================================================================*/
00115 
00116 static del *decode_tabb_line (char *line);
00117 static char *get_val (char *line, int num);
00118 static dseq *decode_tabd_line (char *line);
00119 static void replace_chars (char *line, char oldc, char newc);
00120 static int key (int typ, dd* d);
00121 static void build_keys();
00122 static void print_desc(int i);
00123 static void free_one_desc(int i);
00124 static char *str_lower(char *str);
00125 
00126 
00127 /*===========================================================================*/
00128 
00155 int read_tables (char *dir, int vmtab, int vltab, int subcent, int gencent)
00156 {
00157     char fn[1024];
00158 #if defined(_WIN32)
00159     char *sep = "\\";
00160 #else
00161     char *sep = "/";
00162 #endif
00163 
00164     if (dir == NULL)
00165         dir = "";
00166 
00167     if (strlen(dir) == 0 || dir[strlen(dir) -1] == '/' || 
00168         dir[strlen(dir) -1] == '\\')
00169         sep = "";
00170 
00171     sprintf (fn, "%s%sbufrtabb_%d.csv", dir, sep, vmtab);
00172     if (!read_tab_b (fn)) 
00173     {
00174         fprintf (stderr, "Error: unable to read master BUFR Table B !\n");
00175         return -1;
00176     }
00177     
00178     sprintf (fn, "%s%sbufrtabd_%d.csv", dir, sep, vmtab);
00179     if (!read_tab_d (fn)) 
00180     {
00181         fprintf (stderr, "Error: unable to read master BUFR Table D !\n");
00182         return -1;
00183     }
00184     
00185     sprintf (fn, "%s%slocaltabb_%d_%d.csv", dir, sep, 
00186              subcent * 256 + gencent, vltab);
00187     if (!read_tab_b (fn)) 
00188         fprintf (stderr, "Warning: unable to read local BUFR Table B !\n");
00189     
00190     sprintf (fn, "%s%slocaltabd_%d_%d.csv", dir, sep, 
00191              subcent * 256 + gencent, vltab);
00192     if (!read_tab_d (fn)) 
00193         fprintf (stderr, "Warning: unable to read local BUFR Table D !\n");
00194 
00195     return 0;
00196 }
00197 
00198 /*===========================================================================*/
00199 
00210 void show_desc (int f, int x, int y)
00211 {
00212     if (f == 999)
00213     {
00214         for (f = 0; f < ndes; f++)
00215             print_desc (f);
00216     }
00217     else if (f >= 0 && x >= 0 && y >= 0)
00218     {
00219         int i;
00220         dd d;
00221         d.f = f;
00222         d.x = x;
00223         d.y = y;
00224         if ((i = get_index (SEQDESC, &d)) >= 0)
00225             print_desc (i);
00226         else if ((i = get_index (ELDESC, &d)) >= 0)
00227             print_desc (i);
00228         else
00229             fprintf (stderr, "Descriptor %d %d %d not found !\n", f, x, y);
00230     }
00231 }
00232 
00233 /*===========================================================================*/
00234 
00235 /* Print the descriptor at index i */
00236 
00237 static void print_desc(int i)
00238 {
00239     if (i < 0 || i >= ndes) return;
00240 
00241     if (des[i]->id == ELDESC)
00242     {
00243         del *d = des[i]->el;
00244         printf ("%d %02d %03d %2d %2d  %s  %s   [%d, %d]\n", d->d.f, d->d.x, d->d.y,
00245                 d->scale, d->dw, d->unit, d->elname, i, des[i]->nr);
00246     }
00247     else
00248     {
00249         int j;
00250         dseq *d = des[i]->seq;
00251         printf ("%d %02d %03d  %d %02d %03d   [%d, %d]\n", d->d.f, d->d.x, d->d.y,
00252                 d->del[0].f, d->del[0].x, d->del[0].y, i, des[i]->nr);
00253         for (j = 1; j < d->nel; j++)
00254             printf ("          %d %02d %03d\n", d->del[j].f, d->del[j].x, d->del[j].y);
00255     }
00256 }
00257 
00258 /*===========================================================================*/
00259 
00260 /* Compare key calculation */
00261 
00262 static int key (int typ, dd* d)
00263 {
00264     return (typ << 24) + (d->f << 16) + (d->x << 8) + d->y;
00265 }
00266 
00267 /* Descriptor compare function (for qsort) */ 
00268 
00269 #ifdef DESC_SORT
00270 static int dcmp (const void *p1, const void *p2)
00271 {
00272     desc *d1 = *(desc **) p1;
00273     desc *d2 = *(desc **) p2;
00274     
00275     return d1->key - d2->key;
00276 }
00277 #endif
00278 
00279 /* Create sort keys and sort the descriptor table, 
00280    remove duplicate entries (local table overruling) */
00281 
00282 static void build_keys()
00283 {
00284     int i, n;
00285     if (ndes == 0)
00286         return;
00287 
00288     for (i = 0; i < ndes; i++)
00289     {
00290         if (des[i]->id == ELDESC)
00291             des[i]->key = key (des[i]->id, &des[i]->el->d);
00292         if (des[i]->id == SEQDESC)
00293             des[i]->key = key (des[i]->id, &des[i]->seq->d);
00294     }
00295 
00296 #ifdef DESC_SORT
00297 
00298     /* sort descriptors and remove duplicates */
00299     /* keep decsriptor with higher serial number */
00300     
00301     qsort (des, ndes, sizeof (desc *), dcmp);
00302 
00303     for (i = 1, n = 0; i < ndes; i++)
00304     {
00305         if (des[n]->key == des[i]->key)
00306         {
00307             if (des[i]->nr > des[n]->nr)
00308             {
00309                 free_one_desc (n);
00310                 des[n] = des[i];
00311             }
00312             else
00313                 free_one_desc (i);
00314         }
00315         else
00316             des[++n] = des[i];
00317     }
00318     ndes = n + 1;
00319 
00320 #endif
00321 }
00322 
00323 /*===========================================================================*/
00324 
00337 int get_index (int typ, dd* descr)
00338 {
00339 #ifdef DESC_SORT
00340 
00341     int i1 = 0;
00342     int i2 = ndes -1;
00343     int k = key (typ, descr);
00344 
00345     while (i2 >= i1)
00346     {
00347         int i = (i2 + i1) / 2;
00348             int diff = des[i]->key - k;
00349         if (diff == 0)
00350             return i;
00351         if (diff < 0)
00352             i1 = i + 1;
00353         else
00354             i2 = i - 1;
00355     }
00356     return -1;
00357 
00358 #else
00359 
00360   int i;
00361   int k = key (typ, descr);
00362   for (i = 0; i < ndes; i ++) 
00363   {
00364       if (des[i]->key == k)
00365         return i;
00366   }
00367   return -1;
00368 
00369 #endif
00370 }
00371 
00372 /*===========================================================================*/
00388 int read_tab_d (char *fname)
00389 
00390 {
00391     FILE *fp;
00392     char line[1000], *l;
00393     dseq *sdesc;
00394     int end;
00395 
00396     /* Open input file */
00397 
00398     fp = fopen (fname, "r");
00399     if (fp == NULL) {
00400         fprintf (stderr, "unable to open '%s'\n", fname);
00401         return 0;
00402     }
00403 
00404 /* Run through all lines and decode the ones that contain reasonable data */
00405 
00406     end = 0;
00407     do {
00408         if ((l = fgets (line, 1000, fp)) != NULL)
00409         {
00410             /* For some reasons the '-' is not correct stored in the csv file */
00411             replace_chars (l, -105, 45); 
00412             replace_chars (l, -106, 45);
00413         }
00414 
00415         sdesc = decode_tabd_line (l);
00416         if (sdesc != NULL) {
00417             des[ndes] = malloc (sizeof (desc));
00418             if (des[ndes] == NULL) {
00419                 fprintf (stderr, "Memory allocation error.\n");
00420                 fclose (fp);
00421                 return 0;
00422             }
00423             des[ndes]->id = SEQDESC;
00424             des[ndes]->nr = ndes;
00425             des[ndes]->seq = sdesc;
00426             des[ndes]->el = NULL;
00427             ndes ++;
00428             if (ndes >= MAXDESC) {
00429                 fprintf (stderr, "Parameter MAXDESC exceeded.\n");
00430                 fclose (fp);
00431                 return 0;
00432             }
00433         }
00434     } while (l != NULL);
00435 
00436     fclose (fp);
00437 
00438     build_keys();
00439     return 1;
00440 }
00441 
00442 /*===========================================================================*/
00443 static dseq *decode_tabd_line (char *line)
00444 
00445 /* Decodes a single Table D Line and returns a pointer to a dseq-structure
00446          holding the data that has been decoded. The memory area must be
00447          freed by the calling function
00448 */
00449 
00450 {
00451 /* Get the first 6 strings of the line, each of them separated by a ';'
00452 */
00453 
00454     char *sf, *sx, *sy, *dx, *dy, *df;
00455     int isf, isx, isy, idx, idy, idf;
00456     static dseq *seq = NULL;           /* Holds the current Sequence Descriptor */
00457     dseq *ret = NULL;
00458     dd *ddp;
00459     char tmp[1000];
00460 
00461     if (line == NULL)
00462     {
00463         ret = seq;
00464         seq = NULL;
00465         return ret;
00466     }
00467 
00468     strcpy (tmp, line);
00469 
00470     dy = get_val (line, 5);
00471     dx = get_val (line, 4);
00472     df = get_val (line, 3);
00473     sy = get_val (line, 2);
00474     sx = get_val (line, 1);
00475     sf = get_val (line, 0);
00476 
00477 /* CHeck for valid values */
00478 
00479     if (dy == NULL ||
00480         dx == NULL ||
00481         df == NULL ||
00482         sy == NULL ||
00483         sx == NULL ||
00484         sf == NULL) return NULL;
00485 
00486     if (sscanf (sf, "%d", &isf) != 1) isf = 0;
00487     if (sscanf (sx, "%d", &isx) != 1) isx = 0;
00488     if (sscanf (sy, "%d", &isy) != 1) isy = 0;
00489     if (sscanf (df, "%d", &idf) != 1) idf = 0;
00490     if (sscanf (dx, "%d", &idx) != 1) idx = 0;
00491     if (sscanf (dy, "%d", &idy) != 1) idy = 0;
00492 
00493 /* Check if there is a new seqence descriptor */
00494 
00495     if (isf == 3 || isx != 0 || isy != 0) {
00496         if (seq != NULL) {
00497             ret = seq;       /* This is what we return */
00498         }
00499         seq = malloc (sizeof (dseq));
00500         if (seq == NULL) {
00501             fprintf (stderr, "Memory allocation error !\n");
00502             return NULL;
00503         }
00504         seq->d.f = isf;
00505         seq->d.x = isx;
00506         seq->d.y = isy;
00507         seq->nel = 0;
00508         seq->del = malloc (sizeof (dd));
00509         if (seq->del == NULL) {
00510             fprintf (stderr, "Memory allocation error !\n");
00511             return NULL;
00512         }
00513     }
00514 
00515 /* Get the new entry for the sequence */
00516 
00517     if ((idf != 0 || idx != 0 || idy != 0) && seq != NULL) {
00518         seq->del = realloc (seq->del, (seq->nel + 1) * sizeof (dd));
00519         if (seq->del == NULL) {
00520             fprintf (stderr, "Memory allocation error !\n");
00521             return NULL;
00522         }
00523         ddp = seq->del + seq->nel;
00524         ddp->f = idf;
00525         ddp->x = idx;
00526         ddp->y = idy;
00527         seq->nel += 1;
00528     }
00529 
00530     return ret;
00531 }
00532 
00533 /*===========================================================================*/
00549 int read_tab_b (char *fname)
00550 
00551 {
00552     FILE *fp;
00553     char line[1000];
00554     del *descr;
00555 
00556     /* Open input file */
00557 
00558     fp = fopen (fname, "r");
00559     if (fp == NULL) {
00560         fprintf (stderr, "unable to open '%s'\n", fname);
00561         return 0;
00562     }
00563 
00564     /* Run through all lines and decode the ones that contain reasonable data*/
00565 
00566     while (fgets (line, 1000, fp) != NULL) {
00567         replace_chars (line, -106, 45); /* For some reasons the '-' is not correct stored in the csv file */
00568         replace_chars (line, -105, 45); /* For some reasons the '-' is not correct stored in the csv file */
00569         descr = decode_tabb_line (line);
00570         if (descr != NULL) {
00571             des[ndes] = malloc (sizeof (desc));
00572             if (des[ndes] == NULL) {
00573                 fprintf (stderr, "Memory allocation error.\n");
00574                 fclose (fp);
00575                 return 0;
00576             }
00577             des[ndes]->id = ELDESC;
00578             des[ndes]->nr = ndes;
00579             des[ndes]->el = descr;
00580             des[ndes]->seq = NULL;
00581             ndes ++;
00582             if (ndes >= MAXDESC) {
00583                 fprintf (stderr, "Parameter MAXDESC exceeded.\n");
00584                 fclose (fp);
00585                 return 0;
00586             }
00587         }
00588     }
00589 
00590     fclose (fp);
00591 
00592     /* Finally we add a dummy descriptor describing a single character 
00593        in a CCITT IA5 character string */
00594 
00595     if (ccitt_special == 0) {
00596         ccitt_special = MAXDESC + 1;
00597         descr = decode_tabb_line ("9999;9999;9999;tmp;value;0;0;8;tmp;0;3");
00598         if (descr != NULL) {
00599             des[ccitt_special] = malloc (sizeof (desc));
00600             if (des[ccitt_special] == NULL) {
00601                 fprintf (stderr, "Memory allocation error.\n");
00602                 return 0;
00603             }
00604             des[ccitt_special]->id = ELDESC;
00605             des[ccitt_special]->nr = ccitt_special;
00606             des[ccitt_special]->el = descr;
00607             des[ccitt_special]->seq = NULL;
00608         }
00609     }
00610 
00611     /* The same we need for a dummy for saving a change in the 
00612        reference value */
00613 
00614     if (cf_special == 0) {
00615         cf_special = MAXDESC + 2;
00616         descr = decode_tabb_line ("9999;9999;9998;tmp;value;0;0;8;tmp;0;3");
00617         if (descr != NULL) {
00618             des[cf_special] = malloc (sizeof (desc));
00619             if (des[cf_special] == NULL) {
00620                 fprintf (stderr, "Memory allocation error.\n");
00621                 return 0;
00622             }
00623             des[cf_special]->id = ELDESC;
00624             des[cf_special]->nr = cf_special;
00625             des[cf_special]->el = descr;
00626             des[cf_special]->seq = NULL;
00627         }
00628     }
00629 
00630     /* dummy descriptor for the associated field */
00631 
00632     if (add_f_special == 0) {
00633         add_f_special = MAXDESC + 3;
00634         descr = decode_tabb_line ("0;0;0;Associated Field;value;0;0;0;tmp;0;0");
00635         if (descr != NULL) {
00636             des[add_f_special] = malloc (sizeof (desc));
00637             if (des[add_f_special] == NULL) {
00638                 fprintf (stderr, "Memory allocation error.\n");
00639                 return 0;
00640             }
00641             des[add_f_special]->id = ELDESC;
00642             des[add_f_special]->nr = add_f_special;
00643             des[add_f_special]->el = descr;
00644             des[add_f_special]->seq = NULL;
00645         }
00646     }
00647 
00648     /* dummy descriptor for no data output */
00649     
00650     if (_desc_special == 0) {
00651         _desc_special = MAXDESC + OPTDESC - 1;
00652         descr = decode_tabb_line ("0;0;0;Desc;value;0;0;0;tmp;0;0");
00653         if (descr != NULL) {
00654             des[_desc_special] = malloc (sizeof (desc));
00655             if (des[_desc_special] == NULL) {
00656                 fprintf (stderr, "Memory allocation error.\n");
00657                 return 0;
00658             }
00659             des[_desc_special]->id = ELDESC;
00660             des[_desc_special]->nr = _desc_special;
00661             des[_desc_special]->el = descr;
00662             des[_desc_special]->seq = NULL;
00663         }
00664     }
00665 
00666     build_keys();
00667     return 1;
00668 }
00669 
00670 /*===========================================================================*/
00679 void free_descs (void)
00680 
00681 
00682 {
00683     int i;
00684 
00685     for (i = 0; i < ndes; i ++) {
00686         free_one_desc (i);
00687     }
00688     ndes = 0;
00689 
00690     free_one_desc (ccitt_special);
00691     free_one_desc (cf_special);
00692     free_one_desc (add_f_special);
00693     free_one_desc (_desc_special);
00694     ccitt_special = 0;
00695     cf_special = 0;
00696     add_f_special = 0;
00697     _desc_special = 0;
00698 }
00699 
00700 static void free_one_desc (int i)
00701 {
00702     if (i < 0 || i >= MAXDESC + OPTDESC|| des[i] == NULL) 
00703        return;
00704 
00705     if (des[i]->id == ELDESC) {
00706         free (des[i]->el->unit);
00707         free (des[i]->el->elname);
00708         free (des[i]->el);
00709     }
00710     else if (des[i]->id == SEQDESC) {
00711         free (des[i]->seq->del);
00712         free (des[i]->seq);
00713     }
00714     free (des[i]);
00715     des[i] = NULL;
00716 }
00717 
00718 /*===========================================================================*/
00719 static del *decode_tabb_line (char *line)
00720 
00721 /* Decodes a single Table B Line and returns a pointer to a del-structure
00722          holding the data that has been decoded. The memory area must be
00723          freed by the calling function
00724 */
00725 
00726 {
00727 /* Get the first 8 strings of the line, each of them separated by a ';'
00728 */
00729 
00730     char *data_width, *refval, *scale, *unit, *name, *x, *y, *f;
00731     del desc, *ret;
00732     float tmp;
00733     char tmpline[1000];
00734 
00735     memset (&desc, 0, sizeof (del));
00736     strcpy (tmpline, line);
00737  
00738     data_width = get_val (tmpline, 7);
00739     refval     = get_val (tmpline, 6);
00740     scale      = get_val (tmpline, 5);
00741     unit       = get_val (tmpline, 4);
00742     name       = get_val (tmpline, 3);
00743     y          = get_val (tmpline, 2);
00744     x          = get_val (tmpline, 1);
00745     f          = get_val (tmpline, 0);
00746 
00747     if (data_width == NULL ||
00748         refval     == NULL ||
00749         scale      == NULL ||
00750         unit       == NULL ||
00751         name       == NULL ||
00752         x          == NULL ||
00753         y          == NULL ||
00754         f          == NULL) return NULL;
00755 
00756 
00757 /* A correct line has been found decode data from strings */
00758 
00759     if (sscanf (f,          "%d", &desc.d.f)   != 1) return NULL;
00760     if (sscanf (x,          "%d", &desc.d.x)   != 1) return NULL;
00761     if (sscanf (y,          "%d", &desc.d.y)   != 1) return NULL;
00762     if (sscanf (scale,      "%d", &desc.scale) != 1) return NULL;
00763     if (sscanf (data_width, "%d", &desc.dw)    != 1) return NULL;
00764     if (sscanf (refval,     "%f", &tmp)        != 1) return NULL;
00765     desc.refval = tmp;
00766 
00767     desc.unit = malloc (strlen (unit) + 1);
00768     if (desc.unit == NULL) {
00769         fprintf (stderr, "Memory allocation error !\n");
00770         return NULL;
00771     }
00772     strcpy (desc.unit, unit);
00773 
00774     desc.elname = malloc (strlen (name) + 1);
00775     if (desc.elname == NULL) {
00776         fprintf (stderr, "Memory allocation error !\n");
00777         return NULL;
00778     }
00779     strcpy (desc.elname, name);
00780 
00781     ret = malloc (sizeof (del));
00782     if (ret == NULL) {
00783         fprintf (stderr, "Memory allocation error !\n");
00784         return NULL;
00785     }
00786 
00787     memcpy (ret, &desc, sizeof (del));
00788     return ret;
00789 }
00790 /*===========================================================================*/
00801 int desc_is_flagtable (int ind) {
00802 
00803     char unit[20];
00804 
00805     strncpy (unit, des[ind]->el->unit, 20);
00806     unit[19] = '\0';
00807 
00808     str_lower (unit);
00809 
00810     return (strcmp (unit, "flag table") == 0 ||
00811             strcmp (unit, "flag-table") == 0);
00812 }
00813 
00814 /*===========================================================================*/
00825 int desc_is_codetable (int ind) {
00826 
00827     char unit[20];
00828     
00829     strncpy (unit, des[ind]->el->unit, 20);
00830     unit[19] = '\0';
00831 
00832     str_lower (unit);
00833 
00834     return (strcmp (unit, "code table") == 0 ||
00835             strcmp (unit, "code-table") == 0);
00836 }
00837 
00838 /*===========================================================================*/
00839 static char *get_val (char *line, int num)
00840 
00841 /* Gets a single value (character string) from a LINE licated at position
00842          NUM
00843 */
00844 
00845 {
00846     char *p;
00847     int i;
00848 
00849 /* seek to the end of the desired value and set it to 0 to identify the
00850          end of the string. */
00851 
00852     p = line;
00853     for (i = 0; i < num + 1 && p != NULL; i ++) {
00854         if (i == 0) p = strchr (p, ';');
00855         else p = strchr (p + 1, ';');
00856     }
00857     if (p != NULL) *p = 0;
00858 
00859 /* Now seek to the beginning of the desired value */
00860 
00861     p = line;
00862     for (i = 0; i < num && p != NULL; i ++) {
00863         if (i == 0) p = strchr (p, ';');
00864         else p = strchr (p + 1, ';');
00865     }
00866     if (p == NULL) return NULL;
00867     if (num != 0) p ++;
00868     return p;
00869 }
00870 
00871 /*===========================================================================*/
00880 void trim (char *buf)
00881 
00882 {
00883   int i, len;
00884 
00885   len = strlen (buf);
00886   for (i = len - 1; i >= 0; i --) {
00887     if (*(buf + i) == ' ') *(buf + i) = 0;
00888     else break;
00889   }
00890 }
00891 
00892 /*===========================================================================*/
00905 char *get_unit (dd* d)
00906 
00907 {
00908   int i;
00909 
00910   for (i = 0; i < ndes; i ++) {
00911     if (des[i]->id == ELDESC &&
00912         memcmp (d, &(des[i]->el->d), sizeof (dd)) == 0)
00913         return des[i]->el->unit;
00914   }
00915   return NULL;
00916 }
00917 
00918 /*===========================================================================*/
00919 static void replace_chars (char *line, char oldc, char newc)
00920 
00921 /* replaces one character of a string against another.
00922 */
00923 
00924 {
00925     for (;*line != 0; line ++) {
00926          if (*line == oldc) 
00927              *line = newc;
00928     }
00929 }
00930 
00931 /*===========================================================================*/
00939 static char *str_lower(char *str)
00940 {
00941     register char *p = str;
00942     while (*p != '\0') {
00943         *p = (char) tolower((int) *p);
00944         p++;
00945     }
00946     return str;
00947 }
00948 
00949 
00950 /* end of file */
00951 

Generated on Tue Dec 18 16:52:45 2007 for OPERA BUFR software by  doxygen 1.5.4