Пример #1
0
int cp_pss_ver(g1_t a, g1_t b, uint8_t *msg, int len, g2_t g, g2_t x, g2_t y) {
	g1_t p[2];
	g2_t r[2];
	gt_t e;
	bn_t m, n;
	int result = 1;

	g1_null(p[0]);
	g1_null(p[1]);
	g2_null(r[0]);
	g2_null(r[1]);
	gt_null(e);
	bn_null(m);
	bn_null(n);

	TRY {
		g1_new(p[0]);
		g1_new(p[1]);
		g2_new(r[0]);
		g2_new(r[1]);
		gt_new(e);
		bn_new(m);
		bn_new(n);

		if (g1_is_infty(a)) {
			result = 0;
		}

		g1_copy(p[0], a);
		g1_copy(p[1], b);
		g2_copy(r[1], g);
		g2_neg(r[1], r[1]);
		g1_get_ord(n);
		bn_read_bin(m, msg, len);
		bn_mod(m, m, n);
		g2_mul(r[0], y, m);
		g2_add(r[0], r[0], x);
		g2_norm(r[0], r[0]);

		pc_map_sim(e, p, r, 2);
		if (!gt_is_unity(e)) {
			result = 0;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		g1_free(p[0]);
		g1_free(p[1]);
		g2_free(r[0]);
		g2_free(r[1]);
		gt_free(e);
		bn_free(m);
		bn_free(n);
	}
	return result;
}
Пример #2
0
int cp_bgn_dec2(dig_t *out, g2_t in[2], bgn_t prv) {
	bn_t r, n;
	g2_t s, t, u;
	int i, result = STS_ERR;

	bn_null(n);
	bn_null(r);
	g2_null(s);
	g2_null(t);
	g2_null(u);

	TRY {
		bn_new(n);
		bn_new(r);
		g2_new(s);
		g2_new(t);
		g2_new(u);

		g2_get_ord(n);
		/* Compute T = x(ym + r)G - (zm + xr)G = m(xy - z)G. */
		g2_mul(t, in[0], prv->x);
		g2_sub(t, t, in[1]);
		g2_norm(t, t);
		/* Compute U = (xy - z)G and find m. */
		bn_mul(r, prv->x, prv->y);
		bn_sub(r, r, prv->z);
		bn_mod(r, r, n);
		g2_mul_gen(s, r);
		g2_copy(u, s);
		
		if (g2_is_infty(t) == 1) {
			*out = 0;
			result = STS_OK;
		} else {
			for (i = 0; i < INT_MAX; i++) {
				if (g2_cmp(t, u) == CMP_EQ) {
					*out = i + 1;
					result = STS_OK;
					break;
				}
				g2_add(u, u, s);
				g2_norm(u, u);
			}
		}
	} CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(n);
		bn_free(r);
		g2_free(s);
		g2_free(t);
		g2_free(u);
	}

	return result;
}
Пример #3
0
void FIF(g2_filled_para_5)(F_REAL *dev, F_REAL *N_pt, F_REAL *points)
{
    double *d;
    d=g2_floatp2doublep(points, dtoi(*N_pt)*2);
    g2_filled_para_5(dtoi(*dev), dtoi(*N_pt), d);
    g2_free(d);
}
Пример #4
0
void FIF(g2_filled_raspln)(F_REAL *dev, F_REAL *N_pt, F_REAL *points, F_REAL *tn)
{
    double *d;
    d=g2_floatp2doublep(points, dtoi(*N_pt)*2);
    g2_filled_raspln(dtoi(*dev), dtoi(*N_pt), d, *tn);
    g2_free(d);
}
Пример #5
0
void FIF(g2_filled_b_spline)(F_REAL *dev, F_REAL *N_pt, F_REAL *points, F_REAL *o)
{
    double *d;
    d=g2_floatp2doublep(points, dtoi(*N_pt)*2);
    g2_filled_b_spline(dtoi(*dev), dtoi(*N_pt), d, dtoi(*o));
    g2_free(d);
}
Пример #6
0
void FIF(g2_set_dash)(F_REAL *dev, F_REAL *N, F_REAL *dashes)
{
    double *d;
    d=g2_floatp2doublep(dashes, dtoi(*N));
    g2_set_dash(dtoi(*dev), dtoi(*N), d);
    g2_free(d);
}
Пример #7
0
void FIF(g2_polygon)(F_REAL *dev, F_REAL *N_pt, F_REAL *points)
{
    double *d;
    d=g2_floatp2doublep(points, dtoi(*N_pt)*2);
    g2_polygon(dtoi(*dev), dtoi(*N_pt), d);
    g2_free(d);
}
Пример #8
0
status_t element_clear(element_t e)
{
    if(e->isInitialized == TRUE) {
    	if(e->type == ZR) {
    		bn_free(e->bn);
    		bn_null(e->bn);
		}
    	else if(e->type == G1) {
    		g1_free(e->g1);
    		g1_null(e->g1);
    	}
    	else if(e->type == G2) {
    		g2_free(e->g2);
    		g2_null(e->g2);
    	}
    	else if(e->type == GT) {
    		gt_free(e->gt);
    		gt_null(e->gt);
    	}
    	else {
    		return ELEMENT_INVALID_TYPES;
    	}
		bn_free(e->order);
		bn_null(e->order);
    	e->isInitialized = FALSE;
    	e->type = NIL;
    }
    return ELEMENT_OK;
}
Пример #9
0
void FIF(g2_string)(F_REAL *dev, F_REAL *x, F_REAL *y, F_CHAR *text,
		    F_CHAR_LENGTH length)
{
    char *str;
    str=g2_malloc((length+1)*sizeof(char));
    strncpy(str, text, length);
    str[length]='\0';
    g2_string(dtoi(*dev), *x, *y, str);
    g2_free(str);
}
Пример #10
0
void gb2_clos ( Gribmsg *cmsg, int *iret )
/************************************************************************
 * gb2_clos								*
 *									*
 * This function will free any used memory allocated for struct gribmsg *
 * and close a GRIB file                                                *
 *                                                                      *
 * gb2_clos ( cmsg, iret )                             		        *
 *                                                                      *
 * Input parameters:                                                    *
 *                                                                      *
 * Output parameters:                                                   *
 *      *cmsg        struct gribmsg     current GRIB field              *
 *      *iret		int		Return code                     *
 *                                        -15 = error closing file      *
 **                                                                     *
 * Log:                                                                 *
 * S. Gilbert/NCO           11/2004                                     *
 ***********************************************************************/
{

/*---------------------------------------------------------------------*/
	*iret = 0;


        /*
        if ( cmsg->gfld != 0 )printf("%x\n",cmsg->gfld->idsect);
        if ( cmsg->gfld != 0 )printf("%x\n",cmsg->gfld->local);
        if ( cmsg->gfld != 0 )printf("%x\n",cmsg->gfld->list_opt);
        if ( cmsg->gfld != 0 )printf("%x\n",cmsg->gfld->igdtmpl);
        if ( cmsg->gfld != 0 )printf("%x\n",cmsg->gfld->coord_list);
        if ( cmsg->gfld != 0 )printf("%x\n",cmsg->gfld->idrtmpl);
        if ( cmsg->gfld != 0 )printf("%x\n",cmsg->gfld->bmap);
        if ( cmsg->gfld != 0 )printf("%x\n",cmsg->gfld->fld);
        */
        /*
        **	Free any allocated memory
        */
        if ( cmsg->cgrib2 != 0 ) free(cmsg->cgrib2);
        if ( cmsg->gfld != 0 ) g2_free(cmsg->gfld);
        cmsg->cgrib2=0;
        cmsg->mlength=0;
        cmsg->gfld=0;
        cmsg->field_tot=0;
       

        /*
        **	Close the GRIB file.
        */
        gb_clos ( iret );


}
Пример #11
0
F_REAL FIF(g2_open_ps)(F_CHAR *text, F_REAL *paper, F_REAL *orientation,
		       F_CHAR_LENGTH length)
{
    char *str;
    int rv;

    str=g2_malloc((length+1)*sizeof(char));
    strncpy(str, text, length);
    str[length]='\0';
    rv=g2_open_PS(str, dtoi(*paper), dtoi(*orientation));
    g2_free(str);
    
    return (F_REAL)rv;
}
Пример #12
0
/* thanks to Yuri Sbitnev for contributing the g2_image code for FORTRAN */
void FIF(g2_image)(F_REAL *dev, F_REAL *x, F_REAL *y, F_REAL *x_size, F_REAL *y_size,
		   F_REAL *pens)
{
    int i, j, xs, ys;
    int *mypens;
    xs=dtoi(*x_size);
    ys=dtoi(*y_size);
    mypens=(int *) g2_malloc(xs*ys*sizeof(int));
    for(j=0;j<ys;j++) 
      for(i=0;i<xs;i++) 
        mypens[j*xs+i]=dtoi(pens[j*xs+i]);         /* pens[dtoi(*y_size)][dtoi(*x_size)] */
    g2_image(dtoi(*dev), *x, *y, xs, ys, mypens);
    g2_free(mypens);
}
Пример #13
0
int element_is_member(element_t e)
{
	LEAVE_IF(e->isInitialized != TRUE, "uninitialized argument.");
	int result;

	if(e->type == ZR) {
		if(bn_cmp(e->bn, e->order) <= CMP_EQ)
			result = TRUE;
		else
			result = FALSE;
	}
	else if(e->type == G1) {
		g1_t r;
		g1_inits(r);

		g1_mul(r, e->g1, e->order);
		if(g1_is_infty(r) == 1)
			result = TRUE;
		else
			result = FALSE;
		g1_free(r);
	}
	else if(e->type == G2) {
		g2_t r;
		g2_inits(r);

		g2_mul(r, e->g2, e->order);
		if(g2_is_infty(r) == 1)
			result = TRUE;
		else
			result = FALSE;
		g2_free(r);
	}
	else if(e->type == GT) {
		gt_t r;
		gt_inits(r);

		gt_exp(r, e->gt, e->order);
		if(gt_is_unity(r) == 1)
			result = TRUE;
		else
			result = FALSE;
		gt_free(r);
	}
	else {
		result = ELEMENT_INVALID_ARG;
	}

	return result;
}
Пример #14
0
int cp_bbs_ver(g1_t s, uint8_t *msg, int len, int hash, g2_t q, gt_t z) {
	bn_t m, n;
	g2_t g;
	gt_t e;
	uint8_t h[MD_LEN];
	int result = 0;

	bn_null(m);
	bn_null(n);
	g2_null(g);
	gt_null(e);

	TRY {
		bn_new(m);
		bn_new(n);
		g2_new(g);
		gt_new(e);

		g2_get_ord(n);

		/* m = H(msg). */
		if (hash) {
			bn_read_bin(m, msg, len);
		} else {
			md_map(h, msg, len);
			bn_read_bin(m, h, MD_LEN);
		}
		bn_mod(m, m, n);

		g2_mul_gen(g, m);
		g2_add(g, g, q);
		g2_norm(g, g);

		pc_map(e, s, g);

		if (gt_cmp(e, z) == CMP_EQ) {
			result = 1;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(m);
		bn_free(n);
		g2_free(g);
		gt_free(e);
	}
	return result;
}
Пример #15
0
F_REAL FIF(g2_open_gd)(F_CHAR *text, F_REAL *width, F_REAL *height, F_REAL *gd_type,
			F_CHAR_LENGTH length)
{
    char *str;
    int rv;
    
    str=g2_malloc((length+1)*sizeof(char));
    strncpy(str, text, length);
    str[length]='\0';

    rv=g2_open_gd(str, *width, *height, *gd_type);
    
    g2_free(str);
    
    return (F_REAL)rv;
}
Пример #16
0
status_t element_pp_clear(element_pp_t e_pp, GroupType type)
{
	if(e_pp->isInitialized == FALSE) return ELEMENT_UNINITIALIZED;
	if(type == G1) {
		for (int i = 0; i < G1_TABLE; i++) {
//			printf("%d: ", i);
//    		g1_print(e_pp->t1[i]);
			g1_free(e_pp->t1[i]);
		}
	}
	else if(type == G2) {
		for (int i = 0; i < G2_TABLE; i++) {
			g2_free(e_pp->t2[i]);
		}
	}
	e_pp->isInitialized = FALSE;
	return ELEMENT_OK;
}
Пример #17
0
int cp_bgn_enc2(g2_t out[2], dig_t in, bgn_t pub) {
	bn_t r, n;
	g2_t t;
	int result = STS_OK;

	bn_null(n);
	bn_null(r);
	g2_null(t);

	TRY {
		bn_new(n);
		bn_new(r);
		g2_new(t);

		g2_get_ord(n);
		bn_rand_mod(r, n);

		/* Compute c0 = (ym + r)G. */
		g2_mul_dig(out[0], pub->hy, in);
		g2_mul_gen(t, r);
		g2_add(out[0], out[0], t);
		g2_norm(out[0], out[0]);

		/* Compute c1 = (zm + xr)G. */
		g2_mul_dig(out[1], pub->hz, in);
		g2_mul(t, pub->hx, r);
		g2_add(out[1], out[1], t);
		g2_norm(out[1], out[1]);
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(n);
		bn_free(r);
		g2_free(t);
	}

	return result;
}
Пример #18
0
void gt_get_gen(gt_t a) {
	g1_t g1;
	g2_t g2;

	g1_null(g1);
	g2_null(g2);

	TRY {
		g1_new(g1);
		g2_new(g2);

		g1_get_gen(g1);
		g2_get_gen(g2);

		pc_map(a, g1, g2);
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	} FINALLY {
		g1_free(g1);
		g2_free(g2);
	}
}
Пример #19
0
int cp_bls_ver(g1_t s, uint8_t *msg, int len, g2_t q) {
	g1_t p;
	g2_t g;
	gt_t e1, e2;
	int result = 0;

	g1_null(p);
	g2_null(g);
	gt_null(e1);
	gt_null(e2);

	TRY {
		g1_new(p);
		g2_new(g);
		gt_new(e1);
		gt_new(e2);

		g2_get_gen(g);

		g1_map(p, msg, len);
		pc_map(e1, p, q);
		pc_map(e2, s, g);

		if (gt_cmp(e1, e2) == CMP_EQ) {
			result = 1;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		g1_free(p);
		g2_free(g);
		gt_free(e1);
		gt_free(e2);
	}
	return result;
}
Пример #20
0
int cp_sokaka_key(uint8_t *key, unsigned int key_len, char *id1,
		int len1, sokaka_t k, char *id2, int len2) {
	int first = 0, result = STS_OK;
	g1_t p;
	g2_t q;
	gt_t e;

	g1_null(p);
	g2_null(q);
	gt_null(e);

	TRY {
		g1_new(p);
		g2_new(q);
		gt_new(e);

		if (len1 == len2) {
			if (strncmp(id1, id2, len1) == 0) {
				THROW(ERR_NO_VALID);
			}
			first = (strncmp(id1, id2, len1) < 0 ? 1 : 2);
		} else {
			if (len1 < len2) {
				if (strncmp(id1, id2, len1) == 0) {
					first = 1;
				} else {
					first = (strncmp(id1, id2, len2) < 0 ? 1 : 2);
				}
			} else {
				if (strncmp(id1, id2, len2) == 0) {
					first = 2;
				} else {
					first = (strncmp(id1, id2, len2) < 0 ? 1 : 2);
				}
			}
		}

		if (pc_map_is_type1()) {
			g2_map(q, (uint8_t *)id2, len2);
			pc_map(e, k->s1, q);
		} else {
			if (first == 1) {
				g2_map(q, (uint8_t *)id2, len2);
				pc_map(e, k->s1, q);
			} else {
				g1_map(p, (uint8_t *)id2, len2);
				pc_map(e, p, k->s2);
			}
		}

		/* Allocate size for storing the output. */
		uint8_t buf[gt_size_bin(e, 0)];
		gt_write_bin(buf, sizeof(buf), e, 0);
		md_kdf1(key, key_len, buf, sizeof(buf));
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		g1_free(p);
		g2_free(q);
		gt_free(e);
	}
	return result;
}
Пример #21
0
/**
 * Generates an LDM product-identifier from a GRIB edition 2 message.
 *
 * Atomic,
 * Idempotent,
 * Not thread-safe
 *
 * @param[in]  data             Pointer to the GRIB message.
 * @param[in]  sz               Length of the GRIB message in bytes.
 * @param[in]  wmohead          Pointer to the associated WMO header string.
 * @param[out] ident            Pointer to a buffer to receive the LDM
 *                              product-identifier.
 * @param[in]  identSize        Size of the \c ident buffer in bytes.
 * @retval     0                Success. \c ident is set and NUL-terminated.
 * @retval     1                Invalid GRIB message.
 * @retval     2                GRIB message isn't edition 2.
 * @retval     3                System error.
 */
int grib2name (
    char* const         data,
    const size_t        sz,
    const char* const   wmohead,
    char* const         ident,
    const size_t        identSize)
{
#if USE_GRIB2_DECODER
    int                 status;
    DecodedGrib2Msg*    decoded;

    if (status = g2d_new(&decoded, (unsigned char*)data, sz)) {
        log_add("Couldn't decode GRIB message");
        status = G2D_INVALID == status
                ? 1
                : G2D_NOT_2
                    ? 2
                    : 3;
    }
    else {
        if (status = setIdent(ident, identSize, decoded, wmohead)) {
            log_add("Couldn't set LDM product-identifier");
            status = 1;
        }

        g2d_free(decoded);
    } /* "decoded" allocated */

    return status;
#else
    static StringBuf*  paramNames;    /* Buffer for parameter name(s) */
    int                iField;        /* GRIB-2 field index */
    int                status;        /* Function return code */
    g2int              listsec0[3];   /* GRIB-2 section 0 parameters */
    g2int              listsec1[13];  /* GRIB-2 section 1 parameters */
    g2int              numlocal;      /* Number of GRIB section 2-s */
    int                model_id;      /* ID of model */
    int                grid_id;       /* ID of grid */
    char               fdats[80];     /* No idea */
    char               levelstmp[80]; /* Level? */
    Gribmsg            g2Msg;         /* GRIB-2 message structure */

    if (paramNames) {
        strBuf_clear(paramNames);
    }
    else {
        paramNames = strBuf_new(127);
        if (NULL == paramNames) {
            log_add("Couldn't allocate buffer for parameter name(s)");
            return 3;
        }
    }

    g2Msg.cgrib2 = (unsigned char*)data;
    g2Msg.mlength = sz;
    g2Msg.gfld = NULL;
    g2Msg.field_tot = 0;

    if ((status = g2_info(g2Msg.cgrib2, g2Msg.mlength, listsec0, listsec1,
            &(g2Msg.field_tot), &numlocal)) != 0)
        return (2 == status) ? 2 : 1;

    if (g2Msg.field_tot <= 0) {
        log_add("GRIB-2 message has no data fields");
        return 1;
    }

    for (iField = 0; iField < g2Msg.field_tot; iField++) {
        static char  g2tables[5][LLMXLN];  /* GRIB tables */
        static char* tbllist[5] = {g2tables[0], g2tables[1], g2tables[2],
                g2tables[3], g2tables[4]}; /* Addresses of GRIB tables */
        Geminfo      gemInfo;              /* GEMPAK structure */
        int const    lastField = iField == g2Msg.field_tot - 1;

        status = g2_getfld(g2Msg.cgrib2, g2Msg.mlength, iField+1, 0, 0,
                &g2Msg.gfld);

        if (status) {
            log_add("Invalid GRIB-2 message: g2_getfld() status=%d", status);
            return (2 == status) ? 2 : 1;
        }

        /* "g2Msg.gfld" is allocated */

        /* Initialize strings in Geminfo structure */
        (void)memset(gemInfo.cproj, 0, sizeof(gemInfo.cproj));
        (void)memset(gemInfo.parm, 0, sizeof(gemInfo.parm));
        (void)memset(gemInfo.gdattm1, 0, sizeof(gemInfo.gdattm1));
        (void)memset(gemInfo.gdattm2, 0, sizeof(gemInfo.gdattm2));

        /*
         * In the original code, the last field determined the model ID.
         */
        if (lastField)
            model_id = g2Msg.gfld->ipdtmpl[4];

        /*
         * This assignment to "grid_id" isn't under the above "lastField"
         * conditional because "decode_g2gnum()" might have side-effects upon
         * which "gb2_2gem()" depends.
         */
        grid_id = (g2Msg.gfld->griddef == 0)
            ? decode_g2gnum(g2Msg.gfld)
            : g2Msg.gfld->griddef;

        gb2_2gem(&g2Msg, &gemInfo, tbllist, &status);

        if (status) {
            log_add("Couldn't decode GRIB2 message. WMO header=\"%s\"",
                    wmohead);
            log_flush_error();

            if (lastField) {
                (void)strcpy(fdats, "FHRS"); /* safe */
                (void)strcpy(levelstmp, "LVL"); /* safe */
            }
        }
        else {
            char g2name[13];          /**< Name of product/parameter */
            int  ilen;                /**< Length of resulting string */

            (void)strcpy(g2name, gemInfo.parm); /* both 13 bytes */
            cst_rmbl(g2name, g2name, &ilen, &status);

            if (iField)
                strBuf_appendString(paramNames, ";");
            strBuf_appendString(paramNames, g2name);

            cst_rxbl(gemInfo.unit, gemInfo.unit, &ilen, &status);
            if (ilen == 0)
                (void)strcpy(gemInfo.unit, "-"); /* safe */

            cst_rmbl(gemInfo.gdattm1, gemInfo.gdattm1, &ilen, &status);
            cst_rmbl(gemInfo.gdattm2, gemInfo.gdattm2, &ilen, &status);

            /*
             * In the original code, the last field determined the following
             * parameters.
             */
            if (lastField) {
                static char  strBuf[5];       /* Holds 4-char string */
                static char* strptr = strBuf; /* For "cst_itoc()" */

                if (ilen > 0)
                    (void)snprintf(fdats, sizeof(fdats), "%s-%s",
                            gemInfo.gdattm1, gemInfo.gdattm2);
                else
                    (void)snprintf(fdats, sizeof(fdats), "%s",
                            gemInfo.gdattm1);

                for (ilen = 1; ilen > 0;
                        cst_rmst(fdats, "/", &ilen, fdats, &status));

                cst_itoc(&gemInfo.vcord, 1, &strptr, &status);

                if (gemInfo.level[1] == -1)
                    (void)snprintf(levelstmp, sizeof(levelstmp), "%d %s %s",
                            gemInfo.level[0], gemInfo.unit, strptr);
                else
                    (void)snprintf(levelstmp, sizeof(levelstmp), "%d-%d %s %s",
                            gemInfo.level[0], gemInfo.level[1], gemInfo.unit,
                            strptr);
            }
        }

        g2_free(g2Msg.gfld);
        g2Msg.gfld = NULL;
    }

    /*
     * See if the WMO header can be used for grid 0 products
     */
    if ((grid_id == 0) && (strlen(wmohead) > 11) && (wmohead[7] == 'K') &&
            (wmohead[8] == 'W')) {
        int wmoGridId = wmo_to_gridid(&wmohead[0], &wmohead[2]);

        if (wmoGridId > 0)
            grid_id = wmoGridId;
    }

    (void)snprintf(ident, identSize, "grib2/%s/%s/#%03d/%s/%s/%s",
            s_pds_center((int)listsec1[0], (int)listsec1[1]),
            s_pds_model((int)listsec1[0], model_id),
            grid_id,
            fdats,
            strBuf_toString(paramNames),
            levelstmp);

    return 0;
#endif
}
Пример #22
0
// OCaml handler to free a GRIB field when it is GC'd
void finalize_gribfield( value ml_field ) {
    gribfield *field;
    field = Gribfield_val( ml_field );
    g2_free( field );
    return;
}
Пример #23
0
int cp_bgn_dec(dig_t *out, gt_t in[4], bgn_t prv) {
	int i, result = STS_ERR;
	g1_t g;
	g2_t h;
	gt_t t[4];
	bn_t n, r, s;

	bn_null(n);
	bn_null(r);
	bn_null(s);
	g1_null(g);
	g2_null(h);

	TRY {
		bn_new(n);
		bn_new(r);
		bn_new(s);
		g1_new(g);
		g2_new(h);
		for (i = 0; i < 4; i++) {
			gt_null(t[i]);
			gt_new(t[i]);
		}

		gt_exp(t[0], in[0], prv->x);
		gt_exp(t[0], t[0], prv->x);

		gt_mul(t[1], in[1], in[2]);
		gt_exp(t[1], t[1], prv->x);
		gt_inv(t[1], t[1]);

		gt_mul(t[3], in[3], t[1]);
		gt_mul(t[3], t[3], t[0]);

		gt_get_ord(n);
		g1_get_gen(g);
		g2_get_gen(h);

		bn_mul(r, prv->x, prv->y);
		bn_sqr(r, r);

		bn_mul(s, prv->x, prv->y);
		bn_mul(s, s, prv->z);
		bn_sub(r, r, s);
		bn_sub(r, r, s);

		bn_sqr(s, prv->z);
		bn_add(r, r, s);
		bn_mod(r, r, n);
		pc_map(t[1], g, h);
		gt_exp(t[1], t[1], r);

		gt_copy(t[2], t[1]);

		if (gt_is_unity(t[3]) == 1) {
			*out = 0;
			result = STS_OK;
		} else {
			for (i = 0; i < INT_MAX; i++) {
				if (gt_cmp(t[2], t[3]) == CMP_EQ) {
					*out = i + 1;
					result = STS_OK;
					break;
				}
				gt_mul(t[2], t[2], t[1]);
			}
		}
	} CATCH_ANY {
		result = STS_ERR;
	} FINALLY {
		bn_free(n);
		bn_free(r);
		bn_free(s);
		g1_free(g);
		g2_free(h);		
		for (i = 0; i < 4; i++) {
			gt_free(t[i]);
		}		
	}

	return result;
}
Пример #24
0
void	grib2name ( char *filename, int seqno,  char *data, size_t sz, char *ident )
{
int i, n, ier, ilen;
int unpack=0, expand=0;
g2int  listsec0[3],listsec1[13],numlocal;
int model_id, grid_id;
char g2name[13], fdats[80];
char prodtmp[255];
char levelstmp[80];
char prods[128];
static char datyp[]="grib2", slashstr[]="/";
static int tblinit=0;
static char *strptr[5];

Gribmsg curr_g2;
Geminfo curr_gem;

static char g2tables[5][LLMXLN] = { 0 }, *tbllist[5];

curr_g2.cgrib2 = (unsigned char *)data;
curr_g2.mlength = sz;
curr_g2.gfld = NULL;
curr_g2.field_tot = 0;

if ( !tblinit)
    {
      for (i = 0; i < 5; i++)
        tbllist[i] = g2tables[i];
      tblinit = !0;
    }


/* modify below to pass message size as a failsafe check */
/*if ( ( ier = g2_info ( curr_g2.cgrib2, listsec0,listsec1, &(curr_g2.field_tot), &numlocal) ) != 0 ) */
if ( ( ier = g2_info ( curr_g2.cgrib2, curr_g2.mlength, listsec0,listsec1, &(curr_g2.field_tot), &numlocal) ) != 0 )
	return;

prods[0] = '\0';
for ( n=0; n < curr_g2.field_tot; n++)
   {
   ier=g2_getfld( curr_g2.cgrib2, curr_g2.mlength, n+1, unpack, expand,
           &curr_g2.gfld);

   /* initialize strings in geminfo structure */
   memset ( curr_gem.cproj, 0, sizeof(curr_gem.cproj));
   memset ( curr_gem.parm, 0, sizeof(curr_gem.parm));
   memset ( curr_gem.gdattm1, 0, sizeof(curr_gem.gdattm1));
   memset ( curr_gem.gdattm2, 0, sizeof(curr_gem.gdattm2));
   model_id = curr_g2.gfld->ipdtmpl[4];
   grid_id = curr_g2.gfld->griddef;

   gb2_2gem (&curr_g2, &curr_gem, tbllist, &ier);

   if ( ier != 0 )
      {
      sprintf(g2name,"UNK\0");
      sprintf(levelstmp,"LVL\0");
      sprintf(fdats,"FHRS\0");
      }
   else
      {
      sprintf(g2name,"%s\0",curr_gem.parm);
      cst_rmbl (g2name, g2name, &ilen, &ier );
      if ( n > 0 ) strncat ( prods, ";", 1);
      sprintf(prods+strlen(prods),"%s\0",g2name);

      strptr[0] = (char *)malloc(12);
      cst_itoc ( &curr_gem.vcord, 1, (char **)(&strptr), &ier);
     
      cst_rxbl (curr_gem.unit, curr_gem.unit, &ilen, &ier); 
      if ( ilen == 0 ) sprintf (curr_gem.unit, "-\0"); 
      if ( curr_gem.level[1] == -1 )
	 sprintf(levelstmp,"%d %s %s\0",curr_gem.level[0],curr_gem.unit,strptr[0]);
      else
         sprintf(levelstmp,"%d-%d %s %s\0",curr_gem.level[0],curr_gem.level[1],curr_gem.unit,strptr[0]);

      cst_rmbl (curr_gem.gdattm1, curr_gem.gdattm1, &ilen, &ier );
      cst_rmbl (curr_gem.gdattm2, curr_gem.gdattm2, &ilen, &ier );
      if ( ilen > 0 )
         sprintf(fdats,"%s-%s\0",curr_gem.gdattm1,curr_gem.gdattm2);
      else
         sprintf(fdats,"%s\0",curr_gem.gdattm1);

      ilen = 1;
      while ( ilen > 0 ) cst_rmst(fdats, slashstr, &ilen, fdats, &ier);

      free(strptr[0]);
      }

   g2_free(curr_g2.gfld);
   curr_g2.gfld = NULL;
   }

sprintf(prodtmp,"%s/%s/%s/#%03d/%s/%s/%s! %06d\0",
		datyp,
                s_pds_center((int)listsec1[0],(int)listsec1[1]),
		s_pds_model((int)listsec1[0],model_id),
		grid_id,
		fdats,
                prods,
                levelstmp,seqno);

if(strlen(filename) < 253)
  {
    strcpy(ident,filename);
    strncat(ident," !",2);
    strncat(ident,prodtmp,253-strlen(filename));
  }
else
  {
    strncpy(ident,filename,255);
    ident[255] = '\0';
  }

return;
}
Пример #25
0
int cp_psb_ver(g1_t a, g1_t b, uint8_t *msgs[], int lens[], g2_t g, g2_t x,
		g2_t y[], int l) {
	g1_t p[2];
	g2_t q[2];
	gt_t e;
	bn_t m, n;
	int i, result = 1;

	g1_null(p[0]);
	g1_null(p[1]);
	g2_null(q[0]);
	g2_null(q[1]);
	gt_null(e);
	bn_null(m);
	bn_null(n);

	TRY {
		g1_new(p[0]);
		g1_new(p[1]);
		g2_new(q[0]);
		g2_new(q[1]);
		gt_new(e);
		bn_new(m);
		bn_new(n);

		if (g1_is_infty(a)) {
			result = 0;
		}

		/* Check that e(a, x \prod y_i^m_i) = e(b, g). */
		g1_copy(p[0], a);
		g1_copy(p[1], b);
		g2_copy(q[0], x);
		g1_get_ord(n);
		for (i = 0; i < l; i++) {
			bn_read_bin(m, msgs[i], lens[i]);
			bn_mod(m, m, n);
			g2_mul(q[1], y[i], m);
			g2_add(q[0], q[0], q[1]);
		}
		g2_norm(q[0], q[0]);
		g2_copy(q[1], g);
		g2_neg(q[1], q[1]);
		pc_map_sim(e, p, q, 2);
		if (!gt_is_unity(e)) {
			result = 0;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		g1_free(p[0]);
		g1_free(p[1]);
		g2_free(q[0]);
		g2_free(q[1]);
		gt_free(e);
		bn_free(m);
		bn_free(n);
	}
	return result;
}
Пример #26
0
int main(int argc, char **argv) {
    FILE *in;
    unsigned char *msg, *sec[9];
    long int last_pos;
    struct stat stat_buf;  /* for type of grib input file */

    int file_arg, i, j, num_submsgs;
    int n_arg;
    unsigned int k, ndata;
    float *data;
    double *ddata, ref;

#ifdef USE_G2CLIB
    float missing_c_val_1, missing_c_val_2;
    g2int *bitmap, has_bitmap;
    g2float *g2_data;
    int ii;
#endif

    struct ARGLIST arglist[N_ARGLIST];
    int narglist = 0;
    const char *new_argv[N_ARGLIST];
    void *local[N_ARGLIST];
    int has_inv_option, last_submsg;
    int err, new_GDS, gdt, pdt, center;
    unsigned char dscale[2] = {0,0};

    inv_file = stdout;
//    jas_init();

//  gctpc initialiation
    init(-1,-1,"gctpc_1,txt", "gctpc_2.txt");

    data = NULL;
    ndata = 0;

    /* no arguments .. help screen */
    if (argc == 1) {
	// f_help(-1,NULL,NULL,0,inv_out,local,"most");
	mode = -1;
	data = NULL;
	ndata = 0;
	*inv_out = 0;
	f_h(call_ARG0(inv_out,NULL));
	fprintf(inv_file, "%s\n", inv_out);
	eof_bin(); eof_string();
	exit(8);
    }

    setup_user_gribtable();

    /* copy argv */

    for (i = 0; i < argc; i++) {
	new_argv[i] = argv[i];
    }

    /* scan for "inv" and input file */
    has_inv_option = 0;
    file_arg = 0;
    for (i = 1; i < argc; i++) {
	if (new_argv[i][0] != '-') {
	    /* must be filename */
            file_arg = i;
            continue;
        }
	/* must be an option */
	for (j = 0; j < nfunctions; j++) {
	    if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) {
	        if (functions[j].type == inv) has_inv_option = 1;
		i += functions[j].nargs;
                break;
            }
        }
    }

    /* if no inv option, use default inventory .. put it at end */

    if (has_inv_option == 0) {
	for (i = 0; i < argc; i++) {
	    new_argv[i] = new_argv[i];
	}
	new_argv[argc++] = "-s";
    } 


    /* parse parameters */
    file_arg = 0;
    for (i = 1; i < argc; i++) {

	if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0) ) {
	    /* must be filename */
	    if (file_arg == 0) {
		file_arg = i;
		continue;
	    } else {
		fatal_error("too many grib files .. 2nd=%s", new_argv[i]);
	    }
	}

	/* must be an option */

	for (j = 0; j < nfunctions; j++) {
	    if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) {
#ifdef DEBUG
		fprintf(stderr,"match .. -%s %d args\n",  functions[j].name, functions[j].nargs);
#endif
                /* add to function argument list */
		arglist[narglist].fn = j;
		arglist[narglist].i_argc = i+1;

	        if (functions[j].type == inv) has_inv_option = 1;

		i += functions[j].nargs;
		if (i >= argc) fatal_error("missing arguments option=%s",functions[j].name);
		narglist++;
		break;
	    }
	}

	if (j == nfunctions) {
	    fatal_error("unknown option %s", new_argv[i]);
	}
    }

    if (has_inv_option == 0) {
        fatal_error("missing arguments on last option","");
    }

    /* initialize options mode = -1 */

