Beispiel #1
0
static GMQCC_INLINE ast_expression *fold_op_mul(fold_t *fold, ast_value *a, ast_value *b) {
    if (isfloat(a)) {
        if (isvector(b)) {
            if (fold_can_2(a, b))
                return fold_constgen_vector(fold, vec3_mulvf(fold_immvalue_vector(b), fold_immvalue_float(a)));
        } else {
            if (fold_can_2(a, b))
                return fold_constgen_float(fold, fold_immvalue_float(a) * fold_immvalue_float(b));
        }
    } else if (isvector(a)) {
        if (isfloat(b)) {
            if (fold_can_2(a, b))
                return fold_constgen_vector(fold, vec3_mulvf(fold_immvalue_vector(a), fold_immvalue_float(b)));
        } else {
            if (fold_can_2(a, b)) {
                return fold_constgen_float(fold, vec3_mulvv(fold_immvalue_vector(a), fold_immvalue_vector(b)));
            } else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && fold_can_1(a)) {
                ast_expression *out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(a), b, "xyz"))) return out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(a), b, "yxz"))) return out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(a), b, "zxy"))) return out;
            } else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && fold_can_1(b)) {
                ast_expression *out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(b), a, "xyz"))) return out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(b), a, "yxz"))) return out;
                if ((out = fold_op_mul_vec(fold, fold_immvalue_vector(b), a, "zxy"))) return out;
            }
        }
    }
    return NULL;
}
Beispiel #2
0
static int numeric_compare(const SpnValue *lhs, const SpnValue *rhs)
{
	assert(isnum(lhs) && isnum(rhs));

	if (isfloat(lhs)) {
		if (isfloat(rhs)) {
			return floatvalue(lhs) < floatvalue(rhs) ? -1
			     : floatvalue(lhs) > floatvalue(rhs) ? +1
			     :                                      0;
		} else {
			return floatvalue(lhs) < intvalue(rhs) ? -1
			     : floatvalue(lhs) > intvalue(rhs) ? +1
			     :                                    0;
		}
	} else {
		if (isfloat(rhs)) {
			return intvalue(lhs) < floatvalue(rhs) ? -1
			     : intvalue(lhs) > floatvalue(rhs) ? +1
			     :                                    0;
		} else {
			return intvalue(lhs) < intvalue(rhs) ? -1
			     : intvalue(lhs) > intvalue(rhs) ? +1
			     :                                  0;
		}
	}
}
Beispiel #3
0
static int numeric_equal(const SpnValue *lhs, const SpnValue *rhs)
{
	assert(isnum(lhs) && isnum(rhs));

	if (isfloat(lhs)) {
		return isfloat(rhs) ? floatvalue(lhs) == floatvalue(rhs)
		                    : floatvalue(lhs) == intvalue(rhs);
	} else {
		return isfloat(rhs) ? intvalue(lhs) == floatvalue(rhs)
		                    : intvalue(lhs) == intvalue(rhs);
	}
}
Beispiel #4
0
/* Return the product of two expressions */
static exp_t *
prod(exp_t *a1, exp_t *a2)
{
        exp_t *res;

        CHKNUM(a1, *);
        CHKNUM(a2, *);

        if (isfloat(a1) || isfloat(a2))
                res = nfloat(VALUE(a1) * VALUE(a2));
        else
                res = nrat(NUMER(a1) * NUMER(a2), DENOM(a1) * DENOM(a2));
        return res;
}
Beispiel #5
0
static GMQCC_INLINE ast_expression *fold_op_cmp(fold_t *fold, ast_value *a, ast_value *b, bool ne) {
    if (fold_can_2(a, b)) {
        if (isfloat(a) && isfloat(b)) {
            float la = fold_immvalue_float(a);
            float lb = fold_immvalue_float(b);
            return (ast_expression*)fold->imm_float[!(ne ? la == lb : la != lb)];
        } if (isvector(a) && isvector(b)) {
            vec3_t la = fold_immvalue_vector(a);
            vec3_t lb = fold_immvalue_vector(b);
            return (ast_expression*)fold->imm_float[!(ne ? vec3_cmp(la, lb) : !vec3_cmp(la, lb))];
        }
    }
    return NULL;
}
Beispiel #6
0
void retcode(Tree p) {
	Type ty;

	if (p == NULL) {
		if (events.returns)
			apply(events.returns, cfunc, NULL);
		return;
	}
	p = pointer(p);
	ty = assign(freturn(cfunc->type), p);
	if (ty == NULL) {
		error("illegal return type; found `%t' expected `%t'\n",
			p->type, freturn(cfunc->type));
		return;
	}
	p = cast(p, ty);
	if (retv)
		{
			if (iscallb(p))
				p = tree(RIGHT, p->type,
					tree(CALL+B, p->type,
						p->kids[0]->kids[0], idtree(retv)),
					rvalue(idtree(retv)));
			else {
				Type ty = retv->type->type;
				assert(isstruct(ty));
				if (ty->u.sym->u.s.cfields) {
					ty->u.sym->u.s.cfields = 0;
					p = asgntree(ASGN, rvalue(idtree(retv)), p);
					ty->u.sym->u.s.cfields = 1;
				} else
					p = asgntree(ASGN, rvalue(idtree(retv)), p);
			}
			walk(p, 0, 0);
			if (events.returns)
				apply(events.returns, cfunc, rvalue(idtree(retv)));
			return;
		}
	if (events.returns)
		{
			Symbol t1 = genident(AUTO, p->type, level);
			addlocal(t1);
			walk(asgn(t1, p), 0, 0);
			apply(events.returns, cfunc, idtree(t1));
			p = idtree(t1);
		}
	if (!isfloat(p->type))
		p = cast(p, promote(p->type));
	if (isptr(p->type))
		{
			Symbol q = localaddr(p);
			if (q && (q->computed || q->generated))
				warning("pointer to a %s is an illegal return value\n",
					q->scope == PARAM ? "parameter" : "local");
			else if (q)
				warning("pointer to %s `%s' is an illegal return value\n",
					q->scope == PARAM ? "parameter" : "local", q->name);
		}
	walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);
}
Beispiel #7
0
/* Return the division of two expressions */
static exp_t *
divs(exp_t *a1, exp_t *a2)
{
        exp_t *res;

        CHKNUM(a1, /);
        CHKNUM(a2, /);

        if (VALUE(a2) == 0)
                everr("/: argument is divided by zero", a1);
        if (isfloat(a1) || isfloat(a2))
                res = nfloat(VALUE(a1) / VALUE(a2));
        else
                res = nrat(NUMER(a1) * DENOM(a2), NUMER(a2) * DENOM(a1));
        return res;
}
Beispiel #8
0
static GMQCC_INLINE int fold_cond(ir_value *condval, ast_function *func, ast_ifthen *branch) {
    if (isfloat(condval) && fold_can_1(condval) && OPTS_OPTIMIZATION(OPTIM_CONST_FOLD_DCE)) {
        ast_expression_codegen *cgen;
        ir_block               *elide;
        ir_value               *dummy;
        bool                    istrue  = (fold_immvalue_float(condval) != 0.0f && branch->on_true);
        bool                    isfalse = (fold_immvalue_float(condval) == 0.0f && branch->on_false);
        ast_expression         *path    = (istrue)  ? branch->on_true  :
                                          (isfalse) ? branch->on_false : NULL;
        if (!path) {
            /*
             * no path to take implies that the evaluation is if(0) and there
             * is no else block. so eliminate all the code.
             */
            ++opts_optimizationcount[OPTIM_CONST_FOLD_DCE];
            return true;
        }

        if (!(elide = ir_function_create_block(ast_ctx(branch), func->ir_func, ast_function_label(func, ((istrue) ? "ontrue" : "onfalse")))))
            return false;
        if (!(*(cgen = path->codegen))((ast_expression*)path, func, false, &dummy))
            return false;
        if (!ir_block_create_jump(func->curblock, ast_ctx(branch), elide))
            return false;
        /*
         * now the branch has been eliminated and the correct block for the constant evaluation
         * is expanded into the current block for the function.
         */
        func->curblock = elide;
        ++opts_optimizationcount[OPTIM_CONST_FOLD_DCE];
        return true;
    }
    return -1; /* nothing done */
}
Beispiel #9
0
static int
mp_add_to_form(const char *name, size_t nlen,
	       const char *value, size_t len,
	       const char *file, void *closure)
{ term_t head = PL_new_term_ref();
  term_t tail = (term_t) closure;
  term_t val  = PL_new_term_ref();
  long vl;
  double vf;
  int rc;
  atom_t aname = 0;

  if ( isinteger(value, &vl, len) )
    rc = PL_put_integer(val, vl);
  else if ( isfloat(value, &vf, len) )
    rc = PL_put_float(val, vf);
  else
    rc = PL_unify_chars(val, PL_ATOM|REP_UTF8, len, value);

  rc = ( rc &&
	 PL_unify_list(tail, head, tail) &&
	 (aname = PL_new_atom_nchars(nlen, name)) &&
	 PL_unify_term(head,
			PL_FUNCTOR, PL_new_functor(aname, 1),
			PL_TERM, val) );

  if ( aname )
    PL_unregister_atom(aname);

  return rc;
}
Beispiel #10
0
static GMQCC_INLINE ast_expression *fold_op_div(fold_t *fold, ast_value *a, ast_value *b) {
    if (isfloat(a)) {
        if (fold_can_2(a, b)) {
            return fold_constgen_float(fold, fold_immvalue_float(a) / fold_immvalue_float(b));
        } else if (fold_can_1(b)) {
            return (ast_expression*)ast_binary_new(
                fold_ctx(fold),
                INSTR_MUL_F,
                (ast_expression*)a,
                fold_constgen_float(fold, 1.0f / fold_immvalue_float(b))
            );
        }
    } else if (isvector(a)) {
        if (fold_can_2(a, b)) {
            return fold_constgen_vector(fold, vec3_mulvf(fold_immvalue_vector(a), 1.0f / fold_immvalue_float(b)));
        } else {
            return (ast_expression*)ast_binary_new(
                fold_ctx(fold),
                INSTR_MUL_VF,
                (ast_expression*)a,
                (fold_can_1(b))
                    ? (ast_expression*)fold_constgen_float(fold, 1.0f / fold_immvalue_float(b))
                    : (ast_expression*)ast_binary_new(
                                            fold_ctx(fold),
                                            INSTR_DIV_F,
                                            (ast_expression*)fold->imm_float[1],
                                            (ast_expression*)b
                    )
            );
        }
    }
    return NULL;
}
Beispiel #11
0
void spn_value_print(const SpnValue *val)
{
	switch (valtype(val)) {
	case SPN_TTAG_NIL: {
		fputs("nil", stdout);
		break;
	}
	case SPN_TTAG_BOOL: {
		fputs(boolvalue(val) ? "true" : "false", stdout);
		break;
	}
	case SPN_TTAG_NUMBER: {
		if (isfloat(val)) {
			printf("%.*g", DBL_DIG, floatvalue(val));
		} else {
			printf("%ld", intvalue(val));
		}

		break;
	}
	case SPN_TTAG_STRING: {
		SpnString *s = stringvalue(val);
		fputs(s->cstr, stdout);
		break;
	}
	case SPN_TTAG_ARRAY: {
		SpnArray *array = objvalue(val);
		print_array(array, 0);
		break;
	}
	case SPN_TTAG_HASHMAP: {
		SpnHashMap *hashmap = objvalue(val);
		print_hashmap(hashmap, 0);
		break;
	}
	case SPN_TTAG_FUNC: {
		SpnFunction *func = funcvalue(val);
		void *p;

		if (func->native) {
			p = (void *)(ptrdiff_t)(func->repr.fn);
		} else {
			p = func->repr.bc;
		}

		printf("<function %p>", p);
		break;
	}
	case SPN_TTAG_USERINFO: {
		void *ptr = isobject(val) ? objvalue(val) : ptrvalue(val);
		printf("<userinfo %p>", ptr);
		break;
	}
	default:
		SHANT_BE_REACHED();
		break;
	}
}
Beispiel #12
0
/* Return the difference of two expressions */
static exp_t *
sub(exp_t *a1, exp_t *a2)
{
        long n1, n2, d1, d2;
        exp_t *res;

        CHKNUM(a1, -);
        CHKNUM(a2, -);

        if (isfloat(a1) || isfloat(a2))
                res = nfloat(VALUE(a1) - VALUE(a2));
        else {
                n1 = NUMER(a1), n2 = NUMER(a2);
                d1 = DENOM(a1), d2 = DENOM(a2);
                res = nrat(n1*d2 - n2*d1, d1 * d2);
        }
        return res;
}
Beispiel #13
0
static GMQCC_INLINE ast_expression *fold_op_sub(fold_t *fold, ast_value *a, ast_value *b) {
    if (isfloat(a)) {
        if (fold_can_2(a, b))
            return fold_constgen_float(fold, fold_immvalue_float(a) - fold_immvalue_float(b));
    } else if (isvector(a)) {
        if (fold_can_2(a, b))
            return fold_constgen_vector(fold, vec3_sub(fold_immvalue_vector(a), fold_immvalue_vector(b)));
    }
    return NULL;
}
Beispiel #14
0
static GMQCC_INLINE ast_expression *fold_op_neg(fold_t *fold, ast_value *a) {
    if (isfloat(a)) {
        if (fold_can_1(a))
            return fold_constgen_float(fold, -fold_immvalue_float(a));
    } else if (isvector(a)) {
        if (fold_can_1(a))
            return fold_constgen_vector(fold, vec3_neg(fold_immvalue_vector(a)));
    }
    return NULL;
}
Beispiel #15
0
unsigned long spn_hash_value(const SpnValue *key)
{
	switch (valtype(key)) {
	case SPN_TTAG_NIL:	{ return 0; }
	case SPN_TTAG_BOOL:	{ return boolvalue(key); /* 0 or 1 */ }
	case SPN_TTAG_NUMBER: {
		if (isfloat(key)) {
			double f = floatvalue(key);

			/* only test for integer if it fits into one (anti-UB) */
			if (LONG_MIN <= f && f <= LONG_MAX) {
				long i = f; /* truncate */

				if (f == i) {
					/* it's really an integer.
					 * This takes care of the +/- 0 problem too
					 * (since 0 itself is an integer)
					 */
					return i;
				}
			} else {
				return spn_hash_bytes(&f, sizeof f);
			}
		}

		/* the hash value of an integer is itself */
		return intvalue(key);
	}
	case SPN_TTAG_STRING:
	case SPN_TTAG_ARRAY:
	case SPN_TTAG_HASHMAP:
	case SPN_TTAG_FUNC: {
		SpnObject *obj = objvalue(key);
		unsigned long (*hashfn)(void *) = obj->isa->hashfn;
		return hashfn ? hashfn(obj) : (unsigned long)(obj);
	}
	case SPN_TTAG_USERINFO: {
		if (isobject(key)) {
			SpnObject *obj = objvalue(key);
			unsigned long (*hashfn)(void *) = obj->isa->hashfn;
			return hashfn ? hashfn(obj) : (unsigned long)(obj);
		}

		return (unsigned long)(ptrvalue(key));
	}
	default:
		SHANT_BE_REACHED();
	}

	return 0;
}
Beispiel #16
0
static GMQCC_INLINE ast_expression *fold_op_xor(fold_t *fold, ast_value *a, ast_value *b) {
    if (isfloat(a)) {
        if (fold_can_2(a, b))
            return fold_constgen_float(fold, (qcfloat_t)(((qcint_t)fold_immvalue_float(a)) ^ ((qcint_t)fold_immvalue_float(b))));
    } else {
        if (fold_can_2(a, b)) {
            if (isvector(b))
                return fold_constgen_vector(fold, vec3_xor(fold_immvalue_vector(a), fold_immvalue_vector(b)));
            else
                return fold_constgen_vector(fold, vec3_xorvf(fold_immvalue_vector(a), fold_immvalue_float(b)));
        }
    }
    return NULL;
}
Beispiel #17
0
void Lexer::word() {
    _word[_wi++] = _stream->current();
    while (!isBoundary(_stream->peek()))
        _word[_wi++] = _stream->read();

    // does it look like a number?
    _word[_wi++] = '\0';

    if (isint(_word))
        add(new (collect) Term(TInt, atol(_word)));
    else if (isfloat(_word))
        add(new (collect) Term(TDouble, atof(_word)));
    else
        add(new (collect) Term(TSymbol, Sym::lookup(_word)));
    _wi = 0;
}
Beispiel #18
0
int
load_config(const char *filepath) {
    SDL_RWops *fp = SDL_RWFromFile(filepath, "r");

    if (!fp) {
        LOG_ERROR("Can't open file %s\n", filepath);
        return -1;
    }

    char buffer[256];

    while (!rweof(fp)) {
        memset(buffer, 0, sizeof(buffer));
        rwgets(buffer, sizeof(buffer), fp);

        if (buffer[0] == '#')
            continue;

        char *ptr;
        char *p = strtok_r(buffer, " \r\n", &ptr);

        if (p) {
            struct ConfigItem *item = malloc(sizeof(struct ConfigItem));

            strncpy(item->key, p, MAX_CONFIGS_STR_KEY_SIZE);
            item->hash = pjw_hash(p);

            p = strtok_r(NULL, " \r\n", &ptr);

            if (isint(p)) {
                VARIANT_SET_INT(item->var, atoi(p));
            } else if (isfloat(p)) {
                VARIANT_SET_FLOAT(item->var, atof(p));
            } else {
                VARIANT_SET_STRING(item->var, p);
            }

            // TODO: check dublicate
            slist_append(configs, &item);
        }
    }

    SDL_RWclose(fp);

    return 0;
}
Beispiel #19
0
static GMQCC_INLINE ast_expression *fold_op_not(fold_t *fold, ast_value *a) {
    if (isfloat(a)) {
        if (fold_can_1(a))
            return fold_constgen_float(fold, !fold_immvalue_float(a));
    } else if (isvector(a)) {
        if (fold_can_1(a))
            return fold_constgen_float(fold, vec3_notf(fold_immvalue_vector(a)));
    } else if (isstring(a)) {
        if (fold_can_1(a)) {
            if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
                return fold_constgen_float(fold, !fold_immvalue_string(a));
            else
                return fold_constgen_float(fold, !fold_immvalue_string(a) || !*fold_immvalue_string(a));
        }
    }
    return NULL;
}
Beispiel #20
0
unsigned long spn_hash_value(const SpnValue *key)
{
	switch (valtype(key)) {
	case SPN_TTAG_NIL:	{ return 0; }
	case SPN_TTAG_BOOL:	{ return boolvalue(key); /* 0 or 1 */ }
	case SPN_TTAG_NUMBER: {
		if (isfloat(key)) {
			double f = floatvalue(key);
			long i = f; /* truncate */

			if (f == i) {
				return i; /* it's really an integer */
			} else {
				return spn_hash_bytes(&f, sizeof f);
			}
		}

		/* the hash value of an integer is itself */
		return intvalue(key);
	}
	case SPN_TTAG_STRING:
	case SPN_TTAG_ARRAY:
	case SPN_TTAG_HASHMAP:
	case SPN_TTAG_FUNC: {
		SpnObject *obj = objvalue(key);
		unsigned long (*hashfn)(void *) = obj->isa->hashfn;
		return hashfn ? hashfn(obj) : (unsigned long)(obj);
	}
	case SPN_TTAG_USERINFO: {
		if (isobject(key)) {
			SpnObject *obj = objvalue(key);
			unsigned long (*hashfn)(void *) = obj->isa->hashfn;
			return hashfn ? hashfn(obj) : (unsigned long)(obj);
		}

		return (unsigned long)(ptrvalue(key));
	}
	default:
		SHANT_BE_REACHED();
	}

	return 0;
}
Beispiel #21
0
static int
checkfloat(int loc)
{
  char *c;

  c = field[loc];
  if (*c && (isfloat(*c))) {
    c++;
    while (*c) {
      if (!isfloatany(*c))
	return 0;
      c++;
    }
  }
  else {
    return 0;
  }
#ifdef DEBUG
  printf("%s is a float\n", field[loc]);
#endif
  return 1;
}
Beispiel #22
0
Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
	Tree p;

	if (args)
		f = tree(RIGHT, f->type, args, f);
	if (isstruct(ty))
		assert(t3),
		p = tree(RIGHT, ty,
			tree(CALL+B, ty, f, addrof(idtree(t3))),
			idtree(t3));
	else {
		Type rty = ty;
		if (isenum(ty))
			rty = unqual(ty)->type;
		if (!isfloat(rty))
			rty = promote(rty);
		p = tree(mkop(CALL, rty), rty, f, NULL);
		if (isptr(ty) || p->type->size > ty->size)
			p = cast(p, ty);
	}
	return p;
}
Beispiel #23
0
static void
push_arg(dbref player, struct frame *fr, const char *arg)
{
    int num, lflag = 0;
    double nflt = 0.0;

    if (fr->argument.top >= STACK_SIZE) {
	anotify_nolisten(player, CFAIL "That would overflow the stack.", 1);
	return;
    }
    if (number(arg)) {
	/* push a number */
	num = atoi(arg);
	push(fr->argument.st, &fr->argument.top, PROG_INTEGER, MIPSCAST &num);
	anotify_nolisten(player, CSUCC "Integer pushed.", 1);
    } else if (isfloat(arg)) {
      /* push a float */
      nflt = atof(arg);
      push(fr->argument.st, &fr->argument.top, PROG_FLOAT, MIPSCAST &nflt);
      anotify_nolisten(player, CSUCC "Floating point number pushed.", 1);
    } else if (*arg == '#') {
	/* push a dbref */
	if (!number(arg+1)) {
	    anotify_nolisten(player, CINFO "I don't understand that dbref.", 1);
	    return;
	}
	num = atoi(arg+1);
	push(fr->argument.st, &fr->argument.top, PROG_OBJECT, MIPSCAST &num);
	anotify_nolisten(player, CSUCC "Dbref pushed.", 1);
    } else if (*arg == 'L' || *arg == 'V' || *arg == 'l' || *arg == 'v') {
	if (*arg == 'L' || *arg == 'l') arg++, lflag = 1;
	if (*arg == 'V' || *arg == 'v') arg++;
	if (!number(arg)) {
	    anotify_nolisten(player, CINFO "I don't understand which variable you mean.", 1);
	    return;
	}
	num = atoi(arg);
	if (lflag) {
	    push(fr->argument.st, &fr->argument.top, PROG_LVAR, MIPSCAST &num);
	    anotify_nolisten(player, CSUCC "Local variable pushed.", 1);
	} else {
	    push(fr->argument.st, &fr->argument.top, PROG_VAR, MIPSCAST &num);
	    anotify_nolisten(player, CSUCC "Global variable pushed.", 1);
	}
    } else if (*arg == '"') {
	/* push a string */
	char buf[BUFFER_LEN];
	char *ptr;
	const char *ptr2;

	for (ptr = buf, ptr2 = arg+1; *ptr2; ptr2++) {
	    if (*ptr2 == '\\') {
		if (!*(++ptr2)) break;
		*ptr++ = *ptr2;
	    } else if (*ptr2 == '"') {
		break;
	    } else {
		*ptr++ = *ptr2;
	    }
	}
	*ptr = '\0';
	push(fr->argument.st, &fr->argument.top, PROG_STRING,
		MIPSCAST alloc_prog_string(buf));
	anotify_nolisten(player, CSUCC "String pushed.", 1);
    } else {
	anotify_nolisten(player, CINFO "I don't know that data type.", 1);
    }
}
Beispiel #24
0
/* the actual string format parser
 * Although it's not in the documentation of `printf()`, but in addition to the
 * `%d` conversion specifier, this supports `%i`, which takes an `int` argument
 * instead of a `long`. It is used only for formatting error messages (since
 * Sparkling integers are all `long`s), but feel free to use it yourself.
 *
 * if `errmsg' is not a NULL pointer, and an error occurred while creating the
 * format string, then on return, `*errmsg' will point to a string containing
 * a message that describes the error.
 */
