File c2rfx241.c of Package rnxcmp

/***********************************************************************/
/*     program name : C2RFX241                                         */
/*                                                                     */
/*     recover the RINEX file from buggy Compact RINEX file created by */
/*        RNX2CRX ver 2.4.1 or 2.4.1a which contain bugs               */
/*     Created by HATANAKA, Yuki / Geographical Survey Institute, Japan*/
/*                                                                     */
/*     ver.                                                            */
/*     0.1.1       2004.7.16  created by  HATANAKA, Y.                 */
/*                            based on CRX2RNX ver. 2.4.2              */
/*                                                                     */
/***********************************************************************/

#undef UNIX
#undef DOS
#undef VMS
#undef SUN41
 
/*** Choose the system by defining one of UNIX/DOS/VMS. ***/
#define UNIX

/*** Uncomment next line, in the case of SunOS4.1.x. ***/
/*** #define SUN41 ***/

/*  Maybe, you don't have to change the lines from here. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>

#ifdef UNIX
#define VERSION  "ver.u.0.1"
#define SEPARATOR '/'
#define CR_CHECK(p,q)  if( (p = strrchr(q,'\r')) != NULL && *(p+1) == '\0' ) *p = '\0'
#else
#ifdef  DOS
#define VERSION  "ver.d.0.1"
#define SEPARATOR '\\'
#define CR_CHECK(p,q)                 /*** define to NULL ***/
#else
#define VERSION  "ver.v.0.1"
#define SEPARATOR ']'
#define CR_CHECK(p,q)  if( (p = strrchr(q,'\r')) != NULL && *(p+1) == '\0' ) *p = '\0'
#endif
#endif

#define CHOP_BLANK(q,p) while(*--p == ' ' && p>q);*++p = '\0'

/*** "sprintf" on SunOS4.1.x does not follow the ANSI standard (returned value is   ***/
/*** not the number of output characters). For these OS, "my_sprintf" defined below ***/
/*** is used instead of sprintf. ***/
#ifdef SUN41
#include <stdarg.h>
#define SPRINTF  my_sprintf
int my_sprintf(char *p, char *format, ...){
    va_list ap;
    va_start(ap,format);
    vsprintf(p,format,ap);
    va_end(ap);
    return strlen(p);
}
#else
#define SPRINTF  sprintf
#endif

#define CRX_VERSION "1.0"
#define PROGNAME "C2RFX241"
#define MAXSAT   100           /* Maximum number of satellites   */
#define MAXTYPE  20            /* Maximum number of data types   */
#define MAX_DIFF_ORDER 5       /* Muximum order of difference to be dealt with */
#define MAXSAT3  MAXSAT*3      /* MAXSAT*3                       */
#define MAXTYPE2 MAXTYPE*2+2   /* MAXTYPE2 = MAXTYPE * 2 + 2     */
#define MAXLEN   512           /* Muximum length of one line     */
#define MAXBUF   MAXLEN*MAXSAT /* Muximum size of output buffer  */

#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
#ifdef VMS
#define EXIT_FAILURE 3
#else
#define EXIT_FAILURE 1
#endif
#endif

typedef struct clock_format{
    int  i[MAX_DIFF_ORDER+1];
    long f[MAX_DIFF_ORDER+1];
} clock_format;

typedef struct data_format{
    double r[MAX_DIFF_ORDER+1];
    int  order;
    int  arc_order;
} data_format;

FILE *ifp;

clock_format clk1,clk0;
data_format y1[MAXSAT][MAXTYPE],y0[MAXSAT][MAXTYPE];
char flag1[MAXSAT][MAXTYPE2],flag[MAXSAT][MAXTYPE2];

int nsat,ntype,clk_order = 0, clk_arc_order = 0;
long nl_count=0;

char out_buff[MAXBUF],*p_buff;

void fileopen(int argc, char *argv[]);
void header();
void put_event_data(char *dline);
void process_clock(char *dline);
void set_sat_table(char *p_new, char *p_old, int nsat1, int *sattbl);
void data(int *sattbl);
void repair(char *s, char *ds);
void getdiff(data_format *y, data_format *y0, int i0, char *dflag);
void putfield(data_format *y, char *flag);
void read_clock(char *p ,int *yi, long *yf);
void print_clock(int yi, long yf);
char *read_chk_line(char *line);
void error_exit(int error_no, char *string);