#ifdef DEBUG
    fprintf(stderr,"init options narglist %d\n",narglist);
#endif

    for (j = 0; j < narglist; j++) {
	inv_out[0] = 0;
	n_arg = functions[arglist[j].fn].nargs;
        err = 0;
        if (n_arg == 0) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j);
	else if (n_arg == 1) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc]);
	else if (n_arg == 2) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1]);
	else if (n_arg == 3) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],new_argv[arglist[j].i_argc+2]);
	else if (n_arg == 4) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
	else if (n_arg == 5) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4]);
	else if (n_arg == 6) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
	else if (n_arg == 7) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
		new_argv[arglist[j].i_argc+6]);
	else if (n_arg == 8) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
		new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);

        if(inv_out[0] != 0)  fprintf(inv_file, "%s", inv_out);
        if (err) {
	    err_bin(); err_string();
	    exit(8);
	}
    }

    if (file_arg == 0 && argc > 1) fatal_error("no input file", "");
    if (latlon == 1 && output_order_wanted != wesn) 
           fatal_error("latitude-longitude information is only available with -order we:sn","");

    /* open input file */

    seq_input = 0;
    if (strcmp(new_argv[file_arg],"-") == 0) {
	seq_input = 1;
        in = stdin;
        if (mode == 98) fprintf(stderr, "grib input is stdin\n");
    }
    else { 
        if (stat(new_argv[file_arg], &stat_buf) != -1) {
	    if (S_ISREG(stat_buf.st_mode)) {
                if (mode == 98) fprintf(stderr, "grib input is a regular file\n");
	    }
	    else if (S_ISDIR(stat_buf.st_mode)) {
	        fatal_error("grib input is a directory: %s",new_argv[file_arg]);
	    }
	    else if (S_ISCHR(stat_buf.st_mode)) {
	        seq_input = 1;
                 if (mode == 98) fprintf(stderr, "grib input is a char device\n");
	    }
	    else if (S_ISBLK(stat_buf.st_mode)) {
	        seq_input = 1;
                if (mode == 98) fprintf(stderr, "grib input is a block device\n");
	    }
	    else if (S_ISFIFO(stat_buf.st_mode)) {
	        seq_input = 1;
	        if (mode == 98) fprintf(stderr, "grib input is a fifo device\n");
	    }
	    else {
	        if (mode == 98) fprintf(stderr, "grib input has an unknown type\n");
	    }
	}

	if ((in = fopen(new_argv[file_arg],"rb")) == NULL) {
            fatal_error("could not open file: %s", new_argv[file_arg]);
	}
    }

    /* sequential input - can not do random access */
    if (seq_input && input == inv_mode) fatal_error("wgrib2 cannot random access grib input file","");

    ndata = 0;
    data = NULL;
    ddata = NULL;
    msg_no = 1;
    inv_no = 0;
    len = pos = 0;
    submsg = 0;
    msg = NULL;

    if ((old_gds = (unsigned char *) malloc(GDS_max_size * sizeof(char)) ) == NULL) {
	fatal_error("memory allocation problem old_gds in wgrib2.main","");
    }
    
    last_pos = -1;
    last_submsg = -1;

    /* if dump mode .. position io stream */
    if (input == dump_mode) {
        while (msg_no < dump_msg) {
	    msg = seq_input ?  rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) :
	            rd_grib2_msg(in, &pos, &len, &num_submsgs);
            if (msg == NULL) fatal_error_i("record %d not found", dump_msg);
            last_pos = pos;
            pos += len;
            msg_no++;
        }