static char *make_format_string(
	const char *fmt,
	size_t *len,
	int argc,
	void *argv,
	int isval,
	char **errmsg
)
{
	struct string_builder bld;
	int argidx = 0;
	const char *s = fmt;
	const char *p = s;	/* points to the beginning of the next
				 * non-format part of the format string
				 */

	init_builder(&bld);

	while (*s) {
		if (*s == '%') {
			struct format_args args;
			init_format_args(&args);

			/* append preceding non-format string chunk */
			if (s > p) {
				append_string(&bld, p, s - p);
			}

			s++;

			/* Actually parse the format string.
			 * '#' flag: prepend base prefix (0b, 0, 0x)
			 */
			if (*s == '#') {
				args.flags |= FLAG_BASEPREFIX;
				s++;
			}

			/* ' ' (space) flag: prepend space if non-negative
			 * '+' flag: always prepend explicit + or - sign
			 */
			if (*s == ' ') {
				args.flags |= FLAG_PADSIGN;
				s++;
			} else if (*s == '+') {
				args.flags |= FLAG_EXPLICITSIGN;
				s++;
			}

			/* leading 0 flag: pad field with zeroes */
			if (*s == '0') {
				args.flags |= FLAG_ZEROPAD;
				s++;
			}

			/* field width specifier */
			if (isdigit(*s)) {
				args.width = 0;
				while (isdigit(*s)) {
					args.width *= 10;
					args.width += *s++ - '0';
				}
			} else if (*s == '*') {
				s++;
				if (isval) {
					SpnValue *widthptr;

					/* check argc if the caller wants us to do so */
					if (argc >= 0 && argidx >= argc) {
						format_errmsg(errmsg, OUT_OF_ARGUMENTS, argidx);
						free(bld.buf);
						return NULL;
					}

					/* width specifier must be an integer */
					widthptr = getarg_val(argv, &argidx);
					if (!isnum(widthptr)) {
					 	format_errmsg(
					 		errmsg,
					 		TYPE_MISMATCH,
					 		argidx,
					 		SPN_TTAG_NUMBER,
					 		widthptr->type
					 	);
						free(bld.buf);
						return NULL;
					}

					if (isfloat(widthptr)) {
				 		format_errmsg(
				 			errmsg,
				 			EXPECT_INTEGER,
				 			argidx
				 		);
						free(bld.buf);
						return NULL;
					}

					args.width = intvalue(widthptr);
				} else {
					const int *widthptr = getarg_raw(argv, &argidx);
					args.width = *widthptr;
				}
			}

			/* precision/maximal length specifier */
			if (*s == '.') {
				s++;

				if (*s == '+') {
					args.flags |= FLAG_EXPONENTSIGN;
					s++;
				}

				args.precision = 0;
				if (isdigit(*s)) {
					while (isdigit(*s)) {
						args.precision *= 10;
						args.precision += *s++ - '0';
					}
				} else if (*s == '*') {
					s++;
					if (isval) {
						SpnValue *precptr;

						/* check argc if the caller wants us to do so */
						if (argc >= 0 && argidx >= argc) {
							format_errmsg(errmsg, OUT_OF_ARGUMENTS, argidx);
							free(bld.buf);
							return NULL;
						}

						/* precision must be an integer too */
						precptr = getarg_val(argv, &argidx);

						if (!isnum(precptr)) {
							format_errmsg(
								errmsg,
								TYPE_MISMATCH,
								argidx,
								SPN_TTAG_NUMBER,
								precptr->type
							);
							free(bld.buf);
							return NULL;
						}

						if (isfloat(precptr)) {
					 		format_errmsg(
					 			errmsg,
					 			EXPECT_INTEGER,
					 			argidx
					 		);
							free(bld.buf);
							return NULL;
						}

						args.precision = intvalue(precptr);
					} else {
						const int *precptr = getarg_raw(argv, &argidx);
						args.precision = *precptr;
					}
				}
			}

			args.spec = *s++;

			/* check argc if the caller wants us to do so */
			if (argc >= 0 && argidx >= argc) {
				format_errmsg(errmsg, OUT_OF_ARGUMENTS, argidx);
				free(bld.buf);
				return NULL;
			}

			/* append parsed format string */
			if (append_format(&bld, &args, argv, &argidx, isval, errmsg) != 0) {
				free(bld.buf);
				return NULL;
			}

			/* update non-format chunk base pointer */
			p = s;
		} else {
			s++;
		}
	}

	/* if the format string doesn't end with a conversion specifier,
	 * then just append the last non-format (literal) string chunk
	 */
	if (s > p) {
		append_string(&bld, p, s - p);
	}

	/* append terminating NUL byte */
	expand_buffer(&bld, 1);
	bld.buf[bld.len] = 0;

	if (len != NULL) {
		*len = bld.len;
	}

	return bld.buf;
}
Beispiel #25
0
/* returns zero on success, nonzero on error */
static int append_format(
	struct string_builder *bld,
	const struct format_args *args,
	void *argv,
	int *argidx,
	int isval,
	char **errmsg
)
{
	switch (args->spec) {
	case '%':
		append_string(bld, "%", 1);
		break;
	case 's': {
		const char *str;
		size_t len;

		if (isval) {
			SpnString *strobj;

			/* must be a string */
			SpnValue *val = getarg_val(argv, argidx);
			if (!isstring(val)) {
				format_errmsg(
					errmsg,
					TYPE_MISMATCH,
					*argidx,
					SPN_TYPE_STRING,
					val->type
				);
				return -1;
			}

			strobj = stringvalue(val);
			str = strobj->cstr;
			len = strobj->len;
		} else {
			str = getarg_raw(argv, argidx);
			len = strlen(str);
		}

		if (args->precision >= 0 && args->precision < len) {
			len = args->precision;
		}

		if (args->width >= 0 && args->width > len) {
			size_t pad = args->width - len;
			expand_buffer(bld, pad);

			while (pad-- > 0) {
				bld->buf[bld->len++] = ' ';
			}
		}

		append_string(bld, str, len);
		break;
	}
	case 'i':
	case 'd':
	case 'b':
	case 'o':
	case 'u':
	case 'x':
	case 'X': {
		char *buf, *end, *begin;
		size_t len = PR_LONG_DIGITS;
		enum format_flags flags = args->flags;
		unsigned base = base_for_specifier(args->spec);
		long n;
		unsigned long u;

		if (isval) {
			/* must be a number */
			SpnValue *val = getarg_val(argv, argidx);
			if (!isnum(val)) {
				format_errmsg(
					errmsg,
					TYPE_MISMATCH,
					*argidx,
					SPN_TTAG_NUMBER,
					val->type
				);
				return -1;
			}

			if (isint(val)) {
				n = intvalue(val);
			} else {
				n = floatvalue(val); /* truncate */
			}
		} else {
			/* "%i" expects an int, others expect a long */
			if (args->spec == 'i') {
				n = *(const int *)getarg_raw(argv, argidx);
			} else {
				n = *(const long *)getarg_raw(argv, argidx);
			}
		}

		if (args->spec == 'i' || args->spec == 'd') {
			/* signed conversion specifiers */
			if (n < 0) {
				flags |= FLAG_NEGATIVE;
				u = -n;
			} else {
				u = n;
			}
		} else {
			/* unsigned conversion specifiers */
			u = n;
		}

		if (args->spec == 'X') {
			flags |= FLAG_CAPS;
		}

		if (args->width >= 0 && args->width > len) {
			len = args->width;
		}

		buf = spn_malloc(len);
		end = buf + len;
		begin = ulong2str(end, u, base, args->width, flags);

		assert(buf <= begin);
		append_string(bld, begin, end - begin);
		free(buf);

		break;
	}
	case 'c': {
		unsigned char ch;
		int len = 1; /* one character is one character long... */

		if (isval) {
			/* must be an integer */
			SpnValue *val = getarg_val(argv, argidx);

			if (!isnum(val)) {
				format_errmsg(
					errmsg,
					TYPE_MISMATCH,
					*argidx,
					SPN_TTAG_NUMBER,
					val->type
				);
				return -1;
			}

			if (isfloat(val)) {
				format_errmsg(errmsg, EXPECT_INTEGER, *argidx);
				return -1;
			}

			ch = intvalue(val);
		} else {
			ch = *(const long *)getarg_raw(argv, argidx);
		}

		if (args->width > len) {
			len = args->width;
		}

		expand_buffer(bld, len);

		while (len-- > 1) {
			bld->buf[bld->len++] = ' ';
		}

		bld->buf[bld->len++] = ch;

		break;
	}
	case 'f':
	case 'F': {
		char *buf, *end, *begin;
		size_t len;
		int prec;
		double x;
		enum format_flags flags = args->flags;

		if (isval) {
			SpnValue *val = getarg_val(argv, argidx);
			if (!isnum(val)) {
				format_errmsg(
					errmsg,
					TYPE_MISMATCH,
					*argidx,
					SPN_TTAG_NUMBER,
					val->type
				);
				return -1;
			}

			if (isfloat(val)) {
				x = floatvalue(val);
			} else {
				x = intvalue(val);
			}
		} else {
			x = *(const double *)getarg_raw(argv, argidx);
		}

		if (args->spec == 'F') {
			flags |= FLAG_CAPS;
		}

		/* handle special cases */
		if (+1.0 / x == +1.0 / -0.0) {
			/* negative zero: set sign flag and carry on */
			flags |= FLAG_NEGATIVE;
		} else if (
			x != x		/*  NaN */
		     || x == +1.0 / 0.0	/* +inf */
		     || x == -1.0 / 0.0	/* -inf */
		) {
			print_special_fp(bld, flags, args->width, x);
			break;
		}

		if (x < 0.0) {
			flags |= FLAG_NEGATIVE;
			x = -x;
		}

		/* at this point, `x' is non-negative or -0 */

		if (x >= 1.0) {
			len = ceil(log10(x)) + 1; /* 10 ^ n is n + 1 digits long */
		} else {
			len = 1; /* leading zero needs exactly one character */
		}

		prec = args->precision < 0 ? DBL_DIG : args->precision;

		len += prec + 3; /* decimal point, sign, leading zero */

		if (args->width >= 0 && args->width > len) {
			len = args->width;
		}

		buf = spn_malloc(len);
		end = buf + len;
		begin = double2str(end, x, args->width, prec, flags);

		assert(buf <= begin);
		append_string(bld, begin, end - begin);
		free(buf);

		break;
	}
	case 'B': {
		int boolval;
		const char *str;
		size_t len;

		if (isval) {
			/* must be a boolean */
			SpnValue *val = getarg_val(argv, argidx);
			if (!isbool(val)) {
				format_errmsg(
					errmsg,
					TYPE_MISMATCH,
					*argidx,
					SPN_TTAG_BOOL,
					val->type
				);
				return -1;
			}

			boolval = boolvalue(val);
		} else {
			boolval = *(const int *)getarg_raw(argv, argidx);
		}

		str = boolval ? "true" : "false";
		len = strlen(str);

		if (args->precision >= 0 && args->precision < len) {
			len = args->precision;
		}

		if (args->width >= 0 && args->width > len) {
			size_t pad = args->width - len;
			expand_buffer(bld, pad);

			while (pad-- > 0) {
				bld->buf[bld->len++] = ' ';
			}
		}

		append_string(bld, str, len);
		break;
	}
	default:
		format_errmsg(errmsg, INVALID_SPECIFIER, ++*argidx, args->spec);
		return -1;
	}

	return 0;
}
Beispiel #26
0
int main(int argc, char *argv[])
{
   FILE *fp = stdin, *fpc;
   char *coef = NULL;
   double *x = NULL, *dx = NULL, **dw_coef = NULL, *y = NULL;
   int i, j, l, d, t, tj, ispipe, fsize, leng = LENG, total = T;
   int dw_num = 1, **dw_width = NULL, dw_calccoef = -1, dw_coeflen = 1,
       dw_leng = 1;
   char **dw_fn = (char **) calloc(sizeof(char *), argc);
   int non_magic_num, win_size_forward[2], win_size_backward[2];
   float_list *top, *cur, *prev, *tmpf;

   if ((cmnd = strrchr(argv[0], '/')) == NULL)
      cmnd = argv[0];
   else
      cmnd++;

   while (--argc) {
      if (**++argv == '-') {
         switch (*(*argv + 1)) {
         case 'd':
            if (dw_calccoef == 1 || dw_calccoef == 2) {
               fprintf(stderr,
                       "%s : Options '-r' and '-d' should not be defined simultaneously!\n",
                       cmnd);
               return (1);
            }
            dw_calccoef = 0;
            if (isfloat(*++argv)) {
               dw_coeflen = 0;
               for (i = 0; (i < argc - 1) && isfloat(argv[i]); i++) {
                  dw_coeflen += strlen(argv[i]) + 1;
               }
               dw_coeflen += 1;
               coef = dw_fn[dw_num] = getmem(dw_coeflen, sizeof(char));
               for (j = 0; j < i; j++) {
                  sprintf(coef, " %s", *argv);
                  coef += strlen(*argv) + 1;
                  if (j < i - 1) {
                     argv++;
                     argc--;
                  }
               }
            } else {
               dw_fn[dw_num] = *argv;
            }
            dw_num++;
            --argc;
            break;
         case 'r':
            if (dw_calccoef == 0 || dw_calccoef == 2) {
               fprintf(stderr,
                       "%s : Options '-r' and '-d' should not be defined simultaneously!\n",
                       cmnd);
               return (1);
            }
            dw_calccoef = 1;
            dw_coeflen = atoi(*++argv);
            --argc;
            if ((dw_coeflen != 1) && (dw_coeflen != 2)) {
               fprintf(stderr,
                       "%s : Number of delta parameter should be 1 or 2!\n",
                       cmnd);
               return (1);
            }
            if (argc <= 1) {
               fprintf(stderr,
                       "%s : Window size for delta parameter required!\n",
                       cmnd);
               return (1);
            }
            dw_fn[dw_num] = *++argv;
            dw_num++;
            --argc;
            if (dw_coeflen == 2) {
               if (argc <= 1) {
                  fprintf(stderr,
                          "%s : Window size for delta-delta parameter required!\n",
                          cmnd);
                  return (1);
               }
               dw_fn[dw_num] = *++argv;
               dw_num++;
               --argc;
            }
            break;
         case 'm':
            leng = atoi(*++argv) + 1;
            --argc;
            break;
         case 'l':
            leng = atoi(*++argv);
            --argc;
            break;
         case 'R':
            if (dw_calccoef == 0 || dw_calccoef == 1) {
               fprintf(stderr,
                       "%s : Options '-r', '-d' and '-R' should not be defined simultaneously!\n",
                       cmnd);
               return (1);
            }
            dw_calccoef = 2;
            dw_num = atoi(*++argv) + 1;
            --argc;
            if ((dw_num != 2) && (dw_num != 3)) {
               fprintf(stderr,
                       "%s : Number of delta parameter should be 1 or 2!\n",
                       cmnd);
               return (1);
            }
            if (argc <= 1) {
               fprintf(stderr,
                       "%s : Window size for delta-delta parameter required!\n",
                       cmnd);
               return (1);
            }

            sscanf(*++argv, "%d", &win_size_forward[0]);
            --argc;
            sscanf(*++argv, "%d", &win_size_backward[0]);
            --argc;
            if (dw_num > 2) {
               sscanf(*++argv, "%d", &win_size_forward[1]);
               --argc;
               sscanf(*++argv, "%d", &win_size_backward[1]);
               --argc;
            }
            break;
         case 'M':
            sscanf(*++argv, "%lf", &magic);
            MAGIC = TR;
            --argc;
            break;
         case 'h':
            usage(0);
         default:
            fprintf(stderr, "%s : Invalid option '%c'!\n", cmnd, *(*argv + 1));
            usage(1);
         }
      } else
         fp = getfp(*argv, "rb");
   }

   /* parse window files */
   /* memory allocation */
   if ((dw_width = (int **) calloc(dw_num, sizeof(int *))) == NULL) {
      fprintf(stderr, "%s : Cannot allocate memory!\n", cmnd);
      exit(1);
   }
   for (i = 0; i < dw_num; i++)
      if ((dw_width[i] = (int *) calloc(2, sizeof(int))) == NULL) {
         fprintf(stderr, "%s : Cannot allocate memory!\n", cmnd);
         exit(1);
      }
   if ((dw_coef = (double **) calloc(dw_num, sizeof(double *))) == NULL) {
      fprintf(stderr, "%s : Cannot allocate memory!\n", cmnd);
      exit(1);
   }

   /* window for static parameter */
   dw_width[0][0] = dw_width[0][1] = 0;
   dw_coef[0] = dgetmem(1);
   dw_coef[0][0] = 1;

   /* set delta coefficients */
   if (dw_calccoef == 0) {
      for (i = 1; i < dw_num; i++) {
         if (dw_fn[i][0] == ' ') {
            fsize = str2darray(dw_fn[i], &(dw_coef[i]));
         } else {
            /* read from file */
            fpc = getfp(dw_fn[i], "rb");

            /* check the number of coefficients */
            fseek(fpc, 0L, 2);
            fsize = ftell(fpc) / sizeof(real);
            fseek(fpc, 0L, 0);

            /* read coefficients */
            dw_coef[i] = dgetmem(fsize);
            freadf(dw_coef[i], sizeof(**(dw_coef)), fsize, fpc);
         }

         /* set pointer */
         dw_leng = fsize / 2;
         dw_coef[i] += dw_leng;
         dw_width[i][0] = -dw_leng;
         dw_width[i][1] = dw_leng;
         if (fsize % 2 == 0)
            dw_width[i][1]--;
      }
   } else if (dw_calccoef == 1) {
      int a0, a1, a2;
      for (i = 1; i < dw_num; i++) {
         dw_leng = atoi(dw_fn[i]);
         if (dw_leng < 1) {
            fprintf(stderr,
                    "%s : Width for regression coefficient shuould be more than 1!\n",
                    cmnd);
            exit(1);
         }
         dw_width[i][0] = -dw_leng;
         dw_width[i][1] = dw_leng;
         dw_coef[i] = dgetmem(dw_leng * 2 + 1);
         dw_coef[i] += dw_leng;
      }

      dw_leng = atoi(dw_fn[1]);
      for (a1 = 0, j = -dw_leng; j <= dw_leng; a1 += j * j, j++);
      for (j = -dw_leng; j <= dw_leng; j++)
         dw_coef[1][j] = (double) j / (double) a1;

      if (dw_num > 2) {
         dw_leng = atoi(dw_fn[2]);
         for (a0 = a1 = a2 = 0, j = -dw_leng; j <= dw_leng;
              a0++, a1 += j * j, a2 += j * j * j * j, j++);
         for (j = -dw_leng; j <= dw_leng; j++)
            dw_coef[2][j] =
                2 * ((double) (a0 * j * j - a1)) /
                ((double) (a2 * a0 - a1 * a1));
      }
   }

   /* -- Count number of input vectors and read -- */
   x = dgetmem(leng);
   top = prev = (float_list *) malloc(sizeof(float_list));
   top->f = (float *) malloc(sizeof(float) * leng);
   total = 0;
   prev->next = NULL;
   while (freadf(x, sizeof(*x), leng, fp) == leng) {
      cur = (float_list *) malloc(sizeof(float_list));
      cur->f = (float *) malloc(sizeof(float) * leng);
      for (i = 0; i < leng; i++) {
         cur->f[i] = (float) x[i];
      }
      total++;
      prev->next = cur;
      cur->next = NULL;
      prev = cur;
   }
   free(x);
   x = dgetmem(leng * total);
   dx = dgetmem(dw_num * leng * total);
   fillz(dx, sizeof(*x), dw_num * leng * total);
   for (i = 0, tmpf = top->next; tmpf != NULL; i++, tmpf = tmpf->next) {
      for (j = 0; j < leng; j++) {
         x[i * leng + j] = tmpf->f[j];
      }
   }

   if (dw_calccoef == 0 || dw_calccoef == 1) {
      /* calculate delta and delta-delta */
      for (t = 0; t < total; t++) {
         for (d = 0; d < dw_num; d++) {
            for (j = dw_width[d][0]; j <= dw_width[d][1]; j++) {
               tj = t + j;
               if (tj < 0)
                  tj = 0;
               if (!(tj < total))
                  tj = total - 1;
               for (l = 0; l < leng; l++)
                  dx[dw_num * leng * t + leng * d + l] +=
                      dw_coef[d][j] * x[leng * tj + l];
            }
         }
      }

      /* output static, delta, delta-delta */
      fwritef(dx, sizeof(*dx), dw_num * total * leng, stdout);

   } else if (dw_calccoef == 2) {
      int *position = (int *) malloc(sizeof(int) * total);

      /* skip magic number */
      if (MAGIC == TR) {
         for (t = 0, non_magic_num = 0; t < total; t++) {
            for (l = 0; l < leng; l++) {
               if (x[leng * t + l] == magic) {
                  break;
               }
            }
            if (l == leng) {
               /* remember position of non-magic number */
               position[non_magic_num] = t;
               non_magic_num++;
            }
         }
      } else {
         for (t = 0; t < total; t++) {
            position[t] = t;
         }
         non_magic_num = total;
      }

      /* calculate delta and delta-delta */
      GetCoefficient(x, dx, dw_num, position, total, non_magic_num, leng,
                     win_size_forward, win_size_backward);

      /* output static, delta, delta-delta */
      fwritef(dx, sizeof(*dx), dw_num * total * leng, stdout);
   }

   return (0);
}
Beispiel #27
0
double StringValue::Double() const
{
	if(!isfloat(m_val.c_str())) return 0;
	return atof(m_val.c_str());
}
Beispiel #28
0
float StringValue::Float() const
{
	if(!isfloat(m_val.c_str())) return 0.0f;
	return (float)atof(m_val.c_str());
}
Beispiel #29
0
BOOLEAN isarithmetic(TYPE *tp)
{
    tp = basetype(tp);
    return isint(tp) || isfloat(tp) || iscomplex(tp) || isimaginary(tp);
}
Beispiel #30
0
int main(int argc, char **argv)
{
   FILE *pdffp = stdin, *parfp = stdout;
   int nframe, delay;
   char *coef;
   int coeflen;
   PStream pst;
   int i, j;
   void InitPStream(PStream *);
   double *mlpg(PStream *);

   pst.order = ORDER;
   pst.range = RANGE;
   pst.iType = ITYPE;
   pst.dw.fn = (char **) calloc(sizeof(char *), argc);
   pst.dw.num = 1;
   pst.dw.calccoef = -1;

   if ((cmnd = strrchr(argv[0], '/')) == NULL)
      cmnd = argv[0];
   else
      cmnd++;

   while (--argc) {
      if (**++argv == '-') {
         switch (*(*argv + 1)) {
         case 'd':
            if (pst.dw.calccoef == 1) {
               fprintf(stderr,
                       "%s : Options '-r' and '-d' should not be defined simultaneously!\n",
                       cmnd);
               return (1);
            }
            pst.dw.calccoef = 0;
            if (isfloat(*++argv)) {
               coeflen = 0;
               for (i = 0; (i < argc - 1) && isfloat(argv[i]); i++) {
                  coeflen += strlen(argv[i]) + 1;
               }
               coeflen += 1;
               coef = pst.dw.fn[pst.dw.num] = getmem(coeflen, sizeof(char));
               for (j = 0; j < i; j++) {
                  sprintf(coef, " %s", *argv);
                  coef += strlen(*argv) + 1;
                  if (j < i - 1) {
                     argv++;
                     argc--;
                  }
               }
            } else {
               pst.dw.fn[pst.dw.num] = *argv;
            }
            pst.dw.num++;
            --argc;
            break;
         case 'r':
            if (pst.dw.calccoef == 0) {
               fprintf(stderr,
                       "%s : Options '-r' and '-d' should not be defined simultaneously!\n",
                       cmnd);
               return (1);
            }
            pst.dw.calccoef = 1;
            coeflen = atoi(*++argv);
            --argc;
            if ((coeflen != 1) && (coeflen != 2)) {
               fprintf(stderr,
                       "%s : Number of delta parameter should be 1 or 2!\n",
                       cmnd);
               return (1);
            }
            if (argc <= 1) {
               fprintf(stderr,
                       "%s : Window size for delta parameter required!\n",
                       cmnd);
               return (1);
            }
            pst.dw.fn[pst.dw.num] = *++argv;
            pst.dw.num++;
            --argc;
            if (coeflen == 2) {
               if (argc <= 1) {
                  fprintf(stderr,
                          "%s : Window size for delta-delta parameter required!\n",
                          cmnd);
                  return (1);
               }
               pst.dw.fn[pst.dw.num] = *++argv;
               pst.dw.num++;
               --argc;
            }
            break;
         case 'm':
            pst.order = atoi(*++argv);
            --argc;
            break;
         case 'l':
            pst.order = atoi(*++argv) - 1;
            --argc;
            break;
         case 'i':
            pst.iType = atoi(*++argv);
            --argc;
            break;
         case 's':
            pst.range = atoi(*++argv);
            --argc;
            break;
         case 'h':
            usage(0);
         default:
            fprintf(stderr, "%s : Invalid option '%c'!\n", cmnd, *(*argv + 1));
            usage(1);
         }
      } else
         pdffp = getfp(*argv, "rb");
   }

   InitPStream(&pst);

   delay = pst.range + pst.dw.maxw[WRIGHT];
   nframe = 0;
   while (freadf(pst.mean, sizeof(*(pst.mean)), pst.vSize * 2, pdffp) ==
          pst.vSize * 2) {
      if (pst.dw.num == 1)
         fwritef(pst.mean, sizeof(*pst.mean), pst.order + 1, parfp);
      else {
         if (pst.iType == 0)
            for (i = 0; i < pst.vSize; i++)
               pst.ivar[i] = finv(pst.ivar[i]);
         mlpg(&pst);
         if (nframe >= delay)
            fwritef(pst.par, sizeof(*(pst.par)), pst.order + 1, parfp);
      }
      nframe++;
   }

   if (pst.dw.num > 1) {
      for (i = 0; i < pst.vSize; i++) {
         pst.mean[i] = 0.0;
         pst.ivar[i] = 0.0;
      }
      for (i = 0; i < min(nframe, delay); i++) {
         mlpg(&pst);
         fwritef(pst.par, sizeof(*(pst.par)), pst.order + 1, parfp);
      }
   }

   return (0);
}