/*---------------------------------------------------------------------*/
main(int argc, char *argv[]){
/********************************************************************/
/*  sattbl : previous column on which the satellites are set        */
/*           new satellites are set to -1                           */
/*   date of previous epoch are set to line1, nsat1,                */
/********************************************************************/
    static char line[MAXLEN]="", sat_lst_old[MAXSAT3];
    static int nsat1 = 0, n;

    char dline[MAXLEN],*p;
    int event,sattbl[MAXSAT],i,j;

    if ( DBL_EPSILON > 1.e-15 ) error_exit(17,line);

    fileopen(argc,argv);
    header();

    while( fgets(dline,MAXLEN,stdin) != NULL){
	nl_count++;
        p = strchr(dline,'\n'); if( *(p-1) == '\r' )p--; *p = '\0';
        if(dline[0] == '&'){
            dline[0] = ' ';
            while(atoi(&dline[26]) > 0){
                put_event_data(dline);

	        nl_count++;
                if(fgets(dline,MAXLEN,stdin) == NULL) return EXIT_SUCCESS;  /*** exit program successfully ***/
                p = strchr(dline,'\n'); if( *(p-1) == '\r' )p--; *p = '\0';
                if(dline[0] != '&') error_exit(9,dline);
                dline[0] = ' ';
            }
            line[0]  = '\0';          /**** initialize arc for epoch data ***/
            nsat1 = 0;                /**** initialize the all satellite arcs ****/
        }else if( dline[0] == '\032' ){
            return EXIT_SUCCESS;   /** DOS EOF **/
        }
        /****  read, repair the line  ****/
        repair(line,dline);
        p = strchr(line,'\0');
        CHOP_BLANK(line,p);
	CR_CHECK(p,line);

        set_sat_table(&line[29],sat_lst_old,nsat1,sattbl); /****  set satellite table  ****/
        process_clock(dline);

        /*************************************/
        /**** print the recovered line(s) ****/
        /*************************************/
        p_buff = out_buff;
        if(clk_order >= 0){
            p_buff += SPRINTF(p_buff,"%-68.68s",line);
            print_clock(clk1.i[clk_order],clk1.f[clk_order]);
        }else{
            p_buff += SPRINTF(p_buff,"%.68s\n",line);
        }
        for(p = &line[68],n=nsat-12; n>0; n-=12,p+=36) p_buff += SPRINTF(p_buff,"%32.32s%.36s\n"," ",p);
        data(sattbl);

        *p_buff = '\0'; printf("%s",out_buff);
        /*********************************************************/
        /**** save current epoch for processing of next epoch ****/
        /*********************************************************/
        nsat1 = nsat;
        clk0 = clk1;
        strncpy(sat_lst_old,&line[32],nsat*3);
        for(i=0;i<nsat;i++){
            strncpy(flag1[i],flag[i],ntype*2);
            for(j=0;j<ntype;j++) y0[i][j] = y1[i][j];
        }
    }
    return EXIT_SUCCESS;
}
/*---------------------------------------------------------------------*/
void fileopen(int argc, char *argv[]){
    char *p,*basename,*infile,outfile[MAXLEN],*progname;
    int nfile=0, force=0, help=0;
    int nfout = 0;  /*** =0 default output file name                           ***/
                    /*** =1 specified name (VAX) or standaed output (UNIX,DOS) ***/

    progname = argv[0];
    argc--;argv++;
    for(;argc>0;argc--,argv++){
        if((*argv)[0] != '-'){
            infile = *argv;
            nfile++;
#ifdef VMS
        }else if((*argv)[1] == 'o'){
            argc--;argv++;
            if(argc==0) help = 1;
            nfout++;
            strcpy(outfile,*argv);
#else
        }else if((*argv)[1] == '\0'){
            nfout  = 1;
#endif
        }else if((*argv)[1] == 'f'){
            force = 1;
        }else if((*argv)[1] == 'h'){
            help = 1;
        }else{
            help = 1;
        }
    }

#ifdef VMS
    if(help == 1 || nfile != 1 || nfout > 1) error_exit(1,progname);
#else
    if(help == 1 || nfile > 1 || nfile < 0) error_exit(2,progname);
    if(nfile == 0) return;       /*** stdin & stdout will be used ***/
#endif

    /***********************/
    /*** open input file ***/
    /***********************/
    basename = infile;
    if( (p=strrchr(infile,SEPARATOR)) != NULL ) basename = p+1;
#ifdef VMS
    if( (p=strchr(basename,';')) != NULL ) *p = '\0';
#endif

    p=strstr(basename,".");
    if(p == NULL || (*(p+3) != 'D' && *(p+3) != 'd') || *(p+4) != '\0') error_exit(3,p);
    if((ifp = fopen(infile,"r")) == NULL) error_exit(4,infile);

    /************************/
    /*** open output file ***/
    /************************/
    if(nfout == 0) {
        strcpy(outfile,basename);
        p=strstr(outfile,".");
        *(p+3) = 'o';
#ifdef VMS
    }
    {
#endif
        if((freopen(outfile,"r",stdout)) != NULL && force == 0){
            fprintf(stderr,"The file %s already exists. Overwrite?(n)",outfile);
            if(getchar() != 'y') exit(EXIT_SUCCESS);
        }
#ifdef VMS
        freopen(outfile,"w",stdout,"rfm=var","rat=cr");
#else
	freopen(outfile,"w",stdout);
#endif
    }
    fclose(ifp);
    freopen(infile,"r",stdin);
}
/*---------------------------------------------------------------------*/
void header(){
    int end = 1;
    char line[MAXLEN],*p,crx_ver;
    nl_count++;
    if( fgets(line,MAXLEN,stdin) == NULL ) error_exit(5,CRX_VERSION);
    if( strncmp(&line[0],CRX_VERSION,3) != 0 ||
        strncmp(&line[60],"CRINEX VERS   / TYPE",19) != 0 ) error_exit(5,CRX_VERSION);
    nl_count++;
    if( fgets(line,MAXLEN,stdin) == NULL ) error_exit(8,line);
    if(strncmp(&line[0],"RNX2CRX ver.",12) != 0 ||
       strncmp(&line[13],".2.4.1",6) != 0)error_exit(18,line);
    while(end != 0){
        p=read_chk_line(line);
        while(*--p == ' ' && p>line);*++p = '\0';
        printf("%s\n",line);
        if(strncmp(&line[60],"# / TYPES OF OBSERV",19) == 0){
            ntype=atoi(line);
            if(ntype > MAXTYPE) error_exit(16,line);
        }
        end = strncmp(&line[60],"END OF HEADER",13);
    }
}
/*---------------------------------------------------------------------*/
void process_clock(char *dline){
    /********************************/
    /****  process clock offset  ****/
    /********************************/
    int i,j;
    char *p,*ps;

    read_chk_line(dline);
    p = dline;

    if(*p == '\0'){
        clk_order = -1;
    }else{
        /****************************/
        /**** arc initialization ****/
        /****************************/
        if(*(p+1) == '&') {
            /* sscanf(p,"%d&",&clk_arc_order); */
            clk_arc_order=atoi(p);
            if(clk_arc_order > MAX_DIFF_ORDER) error_exit(7,dline);
            clk_order = -1;
            p += 2;
        }
        /****************************************/
        /**** recover the clock offset value ****/
        /****************************************/
        read_clock(p,clk1.i,clk1.f);
        if(clk_order < clk_arc_order){
            clk_order++;
            for(i=0,j=1 ; i<clk_order ; i++,j++){
                clk1.i[j] = clk1.i[i]+clk0.i[i];
                clk1.f[j] = clk1.f[i]+clk0.f[i];
                clk1.i[j] += clk1.f[j]/100000000;  /*** avoid overflow of y1.f ***/
                clk1.f[j] %= 100000000;
            }
        }else{
            for(i=0,j=1 ; i<clk_order ; i++,j++){
                clk1.i[j] = clk1.i[i]+clk0.i[j];
                clk1.f[j] = clk1.f[i]+clk0.f[j];
                clk1.i[j] += clk1.f[j]/100000000;
                clk1.f[j] %= 100000000;
            }
        }
    }
}
/*---------------------------------------------------------------------*/
void put_event_data(char *dline){
/***********************************************************************/
/*  - Put event data for one event.                                    */
/*  - This function is called when the event flag > 1.                 */
/***********************************************************************/
    int i,n;
    char *p;
    printf("%s\n",dline);
    if( strlen(dline) > 29 ){
        if(*(dline+28) == '6'){      /*** for cycle slip records ***/
            nsat=atoi(&dline[29]);
            n=nsat*((ntype+4)/5)+((nsat-1)/12);
        }else{
            n=atoi(&dline[29]);
        }
        for(i=0;i<n;i++){
            p=read_chk_line(dline);
	    CHOP_BLANK(dline,p);
            printf("%s\n",dline);
            if(strncmp(&dline[60],"# / TYPES OF OBSERV",19) == 0) {
                ntype=atoi(&dline[0]);
                if(ntype > MAXTYPE) error_exit(16,dline);
            }
        }
    }
}
/*---------------------------------------------------------------------*/
void set_sat_table(char *p_new, char *p_old, int nsat1, int *sattbl){
/***********************************************************************/
/*  - Read number of satellites (nsat)                                 */
/*  - Compare the satellite list at the epoch (*p_new) and that at the */
/*    previous epoch(*p_old), and make index (*sattbl) for the         */
/*    corresponding order of the satellites.                           */
/*    *sattbl is set to -1 for new satellites.                         */
/***********************************************************************/
    int i,j;
    char *ps;

    nsat=atoi(p_new);
    if(nsat > MAXSAT) error_exit(6,p_new);

    for (i=0,p_new+=3 ; i<nsat ; i++,p_new+=3){
        *sattbl = -1;
        for(j=0,ps=p_old ; j<nsat1 ; j++,ps+=3){
            if(strncmp(p_new,ps,3) == 0){
                *sattbl = j;
                break;
            }
        }
        sattbl++;
    }
}
/*---------------------------------------------------------------------*/
void data(int *sattbl){
/********************************************************************/
/*  Functions                                                       */
/*      (1) compose the original data from 3rd order difference     */
/*      (2) repair the flags                                        */
/*  sattbl : previous column on which the satellites are set        */
/*           new satellites are set to -1                           */
/*       i : integer part of the data                               */
/*       f : fractioal part of the data                             */
/*            ( y = i*1000 + f )                                    */
/*   date of previous epoch are set to y0                           */
/********************************************************************/
    data_format *py1,*py0;
    int  i,j,k,k1,*i0;
    char dflag[MAXTYPE2];

    for(i=0,i0=sattbl ; i<nsat ; i++,i0++){

        getdiff(y1[i],y0[*i0],*i0,dflag);     /****  read data  ****/

        /*********************************/
        /****  repair the data frags  ****/
        /*********************************/
        if(*i0 < 0){
            sprintf(flag[i],"%-*s",ntype*2,dflag);
        }else{
            strncpy(flag[i],flag1[*i0],ntype*2);
            repair(flag[i],dflag);
        }

        /****************************************/
        /****  recover the date, and output  ****/
        /****************************************/
        for(j=0,py1=y1[i] ; j<ntype ; j++,py1++){
            if(py1->arc_order >= 0){
                py0 = &(y0[*i0][j]);
                if(py1->order < py1->arc_order){
                    (py1->order)++;
                    for(k=0,k1=1; k<py1->order; k++,k1++){
                        py1->r[k1] = py1->r[k] + py0->r[k];
                    }
                }else{
                    for(k=0,k1=1; k<py1->order; k++,k1++){
                        py1->r[k1] = py1->r[k] + py0->r[k1];
                    }
                }
                putfield(py1,&flag[i][j*2]);
            }else{
                p_buff += SPRINTF(p_buff,"                ");
                flag[i][j*2] = flag[i][j*2+1] = ' ';
            }
            if((j+1)%5 == 0 || (j+1) == ntype){
                while(*--p_buff == ' '); p_buff++;  /*** cut spaces ***/
                *p_buff++ = '\n';
            }
        }
    }
}
/*---------------------------------------------------------------------*/
void repair(char *s, char *ds){
    for(; *s != '\0' && *ds != '\0' ; ds++,s++){
        if(*ds != ' '){
            if(*ds == '&')
                *s = ' ';
            else
                *s = *ds;
        }
    }
    if(*ds != '\0') {
        sprintf(s,"%s",ds);
	for(; *s != '\0' ;s++) {
            if(*s == '&') *s = ' ';
        }
    }
}
/*---------------------------------------------------------------------*/
void getdiff(data_format *y, data_format *y0, int i0, char *dflag){
    int j,lmax;
    char *s,*s1,*s2,line[MAXLEN];

    /******************************************/
    /****  separate the fields with "\0"   ****/
    /******************************************/
    read_chk_line(line);
    for(j=0,s=line; j<ntype; s++){
        if(*s == '\0') {
            j++;
            *(s+1) = '\0';
        }else if(*s == ' '){
            j++;
            *s = '\0';
        }
    }
    strcpy(dflag,s);

    /************************************/
    /*     read the differenced data    */
    /************************************/
    s1=line;
    for(j=0;j<ntype;j++){
        if(*s1 == '\0'){
            y->arc_order = -1;      /**** arc_order < 0 means that the feild if blank ****/
            y->order = -1;
            s1++;
        }else{
            if(*(s1+1) == '&'){     /**** arc initialization ****/
                y->order = -1;
                /* sscanf(s1,"%d&",&(y->arc_order)); */
                y->arc_order = atoi(s1);
                s1 += 2;
                if(y->arc_order > MAX_DIFF_ORDER) error_exit(7,line);
            }else if(i0 < 0){
                error_exit(11,line);
            }else if(y0->arc_order < 0){
                error_exit(12,line);
            }else{
                y->order = y0->order;
                y->arc_order = y0->arc_order;
            }

            y->r[0] = atof(s1);
            s1=strchr(s1,'\0')+1;
        }
        y++;
        y0++;
    }
}
/*---------------------------------------------------------------------*/
void putfield(data_format *y, char *flag){
    int  i;
    char *si;

    si=p_buff;

    i=y->order;
    SPRINTF(p_buff,"%13.0f ",y->r[i]);
    /*** devision by 1000 ***/
    si[13]=si[12];
    si[12]=si[11];
    si[11]=si[10];
    si[10]='.';
    /*** relocation of sign and padding 0 ***/
    if(si[11]=='-'){
       si[9]='-';
       si[11]='0';
    }else if(si[11]==' '){
       si[11]='0';
       if(si[12]=='-'){
          si[9]='-';
          si[12]='0';
       }else if(si[12]==' '){
          si[12]='0';
       }
    }
    si[14]=*flag;si[15]=*(flag+1);
    p_buff+=16;
}
/*---------------------------------------------------------------------*/
void print_clock(int yi, long yf){
    char buff[5];

    if(yi<0 && yf>0){
        yi++ ; yf -= 100000000;
    }else if(yi>0 && yf<0){
        yi-- ; yf += 100000000;
    }

    sprintf(buff,"%3d.",yi);
    buff[3]=buff[2];
    buff[2]='.';
    if(yi==0){
        if(yf <0)
            buff[1]='-';
        else
            buff[1]=' ';
    }
    p_buff += SPRINTF(p_buff,"%4s%08.8ld\n",buff,labs(yf));
}
/*---------------------------------------------------------------------*/
void read_clock(char *p ,int *yi, long *yf){
/**************************/
/**** read clock diffs ****/
/**************************/

    char *s=p,*p1=p;

    if(*s == '-') p1++;
    while(*s != '\0') s++;
    if((s-p1) < 9 ){                /** s-p1 == strlen(p1) ***/
        *yi = 0;
        *yf = atol(p);
    }else{
        s -= 8;
        *yf = atol(s);
        *s = '\0';
        *yi = atol(p);
        if(*yi < 0) *yf = -*yf;
    }
}
/*---------------------------------------------------------------------*/
char *read_chk_line(char *line){
    char *p;
 
    nl_count++;
    if( fgets(line,MAXLEN,stdin) == NULL ) error_exit(8,line);
    if( (p = strchr(line,'\n')) == NULL) {
        if( fgetc(stdin) == EOF ) {     /** check if EOF is there **/
            error_exit(8,line);
        }else{
            error_exit(13,line);
        }
    }
    if( *(p-1) == '\r' )p--;   /*** check DOS CR/LF ***/
    *p = '\0';
    return p;
}
/*---------------------------------------------------------------------*/
void error_exit(int error_no, char *string){
    if(error_no == 1 ){
        fprintf(stderr,"Usage: %s input file [-o output file] [-f] [-h]\n",string);
        fprintf(stderr,"    output file name can be omitted if input file name is *.[yy]d\n");
    }else if(error_no == 2 ){
        fprintf(stderr,"Usage: %s [file] [-] [-f] [-h]\n",string);
        fprintf(stderr,"    stdin and stdout are used if input file name is not given.\n");
    }
    if(error_no == 1 || error_no == 2){
        fprintf(stderr,"    -  : output to stdout\n");
        fprintf(stderr,"    -f : force overwrite of output file\n");
        fprintf(stderr,"    -h : display help message\n");
	fprintf(stderr,"    exit code = %d (success)\n",EXIT_SUCCESS);
	fprintf(stderr,"              = %d (error)\n",EXIT_FAILURE);
        fprintf(stderr,"    [version : %s]\n",VERSION);
        exit(EXIT_FAILURE);
    }
    if(error_no == 3 ){
        fprintf(stderr,"ERROR : invalid file name  %s\n",string);
        fprintf(stderr,"The file name should be such as [xxxxxxxx.xxd].\n");
#ifdef VMS
        fprintf(stderr,"       if you don't specify output file name\n");
#else
        fprintf(stderr,"If the file name doesn't obey this naming convention, use this program as a filter. \n");
        fprintf(stderr,"    for example)  cat file.in | %s - > file.out\n",PROGNAME);
#endif
        exit(EXIT_FAILURE);
    }
    if(error_no == 4 ){
        fprintf(stderr,"ERROR : can't open %s\n",string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 5 ){
        fprintf(stderr,"ERROR : version of the format is not valid.\n");
        fprintf(stderr,"        This software can deal with only ver.%s.\n",string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 6 ){
        fprintf(stderr,"ERROR at line %ld : exceed maximum number of satellites(%d)\n",MAXSAT,nl_count);
        fprintf(stderr,"      start>%s<end\n",string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 7 ){
        fprintf(stderr,"ERROR at line %ld : exceed maximum order of difference (%d)\n",MAX_DIFF_ORDER,nl_count);
        fprintf(stderr,"      start>%s<end\n",string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 8 ){
        fprintf(stderr,"ERROR : The file seems to be trancated in the middle.\n");
        fprintf(stderr,"        The conversion is interrupted after reading the line %ld :\n",nl_count);
        fprintf(stderr,"      start>%s<end\n",string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 9 ){
        fprintf(stderr,"ERROR at line %ld : The arc should be initialized, but not.\n",nl_count);
        fprintf(stderr,"      start>%s<end\n",string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 11){
        fprintf(stderr,"ERROR at line %ld : New satellite, but data arc is not initialized.\n",nl_count);
        fprintf(stderr,"      start>%s<end\n",string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 12){
        fprintf(stderr,"ERROR at line %ld : The data feild in previous epoch is blank, but the arc is not initialized.\n",nl_count);
        fprintf(stderr,"      start>%s<end\n",string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 13){
        fprintf(stderr,"ERROR at line %ld : null character is found in the line or the line is too long (>%d) at line.\n",nl_count,MAXLEN);
        fprintf(stderr,"      start>%s<end\n",string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 16 ){
        fprintf(stderr,"Number of datea type exceeds limitation (%d):\n%s\n",MAXTYPE,string);
        exit(EXIT_FAILURE);
    }
    if(error_no == 17 ){
        fprintf(stderr,"ERROR: DBL_EPSILON = %e on this machine architecture.\n",DBL_EPSILON);
        fprintf(stderr,"      (DBL_EPSILON should be smaller than 1.0e-15)\n");
        exit(EXIT_FAILURE);
    }
    if(error_no == 18 ){
        fprintf(stderr,"ERROR: CRINEX PROG must be RNX2CRX ver.?.2.4.1(a).\n");
        fprintf(stderr,"      start>%s<end\n",string);
        exit(EXIT_FAILURE);
    }

}
openSUSE Build Service is sponsored by