#ifdef DEBUG
        printf("dump mode msg=%d\n", msg_no);
#endif
    }

    /* 
     * submsg = 0 .. beginning of unread record
     * submsg = i .. start at ith submsg
     * num_submsgs = number of submessages in grib message
     */

    /* inventory loop */ 

    for (;last_message == 0;) {

        /* need position and submessage number of message */
        if (input == inv_mode || input == dump_mode) {
            if (input == inv_mode) {
                if (rd_inventory(&msg_no,&submsg, &pos)) break;
            }
            else if (input == dump_mode) {
                if (dump_msg == -1) break;
                submsg = dump_submsg;
                dump_msg = -1;
	    }

            if (pos != last_pos) {
		msg = seq_input ?  rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) :
	            rd_grib2_msg(in, &pos, &len, &num_submsgs);
	        if (msg == NULL) {
                    fatal_error_i("grib message #%d not found", msg_no);
                    break;
                }
                last_pos = pos;
		last_submsg = -1;
            }

            if (pos == last_pos && submsg == last_submsg + 1) {
                /* read previous submessage */
		if (parse_next_msg(sec) != 0) {
                    fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, submsg);
                    break;
		}
            }
            else {
                /* need to get desired submessage into sec */
		if (parse_1st_msg(sec) != 0) {
                    fprintf(stderr,"\n*** grib message #%d.1 not found ***\n\n", msg_no);
                    break;
		}
                for (i = 2; i <= submsg; i++) {
		    if (parse_next_msg(sec) != 0) {
                        fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, i);
                        break;
                    }
		}
	    }
            last_submsg = submsg;
	}
        else if (input == all_mode) {
	    if (submsg == 0) {
		msg = seq_input ?  rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) :
	            rd_grib2_msg(in, &pos, &len, &num_submsgs);
		if (msg == NULL) break;
                submsg = 1;
	    }
	    else if (submsg > num_submsgs) {
		pos += len;
                msg_no++;
		msg = seq_input ?  rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) :
	            rd_grib2_msg(in, &pos, &len, &num_submsgs);
		if (msg == NULL) break;
                submsg = 1;
	    }
            if (submsg == 1) {
		if (parse_1st_msg(sec) != 0) {
		    fprintf(stderr,"illegal format: parsing 1st submessage\n");
		}
            }
            else {
		if (parse_next_msg(sec) != 0) {
                    fprintf(stderr,"illegal format: parsing submessages\n");
                }
	    }
	}
        if (only_submsg > 0 && only_submsg != submsg) {
	    submsg++;
	    continue;
	}

	if (for_mode) {
	    if (msg_no < for_start || msg_no > for_end || ((msg_no - for_start) % for_step) != 0) {
	        if (msg_no > for_end && input != inv_mode) last_message = 1;
		submsg++;
		continue;
	    }
	}

#ifdef USE_REGEX

	/* move inv_no++ before match_inv is made */
	inv_no++;
        if (match) {
	   inv_out[0] = 0;
	   if (num_submsgs > 1) {
	       sprintf(inv_out,"%d.%d:", msg_no, submsg);
	   }
           else {
	       sprintf(inv_out,"%d:", msg_no);
	   }

           // f_match_inv(0, sec, NULL, 0, inv_out+strlen(inv_out), NULL);
           f_match_inv(call_ARG0(inv_out+strlen(inv_out), NULL));

           if (is_match(inv_out) != 0) {
              submsg++;
	      inv_no--;
              continue;
           }
        }
#endif
	match_flag = 0;

        if (for_n_mode) {
            if (inv_no < for_n_start || inv_no > for_n_end || ((inv_no - for_n_start) % for_n_step) != 0) {
                if (inv_no > for_n_end) last_message = 1;
                submsg++;
                continue;
            }
        }

        /* see if new GDS */

	if ((i = GB2_Sec3_size(sec)) != old_GDS_size) {
	    new_GDS = 1;
	}
	else {
	    new_GDS = 0;
	    for (j = 0; j < i; j++) {
		if (old_gds[j] != sec[3][j]) new_GDS = 1;
	    }
	}
	if (new_GDS) {
	    GDS_change_no++;
	    if (i > GDS_max_size) {
		free(old_gds);
		GDS_max_size = i;
    		if ((old_gds = (unsigned char *) malloc(GDS_max_size) ) == NULL) {
			fatal_error("memory allocation problem old_gds in wgrib2.main","");
		}
	    }
	    for (j = 0; j < i; j++) {
		old_gds[j] = sec[3][j];
            }
	    old_GDS_size = i;
	    /* update grid information */
            get_nxny(sec, &nx, &ny, &npnts, &res, &scan);	 /* get nx, ny, and scan mode of grid */
	    output_order = (nx == -1 || ny == -1) ? raw : output_order_wanted;

            if (latlon) {
		i = 1;
		if (use_gctpc && output_order == wesn) {		/* use gctpc to get lat lon values */
		   i = gctpc_get_latlon(sec, &lon, &lat);
		}
		if (i) get_latlon(sec, &lon, &lat);			 /* get lat lon of grid points */
	    }
	}

	/* Decode NDFD WxText */
	if (WxText) mk_WxKeys(sec);

	// any fixes to raw grib message before decode need to be placed here
	if (fix_ncep_2_flag) fix_ncep_2(sec);
	if (fix_ncep_3_flag) fix_ncep_3(sec);
	if (fix_ncep_4_flag) fix_ncep_4(sec);

#ifdef CHECK
	j = code_table_5_0(sec);		// type of compression

	/* yes this can be simplified but want to split it up in case other decoders have problems */
	if (j == 0 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib/grib-api simple decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if ((j == 2 || j == 3) && int2(sec[5]+17) != 0 && int4(sec[5] + 31) == 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib complex decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if (j == 40 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib jpeg deocde may differ from WMO standard, use use -g2clib 0 for WMO standard\n");
	if (j == 41 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib/grib-api png decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
#endif

#ifdef CHECK
	/* check the size of Section 7 */
	/* code to check the other sizes needs to be placed in decode routines */

	j = code_table_5_0(sec);		// type of compression
	if (j == 0) {		/* simple */
	    /* to avoid overflow on 32 bit machines */
	    /* old:  k = (GB2_Sec5_nval(sec) * sec[5][19] + 7) / 8 + 5; */
	    k = 5 + (GB2_Sec5_nval(sec)/8) * sec[5][19] +  (GB2_Sec5_nval(sec)%8) * (sec[5][19]/8)
	    	+ ( (GB2_Sec5_nval(sec)%8) * (sec[5][19]%8) + 7) / 8;

	    if (k != GB2_Sec7_size(sec)) {
		fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec));
		if (decode) fatal_error("Section 7 size, mismatch, simple packing","");
	    }
	}
	else if (j == 4) {		/* IEEE */
	    k = GB2_Sec5_nval(sec) * 4 + 5;
	    if (k != GB2_Sec7_size(sec)) {
		fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec));
		if (decode) fatal_error("Section 7 size, mismatch, IEEE packing","");
	    }
	}
#endif

	if (decode) {

#ifdef CHECK
            if (code_table_6_0(sec) == 0) {                         // has bitmap
                k = GB2_Sec3_npts(sec) -  GB2_Sec5_nval(sec);
                if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec)))
                    fatal_error_ii("inconsistent number of bitmap points sec3-sec5: %d sec6: %d",
			k, missing_points(sec[6]+6, GB2_Sec3_npts(sec)));
            }
            else if (code_table_6_0(sec) == 255) {                  // no bitmap
                if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec))
                    fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d",
                        GB2_Sec3_npts(sec), GB2_Sec5_nval(sec));
            }
#endif

            /* allocate data */
            if (GB2_Sec3_npts(sec) != ndata) {
                if (ndata) free(data);
                ndata = GB2_Sec3_npts(sec);
                if (ndata) {
                    data = (float *) malloc(ndata * sizeof(float));
                    if (data == NULL) fatal_error("main: memory allocation failed data","");
                }
                else { data = NULL; }
            }

	    j = code_table_5_0(sec);		// type of compression
	    gdt = code_table_3_1(sec);		// grid type
            pdt = GB2_ProdDefTemplateNo(sec);   // product defintion template

            /* USE G2CLIB */

#ifdef USE_G2CLIB
            if (use_g2clib == 2) {
                err = g2_getfld(msg,submsg,1,1,&grib_data);
                if (err != 0) fatal_error_ii("Fatal g2clib decode err=%d msg=%d", err, msg_no);
                free_gribfield = 1;

                has_bitmap = grib_data->ibmap;
                g2_data = &(grib_data->fld[0]);
                if (has_bitmap == 0 || has_bitmap == 254) {
                    bitmap = grib_data->bmap;
                    for (i = 0; i < ndata; i++) {
                         data[i] = (bitmap[i] == 0) ? UNDEFINED : g2_data[i];
                    }
                }
                else {
                    for (i = 0; i < ndata; i++) {
                        data[i] = g2_data[i];
                    }
                }

                /* complex packing uses special values for undefined */
                ii = sub_missing_values(sec, &missing_c_val_1, &missing_c_val_2);
                if (ii == 1) {
                    for (i = 0; i < ndata; i++) {
                        if (data[i] == missing_c_val_1) data[i] = UNDEFINED;
                    }
                }
                else if (ii == 2) {
                    for (i = 0; i < ndata; i++) {
                        if (data[i] == missing_c_val_1) data[i] = UNDEFINED;
                        if (data[i] == missing_c_val_2) data[i] = UNDEFINED;
                    }
                }
            }
#endif

            /* USE INTERNAL DECODER */

            if (use_g2clib != 2) {
                center = GB2_Center(sec);
                if (use_g2clib == 1) {	// introduce g2clib constant field error
		    /* g2clib ignores decimal scaling for constant fields make internal decoders look like g2clib*/
                    if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) ||
                         (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19] == 0) ||
                         (center == NCEP && j == 40000 && sec[5][19] == 0) || 
                         (center == NCEP && j == 40010 && sec[5][19] == 0)  ) {
			dscale[0] = sec[5][17];
			dscale[1] = sec[5][18];
			sec[5][17] = sec[5][18] = 0;
                    }
		}

		err = unpk_grib(sec, data);
                if (err != 0) fatal_error_i("Fatal decode packing type %d",err);

		if (use_g2clib == 1) {  // fix up data 
		    /* restore decimal scaling */
                    if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) ||
                         (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19]) ||
                         (center == NCEP && j == 40000 && sec[5][19] == 0) || 
                         (center == NCEP && j == 40010 && sec[5][19] == 0)  ) {
			sec[5][17] = dscale[0];
			sec[5][18] = dscale[1];
                    }
		}
            }

	    /* convert to standard output order we:sn */

	    if (output_order_wanted == wesn) to_we_sn_scan(data);
	    else if (output_order_wanted == wens) to_we_ns_scan(data);
	}
        else {
	    if (ndata) free(data);
            ndata = 0;
            data = NULL;
        }

	/* get scaling parameters */

	use_scale = scaling(sec, &ref, &dec_scale, &bin_scale, &i) == 0;


	if (num_submsgs > 1) {
	    fprintf(inv_file, "%d.%d%s%ld", msg_no, submsg, ":", pos);
	}
        else {
	    fprintf(inv_file, "%d%s%ld", msg_no, ":", pos);
	}

	for (j = 0; j < narglist; j++) {

	    /* skip execution if match_flag == 1 */
	    /* an output option acts as endif for match_flag */
	    if (match_flag == 1) {
                if (functions[arglist[j].fn].type == output)  match_flag = 0;
		continue;
	    }


            // if (functions[arglist[j].fn].type == inv) fprintf(inv_file, item_deliminator);
            if (functions[arglist[j].fn].type == inv) fprintf(inv_file, "%s", item_deliminator);
            if (functions[arglist[j].fn].type != setup) {
		inv_out[0] = 0;
	        n_arg = functions[arglist[j].fn].nargs;
		if (n_arg == 0) 
                    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j);
		else if (n_arg == 1)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			 new_argv[arglist[j].i_argc]);
		else if (n_arg == 2)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]);
		else if (n_arg == 3)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2]);
		else if (n_arg == 4)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
		else if (n_arg == 5)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4]);
		else if (n_arg == 6)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
		else if (n_arg == 7)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6]);
		else if (n_arg == 8)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);

        	if(inv_out[0] != 0)  fprintf(inv_file, "%s", inv_out);
           }
	}

#ifdef CHECK
	if (!decode) {
            if (code_table_6_0(sec) == 0) {                         // has bitmap
                k = GB2_Sec3_npts(sec) -  GB2_Sec5_nval(sec);
                if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec)))
                    fatal_error_ii("inconsistent number of bitmap points sec3-sec5: %d sec6: %d",
			k, missing_points(sec[6]+6, GB2_Sec3_npts(sec)));
            }
            else if (code_table_6_0(sec) == 255) {                  // no bitmap
                if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec))
                    fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d",
                        GB2_Sec3_npts(sec), GB2_Sec5_nval(sec));
            }
	}
#endif

	submsg++;

#ifdef USE_G2CLIB
	if (free_gribfield) { g2_free(grib_data); free_gribfield = 0;}
#endif

	// fprintf(inv_file, "\n");
	fprintf(inv_file, "%s",end_inv);
	if (flush_mode) fflush(inv_file);
	if (dump_msg > 0) break;
    }

    /* finalize all functions, call with mode = -2 */

    for (j = 0; j < narglist; j++) {
        if (functions[arglist[j].fn].type != setup) {
	    n_arg = functions[arglist[j].fn].nargs;
	    inv_out[0] = 0;
	    if (n_arg == 0) 
                functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j);
	    else if (n_arg == 1)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc]);
	    else if (n_arg == 2)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]);
	    else if (n_arg == 3)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2]);
	    else if (n_arg == 4)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
	    else if (n_arg == 5)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4]);
	    else if (n_arg == 6)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
	    else if (n_arg == 7)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6]);
	    else if (n_arg == 8)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);
            // if (inv_out[0]) fprintf(stderr, "%s\n", inv_out);
            if (inv_out[0]) fprintf(stderr, "%s%s", inv_out, end_inv);
        }
    }
    eof_bin(); eof_string();
    exit(0);
}
Пример #27
0
bool GribV2::loadFile(QString fileName) {

    FILE * fptr=NULL;
    int msg=0;

    this->fileName=fileName;

    QTime tLoad;
    int m_sec_readCgrib=0;
    int m_sec_ginfo=0;
    int m_sec_g2_getfld=0;
    int m_sec_grecConst=0;
    int m_sec_endLoop=0;

    qWarning() << "GV2 loading " << fileName;

    g2int lskip=0,lgrib=0,iseek=0;
    unsigned char *cgrib; // msg buffer
    g2int ierr,listsec0[3],listsec1[13],numfields,numlocal;


    std::string fname = qPrintable(fileName);
    if(fileName == "") return false;

    gribfield  *gfld=NULL;

    ok=false;

    fptr=fopen(fname.c_str(),"rb");
    if(!fptr) {
        qWarning() << "Can't open Grib2 file (in loadFile): " << fileName;
        return false;
    }

    fseek(fptr,0,SEEK_END);
    fileSize=ftell(fptr);
    rewind(fptr);

    /* clean data structure + iso lines */
    clean_all_vectors();
    Util::cleanListPointers(listIsobars);
    Util::cleanListPointers(listIsotherms0);

    for(;;) {

        msg++;

        seekgb(fptr,iseek,32000,&lskip,&lgrib);
        if (lgrib == 0) break;    // end loop at EOF or problem

        cgrib=(unsigned char *)malloc(lgrib);

        fseek(fptr,lskip,SEEK_SET);
        tLoad.start();
        fread(cgrib,sizeof(unsigned char),lgrib,fptr);
        m_sec_readCgrib+=tLoad.elapsed();
        //qWarning() << "Size of cgrib: " << lgrib << ", skip=" << lskip;
        //qWarning() << "Bytes read from file: " << bRead;
        //qWarning() << "EOF=" << feof(fptr) << ", ferror=" << ferror(fptr);
        //qWarning() << "File pos=" << ftell(fptr);
        //qWarning() << "End of grib=" << cgrib[lgrib-4] << cgrib[lgrib-3] << cgrib[lgrib-2] << cgrib[lgrib-1];

        iseek=lskip+lgrib;

        tLoad.start();
        ierr=g2_info(cgrib,listsec0,listsec1,&numfields,&numlocal);
        m_sec_ginfo+=tLoad.elapsed();
        if(ierr) {
            qWarning() << "msg " << msg << ": g2_info error num=" << ierr;
            fclose(fptr);
            return false;
        }



        // accepting only GRIB2 with discipline=0 => Meteorological product (table 0.0)
        if(listsec0[1]!=2 || (listsec0[0]!=0 && listsec0[0]!=10)) {
            qWarning() << "msg " << msg << ": wrong version " << listsec0[1] << ", or discipline: " << listsec0[0];
            continue;
        }

        if(listsec1[4]!=1) {
            qWarning() << "msg " << msg << ": wrong reference time type: " << listsec1[4];
            continue;
        }

        /* loop on th fields => 1 field = 1 GribRecord */
        //qWarning() << "nb fields=" << numfields << ", nb locals=" << numlocal;

        for(int i=0;i<numfields;++i) {
            tLoad.start();
            ierr=g2_getfld(cgrib,i+1,GRB2_UNPACK,GRB2_EXPAND,&gfld);
            m_sec_g2_getfld+=tLoad.elapsed();
            if(ierr) {
                qWarning() << "msg=" << msg << "- field=" << i << ": g2_getfld error num=" << ierr;
                continue;
            }
            tLoad.start();
            GribV2Record * record = new GribV2Record(gfld,msg,i);
            m_sec_grecConst+=tLoad.elapsed();
            tLoad.start();
            if(record && record->isOk() && record->isDataKnown())
                addRecord(record);
            else
                if(record) delete record;
            g2_free(gfld);
            m_sec_endLoop+=tLoad.elapsed();
        }
        free(cgrib);
    }

    if(fptr) fclose(fptr);

    qWarning() << "GRIBV2 load finished";
    qWarning() << "NB key: " << mapGribRecords.size();
    qWarning() << "List:";
    std::map <long int, QMap<time_t,GribRecord *>* >::iterator it;
    int i=0;
    for(it=mapGribRecords.begin();it!=mapGribRecords.end();++it) {
        qWarning() << "key " << i << ": key= " << it->first << ", nb elem" << it->second->size();
        ++i;
    }

    qWarning() << "Time stat:";
    qWarning() << "\t read Cgrib: " << m_sec_readCgrib;
    qWarning() << "\t call gInfo: " << m_sec_ginfo;
    qWarning() << "\t call getFld: " << m_sec_g2_getfld;
    qWarning() << "\t const GribRecordV2: " << m_sec_grecConst;
    qWarning() << "\t End loop: " << m_sec_endLoop;

    createDewPointData();

    ok=true;
    return true;
}
Пример #28
0
int main(int argc, char **argv) {

#else

int wgrib2(int argc, const char **argv) {

#endif


//WNE    FILE *in;
    struct seq_file in_file;
    unsigned char *msg, *sec[10];	/* sec[9] = last valid bitmap */
    long int last_pos;

    int file_arg, i, j, num_submsgs;
    int n_arg;
    unsigned int k, ndata;
    int err_4_3_count;
    float *data;
    double ref;
//    double *ddata, ref;

#ifdef USE_G2CLIB
    float missing_c_val_1, missing_c_val_2;
    g2int *bitmap, has_bitmap;
    g2float *g2_data;
    int ii;
#endif

    struct ARGLIST arglist[N_ARGLIST];
    int narglist;
    const char *new_argv[N_ARGLIST];
    void *local[N_ARGLIST];
    int has_inv_option, last_submsg;
    int err, new_GDS, center;
    unsigned char dscale[2];

    init_globals();
    init_inv_out();
    ndata = 0;
    err_4_3_count = 0;

    if (initial_call) {		/* only done 1st time */
	setup_user_gribtable();
//      jas_init();
//      gctpc initialiation
        init(-1,-1,"gctpc_error,txt", "gctpc_param.txt");
        initial_call = 0;
    }

    narglist = 0;
    dscale[0] = dscale[1] = 0;
    mode = 0;

    if (fopen_file(&(rd_inventory_input), "-", "r")) fatal_error("opening stdin for rd_inventory","");
    data = NULL;
//    ddata = NULL;

#ifdef CALLABLE_WGRIB2
    if (setjmp(fatal_err)) {
	fprintf(stderr,"*** arg list to wgrib2:");
	for (i=0; i < argc; i++) {
	    fprintf(stderr," %s", argv[i]);
	}
	fprintf(stderr,"\n\n");
	if (ndata && data != NULL) free(data);
	ndata=0;
        return 1;
    }
#endif

    /* no arguments .. help screen */
    if (argc == 1) {
	mode = -1;
	inv_out[0] = 0;
	f_h(call_ARG0(inv_out,NULL));
	// fprintf(inv_file, "%s\n", inv_out);
	i = strlen(inv_out);
	inv_out[i++] = '\n';
	inv_out[i] = '\0';
        fwrite_file(inv_out, 1, i, &inv_file);
	err_bin(1); err_string(1);
        return 8;
    }

    /* copy argv */

    for (i = 0; i < argc; i++) {
	new_argv[i] = argv[i];
    }

    /* scan for "inv" and input file */
    has_inv_option = 0;
    file_arg = 0;
    for (i = 1; i < argc; i++) {
	if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0) ) {
	    /* must be filename */
	    if (file_arg == 0) {
		file_arg = i;
		continue;
	    } else {
		fatal_error_ss("too many grib files .. 1st=%s 2nd=%s", new_argv[file_arg], new_argv[i]);
	    }
	}
	/* must be an option */
	for (j = 0; j < nfunctions; j++) {
	    if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) {
	        if (functions[j].type == inv) has_inv_option = 1;
		i += functions[j].nargs;
                break;
            }
        }
	if (j == nfunctions) {
	    fatal_error("undefined option: %s", new_argv[i]);
	}
    }

    /* if no inv option, use default inventory .. put it at end */
    if (has_inv_option == 0) new_argv[argc++] = "-s";

    /* try opening the input file */
    in_file.file_type = NOT_OPEN;
    if (file_arg != 0) {
	fopen_file(&in_file, new_argv[file_arg],"rb");
    }

    /* "compile" options */
#ifdef DEBUG
    fprintf(stderr,"going to compile phase\n");
#endif
    for (i = 1; i < argc; i++) {

	/* if filename skip */
	if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0))  continue;

	/* must be an option */

	for (j = 0; j < nfunctions; j++) {
	    if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) break;
	}
	if (j == nfunctions) fatal_error("unknown option %s", new_argv[i]);

        /* add to function argument list */
	arglist[narglist].fn = j;
	arglist[narglist].i_argc = i+1;

	if (functions[j].type == inv) has_inv_option = 1;

	i += functions[j].nargs;
	if (i >= argc) fatal_error("missing arguments option=%s",functions[j].name);
	narglist++;

    }
    if (has_inv_option == 0) fatal_error("missing arguments on last option","");

    /* initialize options,  mode = -1 */

#ifdef DEBUG
    fprintf(stderr,"going to init options,  narglist %d\n",narglist);
#endif

    for (j = 0; j < narglist; j++) {
	new_inv_out();	/* inv_out[0] = 0; */
	n_arg = functions[arglist[j].fn].nargs;
        err = 0;
#ifdef DEBUG
    fprintf(stderr,"going to init option %s\n", functions[arglist[j].fn].name);
#endif
        if (n_arg == 0) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j);
	else if (n_arg == 1) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc]);
	else if (n_arg == 2) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1]);
	else if (n_arg == 3) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],new_argv[arglist[j].i_argc+2]);
	else if (n_arg == 4) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
	else if (n_arg == 5) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4]);
	else if (n_arg == 6) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
	else if (n_arg == 7) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
		new_argv[arglist[j].i_argc+6]);
	else if (n_arg == 8) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
		new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);

        // if(inv_out[0] != 0)  fprintf(inv_file, "%s", inv_out);
        if(inv_out[0] != 0) fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file);

        if (err) {
	    err_bin(1); err_string(1);
	    // cleanup
            return 8;
	}
    }

    /* error and EOF handlers have been initialized */
#ifdef DEBUG
    fprintf(stderr,"initial error and EOF handlers\n");
#endif

    if (has_inv_option == 0) fatal_error("missing arguments on last option","");
    if (in_file.file_type == NOT_OPEN) {
	if (file_arg == 0) fatal_error("no input file defined","");
	else fatal_error("missing input file %s", new_argv[file_arg]);
    }

    if (latlon == 1 && output_order_wanted != wesn) 
           fatal_error("latitude-longitude information is only available with -order we:sn","");

    if (input == inv_mode && (in_file.file_type != DISK && in_file.file_type != MEM)) 
	fatal_error("wgrib2 cannot random access grib input file","");

#ifdef DEBUG
    fprintf(stderr,"going to process data\n");
#endif

    msg_no = 1;
    inv_no = 0;
    len = pos = 0;
    submsg = 0;
    msg = NULL;

    last_pos = -1;
    last_submsg = -1;

    /* if dump mode .. position io stream */
    if (input == dump_mode) {
        while (msg_no < dump_msg) {
// //	    if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs);
//	    if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
//	    else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs);

	    msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
            if (msg == NULL) fatal_error_i("record %d not found", dump_msg);
            last_pos = pos;
            pos += len;
            msg_no++;
        }
#ifdef DEBUG
        printf("dump mode msg=%d\n", msg_no);
#endif
    }

    /* 
     * submsg = 0 .. beginning of unread record
     * submsg = i .. start at ith submsg
     * num_submsgs = number of submessages in grib message
     */

    /* inventory loop */ 

    for (;last_message == 0;) {

        /* need position and submessage number of message */
        if (input == inv_mode || input == dump_mode) {
            if (input == inv_mode) {
                if (rd_inventory(&msg_no,&submsg, &pos, &rd_inventory_input)) break;
		if (fseek_file(&in_file, pos,SEEK_SET) != 0) fatal_error("fseek_file failed","");
            }
            else if (input == dump_mode) {
                if (dump_msg == -1) break;
                submsg = dump_submsg;
                dump_msg = -1;
	    }

            if (pos != last_pos) {
// //	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs);
//	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
//		else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs);
	        msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
	        if (msg == NULL) {
                    fatal_error_i("grib message #%d not found", msg_no);
                    break;
                }
                last_pos = pos;
		last_submsg = -1;
            }

            if (pos == last_pos && submsg == last_submsg + 1) {
                /* read previous submessage */
		if (parse_next_msg(sec) != 0) {
                    fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, submsg);
                    break;
		}
            }
            else {
                /* need to get desired submessage into sec */
		if (parse_1st_msg(sec) != 0) {
                    fprintf(stderr,"\n*** grib message #%d.1 not found ***\n\n", msg_no);
                    break;
		}
                for (i = 2; i <= submsg; i++) {
		    if (parse_next_msg(sec) != 0) {
                        fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, i);
                        break;
                    }
		}
	    }
            last_submsg = submsg;
	}
        else if (input == all_mode) {
	    if (submsg == 0) {
// //	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs);
//	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
//		else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs);
	        msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
		if (msg == NULL) break;
                submsg = 1;
	    }
	    else if (submsg > num_submsgs) {
		pos += len;
                msg_no++;
// //	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs);
//	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
//		else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs);
	        msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
		if (msg == NULL) break;
                submsg = 1;
	    }
            if (submsg == 1) {
		if (parse_1st_msg(sec) != 0) {
		    fprintf(stderr,"illegal format: parsing 1st submessage\n");
		}
            }
            else {
		if (parse_next_msg(sec) != 0) {
                    fprintf(stderr,"illegal format: parsing submessages\n");
                }
	    }
	}
        if (only_submsg > 0 && only_submsg != submsg) {
	    submsg++;
	    continue;
	}

	if (for_mode) {
	    if (msg_no < for_start || msg_no > for_end || ((msg_no - for_start) % for_step) != 0) {
	        if (msg_no > for_end && input != inv_mode) last_message = 1;
		submsg++;
		continue;
	    }
	}

	/* move inv_no++ before match_inv is made */
	inv_no++;

        if (match || match_fs) {
	   inv_out[0] = 0;
	   if (num_submsgs > 1) {
	       sprintf(inv_out,"%d.%d:", msg_no, submsg);
	   }
           else {
	       sprintf(inv_out,"%d:", msg_no);
	   }

           f_match_inv(call_ARG0(inv_out+strlen(inv_out), NULL));

           if (is_match_fs(inv_out) != 0) {
              submsg++;
	      inv_no--;
              continue;
           }

#ifdef USE_REGEX
           if (is_match(inv_out) != 0) {
              submsg++;
	      inv_no--;
              continue;
           }
#endif

        }
	match_flag = 0;

        if (for_n_mode) {
            if (inv_no < for_n_start || inv_no > for_n_end || ((inv_no - for_n_start) % for_n_step) != 0) {
                if (inv_no > for_n_end) last_message = 1;
                submsg++;
                continue;
            }
        }

        /* see if new GDS */

	if ((i = (int) GB2_Sec3_size(sec)) != old_GDS_size) {
	    new_GDS = 1;
	}
	else {
	    new_GDS = 0;
	    for (j = 0; j < i; j++) {
		if (old_gds[j] != sec[3][j]) new_GDS = 1;
	    }
	}
	if (new_GDS) {
	    GDS_change_no++;
	    if (i > GDS_max_size) {
		if (GDS_max_size) free(old_gds);
		GDS_max_size = i + 100;		/* add 100 just to avoid excessive memory allocations */
    		if ((old_gds = (unsigned char *) malloc(GDS_max_size) ) == NULL) {
			fatal_error("memory allocation problem old_gds in wgrib2.main","");
		}
	    }
	    for (j = 0; j < i; j++) {
		old_gds[j] = sec[3][j];
            }
	    old_GDS_size = i;
	    /* update grid information */
            get_nxny(sec, &nx, &ny, &npnts, &res, &scan);	 /* get nx, ny, and scan mode of grid */
            get_nxny_(sec, &nx_, &ny_, &npnts, &res, &scan);	 /* get nx, ny, and scan mode of grid */

	    output_order = (nx_ < 1 || ny_ < 1) ? raw : output_order_wanted;

            if (latlon) {
		i = 1;

#ifdef USE_PROJ4
		if (use_proj4 && i != 0) {				/* use Proj4 to get lat lon values */
		    i = proj4_get_latlon(sec, &lon, &lat);
//		    if (i == 0) fprintf(stderr,"proj4_get_lat used\n");
		}
#endif

		if (use_gctpc && i != 0) {				/* use gctpc to get lat lon values */
		    i = gctpc_get_latlon(sec, &lon, &lat);
//		    if (i == 0) fprintf(stderr,"gctpc_get_lat used\n");
		}

		if (i != 0) get_latlon(sec, &lon, &lat);		 /* get lat lon of grid points using built-in code */
	    }
	}

	/* Decode NDFD WxText */
	if (WxText) mk_WxKeys(sec);

	// any fixes to raw grib message before decode need to be placed here
	if (fix_ncep_2_flag) fix_ncep_2(sec);
	if (fix_ncep_3_flag) fix_ncep_3(sec);
	if (fix_ncep_4_flag) fix_ncep_4(sec);

#ifdef CHECK
	j = code_table_5_0(sec);		// type of compression

	/* yes this can be simplified but want to split it up in case other decoders have problems */
	if (j == 0 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib/grib-api simple encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if ((j == 2 || j == 3) && int2(sec[5]+17) != 0 && int4(sec[5] + 31) == 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib complex encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if (j == 40 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib jpeg encode/deocde may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if (j == 41 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib/grib-api png encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");

	/* check the size of Section 7 */
	/* code to check the other sizes needs to be placed in decode routines */

	j = code_table_5_0(sec);		// type of compression
	if (j == 0) {		/* simple */
	    /* to avoid overflow on 32 bit machines */
	    /* old:  k = (GB2_Sec5_nval(sec) * sec[5][19] + 7) / 8 + 5; */
	    k = 5 + (GB2_Sec5_nval(sec)/8) * sec[5][19] +  (GB2_Sec5_nval(sec)%8) * (sec[5][19]/8)
	    	+ ( (GB2_Sec5_nval(sec)%8) * (sec[5][19]%8) + 7) / 8;

	    if (k != GB2_Sec7_size(sec)) {
		fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec));
		if (decode) fatal_error("Section 7 size, mismatch, simple packing","");
	    }
	}
	else if (j == 4) {		/* IEEE */
	    k = GB2_Sec5_nval(sec) * 4 + 5;
	    if (k != GB2_Sec7_size(sec)) {
		fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec));
		if (decode) fatal_error("Section 7 size, mismatch, IEEE packing","");
	    }
	}

	/* code table 4.3 can change units, warn if undefined */

	if (err_4_3_count < 2) {
	    if (code_table_4_3(sec) == 255) {
		fprintf(stderr,"** WARNING input Code Table 4.3 = 255 (undefined) **\n");
		err_4_3_count++;
	    }
        }
#endif

	if (decode) {

#ifdef CHECK
            if (code_table_6_0(sec) == 0) {                         // has bitmap
                k = GB2_Sec3_npts(sec) -  GB2_Sec5_nval(sec);
                if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec)))
                    fatal_error_uu("inconsistent number of bitmap points sec3-sec5: %u sec6: %u",
			k, missing_points(sec[6]+6, GB2_Sec3_npts(sec)));
            }
            else if (code_table_6_0(sec) == 255) {                  // no bitmap
                if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec))
                    fatal_error_uu("inconsistent number of data points sec3: %u sec5: %u",
                        GB2_Sec3_npts(sec), GB2_Sec5_nval(sec));
            }
#endif

            /* allocate data */
            if (GB2_Sec3_npts(sec) != ndata) {
		if (ndata) free(data);
                ndata = GB2_Sec3_npts(sec);
		if (ndata) {
                    data = (float *) malloc(sizeof(float) * (size_t) ndata);
                    if (data == NULL) {
			ndata = 0;
			fatal_error("main: memory allocation failed data","");
		    }
		}
                else { data = NULL; }
            }

	    j = code_table_5_0(sec);		// type of compression

            /* USE G2CLIB */

#ifdef USE_G2CLIB
            if (use_g2clib == 2) {
                err = g2_getfld(msg,submsg,1,1,&grib_data);
                if (err != 0) fatal_error_ii("Fatal g2clib decode err=%d msg=%d", err, msg_no);
                free_gribfield = 1;

                has_bitmap = grib_data->ibmap;
                g2_data = &(grib_data->fld[0]);
                if (has_bitmap == 0 || has_bitmap == 254) {
                    bitmap = grib_data->bmap;
                    for (k = 0; k < ndata; k++) {
                         data[k] = (bitmap[k] == 0) ? UNDEFINED : g2_data[k];
                    }
                }
                else {
                    for (k = 0; k < ndata; k++) {
                        data[k] = g2_data[k];
                    }
                }

                /* complex packing uses special values for undefined */
                ii = sub_missing_values(sec, &missing_c_val_1, &missing_c_val_2);
                if (ii == 1) {
                    for (k = 0; k < ndata; k++) {
                        if (data[k] == missing_c_val_1) data[k] = UNDEFINED;
                    }
                }
                else if (ii == 2) {
                    for (k = 0; k < ndata; k++) {
                        if (data[k] == missing_c_val_1) data[k] = UNDEFINED;
                        if (data[k] == missing_c_val_2) data[k] = UNDEFINED;
                    }
                }
            }
#endif

            /* USE INTERNAL DECODER */

            if (use_g2clib != 2) {
                center = GB2_Center(sec);
                if (use_g2clib == 1) {	// introduce g2clib constant field error
		    /* g2clib ignores decimal scaling for constant fields make internal decoders look like g2clib*/
                    if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) ||
                         (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19] == 0) ||
                         (center == NCEP && j == 40000 && sec[5][19] == 0) || 
                         (center == NCEP && j == 40010 && sec[5][19] == 0)  ) {
			dscale[0] = sec[5][17];
			dscale[1] = sec[5][18];
			sec[5][17] = sec[5][18] = 0;
                    }
		}

		err = unpk_grib(sec, data);
                if (err != 0) fatal_error_i("Fatal decode packing type %d",err);

		if (use_g2clib == 1) {  // fix up data 
		    /* restore decimal scaling */
                    if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) ||
                         (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19]) ||
                         (center == NCEP && j == 40000 && sec[5][19] == 0) || 
                         (center == NCEP && j == 40010 && sec[5][19] == 0)  ) {
			sec[5][17] = dscale[0];
			sec[5][18] = dscale[1];
                    }
		}
            }

	    /* convert to standard output order we:sn */

	    if (output_order_wanted == wesn) to_we_sn_scan(data, scan, npnts, nx, ny, save_translation);
	    else if (output_order_wanted == wens) to_we_ns_scan(data, scan, npnts, nx, ny, save_translation);
	}
        else {
	    if (ndata) free(data);
            ndata = 0;
            data = NULL;
        }

	/* get scaling parameters */

	use_scale = input_scale = scaling(sec, &ref, &dec_scale, &bin_scale, &i) == 0;

	/* make sure msg_no:pos is put in inv_out so that -last will work */
	new_inv_out();	// inv_out[0] = 0;
	if (num_submsgs > 1) {
	    sprintf(inv_out, "%d.%d%s%ld", msg_no, submsg, ":", pos);
	}
        else {
	    sprintf(inv_out, "%d%s%ld", msg_no, ":", pos);
	}
        // fprintf(inv_file, "%s", inv_out);
        fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file);

	for (j = 0; j < narglist; j++) {

	    /* skip execution if match_flag == 1 */
	    /* an output option acts as endif for match_flag */
	    if (match_flag == 1) {
                if (functions[arglist[j].fn].type == output)  match_flag = 0;
		continue;
	    }


            // if (functions[arglist[j].fn].type == inv) fprintf(inv_file, "%s", item_deliminator);
            if (functions[arglist[j].fn].type == inv) fwrite_file(item_deliminator, 1, strlen(item_deliminator), &inv_file);
            if (functions[arglist[j].fn].type != setup) {
		new_inv_out();	// inv_out[0] = 0;
	        n_arg = functions[arglist[j].fn].nargs;
		if (n_arg == 0) 
                    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j);
		else if (n_arg == 1)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			 new_argv[arglist[j].i_argc]);
		else if (n_arg == 2)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]);
		else if (n_arg == 3)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2]);
		else if (n_arg == 4)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
		else if (n_arg == 5)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4]);
		else if (n_arg == 6)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
		else if (n_arg == 7)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6]);
		else if (n_arg == 8)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);

        	// if(inv_out[0] != 0)  fprintf(inv_file, "%s", inv_out);
        	if(inv_out[0] != 0) fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file);
           }
	}

#ifdef CHECK
	if (!decode) {
            if (code_table_6_0(sec) == 0) {                         // has bitmap
                k = GB2_Sec3_npts(sec) -  GB2_Sec5_nval(sec);
                if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec)))
                    fatal_error_uu("inconsistent number of bitmap points sec3-sec5: %u sec6: %u",
			k, missing_points(sec[6]+6, GB2_Sec3_npts(sec)));
            }
            else if (code_table_6_0(sec) == 255) {                  // no bitmap
                if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec))
                    fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d",
                        (int) GB2_Sec3_npts(sec), (int) GB2_Sec5_nval(sec));
            }
	}
#endif

	submsg++;

#ifdef USE_G2CLIB
	if (free_gribfield) { g2_free(grib_data); free_gribfield = 0;}
#endif

	// fprintf(inv_file, "%s",end_inv);
        fwrite_file(end_inv, 1, strlen(end_inv), &inv_file);

	if (flush_mode) fflush_file(&inv_file);
	if (dump_msg > 0) break;
    }

    /* finalize all functions, call with mode = -2 */

    err = 0;
    for (j = 0; j < narglist; j++) {
//        if (functions[arglist[j].fn].type != setup) {
	    n_arg = functions[arglist[j].fn].nargs;
	    new_inv_out();	// inv_out[0] = 0;
	    if (n_arg == 0) 
                err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j);
	    else if (n_arg == 1)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc]);
	    else if (n_arg == 2)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]);
	    else if (n_arg == 3)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2]);
	    else if (n_arg == 4)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
	    else if (n_arg == 5)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4]);
	    else if (n_arg == 6)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
	    else if (n_arg == 7)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6]);
	    else if (n_arg == 8)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);
            // if (inv_out[0]) fprintf(stderr, "%s\n", inv_out);
            if (inv_out[0]) fprintf(stderr, "%s%s", inv_out, end_inv);
//        }
    }
    err_bin(0); err_string(0);
    fclose_file(&in_file);
    if (ndata) {
	ndata = 0;
	free(data);
    }
    // return 0;
    return err;
}

void set_mode(int new_mode) {
	mode = new_mode;
}