Esempio n. 1
0
/* <value to be concatenated onto named parameter> .
 */
void 
o_catassign (memel *argp)
{
	char	*pname = (char *) argp;
	char	*pk, *t, *p, *f;
	char	s1[1024+1];
	struct	operand o1, o2;
	struct	param *pp;

	breakout (pname, &pk, &t, &p, &f);
	pp = paramsrch (pk, t, p);
	paramget (pp, *f);

	/* If param value is undefined merely assign into it, otherwise
	 * concatenate operand to current value.
	 */
	o1 = popop();
	if (!opundef(&o1)) {
	    /* Must copy string value off of operand stack or the next
	     * pushop below will reuse the space!
	     */
	    o2 = popop();
	    strncpy (s1, o2.o_val.v_s, 1024);
	    s1[1024] = EOS;
	    o2.o_val.v_s = s1;

	    pushop (&o1);
	    pushop (&o2);
	    binop (OP_CONCAT);
	}

	paramset (pp, *f);
	pp->p_flags |= P_SET;
}
Esempio n. 2
0
/* <string operand> .
 * if argument to which we are assigning is a simple string or filename (or
 *   list, since assigning to a list sets a filename too), set it to o_val.v_s,
 * else use o_val.v_s as the name of a parameter and use its value as the name
 *   of the variable, that is, do an indirect through o_val.v_s.
 * compiled when the parser sees a simple identifier, not in an expression.
 *   this avoids quotes around simple strings and filenames.
 * if the parameter is to be fake, make it type string and do not do the
 *   indirection.
 */
void 
o_indirabsset (memel *argp)
{
	char	*argname = (char *) argp;
	char	*pk, *t, *p, *f;
	struct	pfile *pfp;
	struct	param *pp;
	int	type, string_len;

	pfp = newtask->t_pfp;
	if (pfp->pf_flags & PF_FAKE) {
	    struct	operand o;
	    o = popop();
	    string_len = strlen (o.o_val.v_s);
	    pp = newfakeparam (pfp, argname, 0, OT_STRING, string_len);
	    f = argname;
	    *f = FN_NULL;
	    pushop (&o);

	} else {
	    breakout (argname, &pk, &t, &p, &f);
	    if (*pk)
		cl_error (E_UERR, e_simplep, p);
	    pp = ppfind (pfp, t, p, 0, NO);
	    if (pp == NULL)
		cl_error (E_UERR, e_pnonexist, p);
	    if ((XINT)pp == ERR)
		cl_error (E_UERR, e_pambig, p, pfp->pf_ltp->lt_lname);
	}

	/* lone identifiers are treated as strings, rather than variables,
	 * if the corresponding parameter is a simple string, filename or list.
	 * note that fakeparams are made as strings.
	 */
	type = pp->p_type;
	if (type & (PT_FILNAM|PT_LIST|PT_PSET)) {
	    struct operand o;
	    o = popop();
	    pushop (&o);
	} else if ((type & OT_BASIC) != OT_STRING ||
	    type & (PT_STRUCT|PT_IMCUR|PT_GCUR|PT_UKEY)) {

	    opindir(); /* replace top op with value of o_val.v_s */
	}

	paramset (pp, *f);
	if (pp->p_type & PT_PSET)
	    psetreload (pfp, pp);
	pp->p_flags |= P_CLSET;
}
Esempio n. 3
0
void 
o_doscanf (void)
{
	struct operand o;
	struct operand o_sv[64];
	char	format[SZ_LINE];
	int	nargs, i;

	/* Get number of arguments. */
	o = popop();
	nargs = o.o_val.v_i;

	/* Get scan format.  Unfortunately the way the parser works this
	 * is the last operand on the stack.  We need to pop and save the
	 * first nargs-1 operands and restore them when done.
	 */
	for (i=0;  i < nargs-1;  i++)
	    o_sv[i] = popop();

	o = popop();
	if ((o.o_type & OT_BASIC) != OT_STRING)
	    cl_error (E_UERR, "scanf: bad format string\n");
	strcpy (format, o.o_val.v_s);

	for (--i;  i >= 0;  i--)
	    pushop (&o_sv[i]);

	/* Do the scan. */
	cl_scanf (format, nargs-2, "stdin");
}
Esempio n. 4
0
/* .
 * given the name of a parameter, print it on t_out, the task pipe channel.
 */
void 
o_inspect (memel *argp)
{
	char *pname = (char *) argp;
	char *pk, *t, *p, *f;
	struct param *pp;
	struct operand o;

	breakout (pname, &pk, &t, &p, &f);
	pp = paramsrch (pk, t, p);

	if (*f == FN_NULL && (pp->p_type & PT_LIST)) {
	    /* Hitting EOF from a list is ok during an inspect stmt so
	     * avoid using paramget() with its EOF error.
	     * readlist() may set P_LEOF.
	     */
	    o = readlist (pp);
	    if ((pp->p_flags & P_LEOF) || inrange (pp, &o))
		pushop (&o);
	    else
		query (pp);
	} else
	    validparamget (pp, *f);

	o = popop();

	if (cldebug && (o.o_type & OT_BASIC) == OT_STRING)
	    eprintf ("Inspect--%s\n", o.o_val.v_s);

	prop (&o);
	tprintf ("\n");
}
Esempio n. 5
0
/* <new value for argument at command position *argp> .
 */
void 
o_posargset (memel *argp)
{
	int	pos = (int) *argp;
	struct	pfile *pfp;
	struct	param *pp;
	struct	operand o;
	int	string_len=0;

	pfp = newtask->t_pfp;

	if (pos < 0) {
	    /* Lone comma in arg list, merely bump nargs counter */
	    pfp->pf_n++;
	    return;
	}

	if (pfp->pf_flags & PF_FAKE) {
	    o = popop();
	    if ((o.o_type & OT_BASIC) == OT_STRING)
		string_len = strlen (o.o_val.v_s);
	    pp = newfakeparam (pfp, (char *) NULL, pos, o.o_type, string_len);
	    pushop (&o);
	} else {
	    pp = paramfind (pfp, (char *) NULL, pos, NO);
	    if (pp == NULL)
		cl_error (E_UERR, e_posargs, newtask->t_ltp->lt_lname);
	}

	paramset (pp, FN_NULL);
	pfp->pf_n++;
	pp->p_flags |= P_CLSET;
}
Esempio n. 6
0
void 
o_swon (memel *argp)
{
	register char *pname = (char *)argp;
	register struct param *pp;
	struct	pfile *pfp;
	struct	operand o;
	char	*pk, *t, *p, *f;

	breakout (pname, &pk, &t, &p, &f);
	if (*pk)
	    cl_error (E_UERR, e_simplep, p);

	pfp = newtask->t_pfp;
	pp = ppfind (pfp, t, p, 0, NO);
	if (pp == NULL)
	    cl_error (E_UERR, e_pnonexist, p);
	if ((XINT)pp == ERR)
	    cl_error (E_UERR, e_pambig, p, newtask->t_ltp->lt_lname);

	o.o_type = OT_BOOL;
	o.o_val.v_i = YES;
	pushop (&o);
	paramset (pp, FN_VALUE);
	if (pp->p_type & PT_PSET)
	    psetreload (pfp, pp);

	pp->p_flags |= P_CLSET;
}
Esempio n. 7
0
void 
o_doaddpipe (memel *argp)
{
	XINT	getpipe_pc = *argp;
	char	*x1, *pk, *t, *x2;	
	char	*ltname;
	struct	operand	o;
	struct	ltask *ltp;
	char	*addpipe();

	/* ADDPIPE is called immediately before REDIR and before EXEC so we
	 * do not have to worry about storing the pipefile name in the dict.
	 * Our argument is the PC of the GETPIPE instruction, the args field
	 * of which is the taskname of the second task in the pipe.  If either
	 * the new task (first task in the pipe) or the second task is a
	 * FOREIGN task, the pipe must be created as a text file.
	 */
	ltname = (char *)&(coderef(getpipe_pc)->c_args);
	if (*ltname == '$')
	    ltname++;
	breakout (ltname, &x1, &pk, &t, &x2);
	ltp = cmdsrch (pk, t);

	binpipe = ((ltp == NULL || !(ltp->lt_flags & LT_FOREIGN)) &&
	    !(newtask->t_flags & T_FOREIGN));

	if (binpipe)
	    newtask->t_flags |= T_STDOUTB;

	o.o_type = OT_STRING;
	o.o_val.v_s = comdstr (addpipe());
	pushop (&o);
}
Esempio n. 8
0
void 
o_dofscanf (void)
{
	struct operand o, o_sv[64];
	char	format[SZ_LINE];
	char	pname[SZ_FNAME];
	int	nargs, i;

	/* Get number of arguments. */
	o = popop();
	nargs = o.o_val.v_i;

	/* Get scan format and input parameter name.  The arguments on the
	 * stack are pushed in the order input param name, format string,
	 * and then the output arguments.
	 */

	/* Get output arguments. */
	for (i=0;  i < nargs-2;  i++)
	    o_sv[i] = popop();

	/* Get format string. */
	o = popop();
	if ((o.o_type & OT_BASIC) != OT_STRING)
	    cl_error (E_UERR, "fscanf: bad format string\n");
	strcpy (format, o.o_val.v_s);

	/* Get parameter name. */
	o = popop();
	if ((o.o_type & OT_BASIC) != OT_STRING)
	    cl_error (E_UERR, "fscanf: bad input parameter specification\n");
	strcpy (pname, o.o_val.v_s);

	/* Restore the output argument operands. */
	for (--i;  i >= 0;  i--)
	    pushop (&o_sv[i]);

	/* Restore the input parameter name operand. */
	o.o_type = OT_STRING;
	o.o_val.v_s = pname;
	pushop (&o);

	/* Do the scan. */
	cl_scanf (format, nargs-2, "");
}
Esempio n. 9
0
/* <value to be divided into named parameter> .
 */
void 
o_divassign (memel *argp)
{
	char	*pname = (char *) argp;
	char	*pk, *t, *p, *f;
	struct	param *pp;
	struct	operand o1, o2;

	breakout (pname, &pk, &t, &p, &f);
	pp = paramsrch (pk, t, p);

	validparamget (pp, *f);		/* get param value on stack	*/
	o1 = popop();			/* swap operands		*/
	o2 = popop();
	pushop (&o1);
	pushop (&o2);
	binop (OP_DIV);			/* perform the division		*/
	paramset (pp, *f);
	pp->p_flags |= P_SET;
}
Esempio n. 10
0
/* . <new constant>
 * The "illegal constant" business comes from the possibility of syntactically
 * correct but valuely wrong sexagesimal constants, such as 1:222:1.
 * We don't want to abort in sexa() because it may be used to digest a query
 * response and producing a quiet undefined op there is correct.
 */
void 
o_pushconst (memel *argp)
{
	/* argument is pointer to an operand */
	struct operand *op;

	op = (struct operand *) argp;
	if (opundef (op))
	    cl_error (E_UERR, "illegal constant");
	pushop (op);
}
Esempio n. 11
0
/* <increment to be added to named parameter> .
 */
void 
o_addassign (memel *argp)
{
	/* order of operands will be incorrect.
	 * strictly speaking, only strings are not commutative but we need
	 * to pop both operands anyway to check.
	 */
	char *pname = (char *) argp;
	char *pk, *t, *p, *f;
	struct param *pp;
	struct operand o1, o2;

	breakout (pname, &pk, &t, &p, &f);
	pp = paramsrch (pk, t, p);
	validparamget (pp, *f);
	o1 = popop();
	o2 = popop();

	if ((o2.o_type & OT_BASIC) == OT_STRING) {
	    /* copy o2 onto dictionary to avoid overwriting it on stack
	     * when o1 is pushed. we can get by with not worrying about o1
	     * as long as whatever code copies the string works when the
	     * strings overlap.
	     */
	    XINT oldtopd = topd;
	    char *s2 = memneed (btoi (strlen (o2.o_val.v_s) + 1));
	    strcpy (s2, o2.o_val.v_s);
	    o2.o_val.v_s = s2;
	    pushop (&o1);
	    pushop (&o2);
	    topd = oldtopd;		/* discard temp string area	*/

	} else {
	    pushop (&o1);
	    pushop (&o2);
	}

	binop (OP_ADD);
	paramset (pp, *f);
	pp->p_flags |= P_SET;
}
Esempio n. 12
0
/* <string operand> .
 * if argument to which we are assigning is a simple string or filename (or
 *   list, since assigning to a list sets a filename too), set it to o_val.v_s,
 * else use o_val.v_s as the name of a parameter and use its value as the name
 *   of the variable, that is, do an indirect through o_val.v_s.
 * compiled when the parser sees a simple identifier, not in an expression.
 *   this avoids quotes around simple strings and filenames.
 */
void 
o_indirposset (memel *argp)
{
	int pos = (int) *argp;
	struct pfile *pfp;
	struct param *pp;
	int type, string_len;

	pfp = newtask->t_pfp;
	if (pfp->pf_flags & PF_FAKE) {
	    struct	operand o;
	    o = popop();
	    string_len = strlen (o.o_val.v_s);
	    pp = newfakeparam (pfp, (char *) NULL, pos, OT_STRING, string_len);
	    pushop (&o);
	} else {
	    pp = paramfind (pfp, (char *) NULL, pos, NO);
	    if (pp == NULL)
		cl_error (E_UERR, e_posargs, newtask->t_ltp->lt_lname);
	}

	/* lone identifiers are treated as strings, rather than variables,
	 * if the corresponding parameter is a simple string, filename or list.
	 * note that fakeparams are made as strings.
	 */
	type = pp->p_type;
	if (type & (PT_FILNAM|PT_LIST|PT_PSET)) {
	    struct operand o;
	    o = popop();
	    pushop (&o);
	} else if ((type & OT_BASIC) != OT_STRING ||
	    type & (PT_STRUCT|PT_IMCUR|PT_GCUR|PT_UKEY)) {

	    opindir(); /* replace top op with value of o_val.v_s */
	}

	paramset (pp, FN_NULL);
	pfp->pf_n++;
	pp->p_flags |= P_CLSET;
}
Esempio n. 13
0
/*
**  VALOF -- compute value of expression
**
**	This is the real expression processor.  It handles sequencing
**	and precedence.
**
**	Parameters:
**		terminator -- the symbol which should terminate
**			the expression.
**
**	Returns:
**		The value of the expression.
**
**	Side Effects:
**		Gobbles input.
**
**	Requires:
**		exprfind -- to read operands.
**		opfind -- to read operators.
**		exp_op -- to perform operations.
**
**	Called By:
**		expr
**
**	Diagnostics:
**		Extra Parenthesis found: assumed typo
**			An unmatched right parenthesis was read.
**			It was thrown away.
**		Insufficient parenthesis found: assumed zero.
**			An unmatched left parenthesis was left
**			in the operator stack at the end of the
**			expression.  The value zero was taken
**			for the expression.
**
**	Syserrs:
**		none
*/
int
valof(int terminator)
{
	register int	number;
	register int	operator;

	pushop(SEPERATOR);		/* initialize the stack */
	for(;;) {
		number = exprfind();
		if (ExprError) 
			return(0);
		operator = opfind();
		if (ExprError)
			return(0);

		if (operator == RIGHTP || operator == END)
			break;

		/* Do all previous operations with a higher precedence */
		while (ExprPrec[operator] <= ExprPrec[ExprOptr[-1]])	
			number = exp_op(popop(), popnum(), number);
		pushop(operator);
		pushnum(number);
	}
	if (operator != terminator)		/* ExprError in operators */
		if (operator == RIGHTP)
			printf("Extra parenthesis found: assumed typo.\n");
		else {
			ExprError = TRUE;
			printf("Insufficient parenthesis found: Assumed zero.\n");
			return(0);
		}
	/* Empty stack for this call of valof */
	while ((operator = popop()) != SEPERATOR)
		number = exp_op(operator, popnum(), number);

	return(number);
}
Esempio n. 14
0
void 
o_dogetpipe (
    memel *argp			/* name of ltask (not used) */
)
{
	struct	operand o;
	char	*getpipe(), *comdstr();

	/* GETPIPE is called immediately before REDIRIN and before EXEC so we
	 * do not have to worry about storing the pipefile name in the dict.
	 * The flag binpipe is set by the last ADDPIPE if the pipe is a binary
	 * file.
	 */
	if (binpipe)
	    newtask->t_flags |= T_STDINB;

	o.o_type = OT_STRING;
	o.o_val.v_s = comdstr (getpipe());
	pushop (&o);
}
Esempio n. 15
0
/* <new value for named argument> .
 * Assign the top operand to the named parameter.  Also, make the type of the
 * fake parameter the same as the type of the operand.
 */
void 
o_absargset (memel *argp)
{
	char	*argname = (char *) argp;
	char	*pk, *t, *p, *f;
	struct	pfile *pfp;
	struct	param *pp;

	pfp = newtask->t_pfp;
	if (pfp->pf_flags & PF_FAKE) {
	    /* use full argname and always assign to value field.
	     */
	    struct operand o;
	    int	string_len=0;
	    o = popop();
	    if ((o.o_type & OT_BASIC) == OT_STRING)
		string_len = strlen (o.o_val.v_s);
	    pp = newfakeparam (pfp, argname, 0, o.o_type, string_len);
	    pushop (&o);
	    f = argname;
	    *f = FN_NULL;

	} else {
	    breakout (argname, &pk, &t, &p, &f);
	    if (*pk)
		cl_error (E_UERR, e_simplep, p);
	    pp = ppfind (pfp, t, p, 0, NO);
	    if (pp == NULL)
		cl_error (E_UERR, e_pnonexist, p);
	    if ((XINT)pp == ERR)
		cl_error (E_UERR, e_pambig, p, pfp->pf_ltp->lt_lname);
	}

	paramset (pp, *f);
	if (pp->p_type & PT_PSET)
	    psetreload (pfp, pp);
	pp->p_flags |= P_CLSET;
}
Esempio n. 16
0
int main()
{	struct node*sv=NULL;
	struct node2*sop=NULL;
	int n,n1,n2,result,i;
	char thisop;
	//scanf("%d",&n);
	char a[100];
	
	scanf("%s",a);
	i=0;
	for(;a[i]!='\0';i++)
	{	if(isdigit(a[i]))
		{	sv=pushval(sv,a[i]);
		}
		else if(a[i]=='+')
		{	if(sop!=NULL)
			{	n1=popval(&sv);
				n2=popval(&sv);
				result=n2+n1;
				//editing required
				sv=pushval(sv,result);
			}	
			else
			{	sop=pushop(sop,a[i]);
			}
		}
	}
	while(sop!=NULL)
	{	thisop=popop(&sop);
			n1=popval(&sv);
				n2=popval(&sv);
				result=n2+n1;//editing required
				sv=pushval(sv,result);
	}
	result=popval(&sv);
	printf("%d",result);
	
}
Esempio n. 17
0
File: modes.c Progetto: geechee/iraf
/* QUERY -- Query the user for the value of a parameter.  Prompt with the
 *  current value if any.  Keep this up until we can push a reasonable value.
 *  Also, store the new value in the parameter (except for list params, where,
 *  since the values are not kept, all that may change is P_LEOF if seen).
 * Give prompt, or name if none, current value and range if int, real or 
 *   filename.  Accept CR to leave value unchanged, else take the string
 *   entered to be the new value.  Repeat until parameter value is in range.
 * We mean to talk straight to the user here; thus, interact with the real
 *   stdio, not the effective t_stdio, so that redirections do not get in
 *   the way.  In batch mode, a forced query is handled by writing a
 *   message on the terminal of the parent cl (the original stderr), and
 *   leaving some info describing the query in a file in uparm (if there is
 *   no uparm, we abort).  We then loop, waiting for the user to run "service"
 *   in the interactive cl to service the query, leaving the answer in a
 *   another file which we read and then delete.  If we wait a long time and
 *   get no response, we timeout.
 */
void 
query (struct param *pp)
{
	static	char *oormsg =
		"ERROR: Parameter value is out of range; try again";
	register char *ip;
	char	buf[SZ_PROMPTBUF+1];
	struct	operand o;
	int	bastype, batch, arrflag, offset=0, n_ele, max_ele, fd;
	char	*index(), *nlp, *nextstr();
	char	*bkg_query(), *query_status;
	char	*abuf;

	bastype = pp->p_type & OT_BASIC;
	batch = firstask->t_flags & T_BATCH;
	arrflag = pp->p_type & PT_ARRAY;

	if (arrflag) {			/* We may access the array many     */
	    offset = getoffset (pp);	/* times, so save the offset and    */
					/* push it when necessary.	    */
	    poffset (offset);
	    max_ele = size_array (pp) - offset;
	} else
	    max_ele = 1;


	forever {
	    if (batch) {
		/* Query from a background job.
		 */
		query_status = bkg_query (buf, SZ_PROMPTBUF, pp);

	    } else if (pp->p_type & (PT_GCUR|PT_IMCUR)) {
		/* Read a graphics cursor.
		 */
		char	source[33];
		int	cursor;

		/* Determine the source of graphics cursor input, chosen from
		 * either the graphics or image cursor or the terminal.
		 */
		if (pp->p_type & PT_GCUR) {
		    if (c_envfind ("stdgcur", source, 32) <= 0)
			strcpy (source, "stdgraph");
		} else {
		    if (c_envfind ("stdimcur", source, 32) <= 0)
			strcpy (source, "stdimage");
		}

		if (strcmp (source, "stdgraph") == 0)
		    cursor = STDGRAPH;
		else if (strcmp (source, "stdimage") == 0)
		    cursor = STDIMAGE;
		else
		    goto text_query;		/* get value from terminal */

		/* Read a physical graphics cursor.
		 */
		pp->p_flags &= ~P_LEOF;
		if (cursor == STDIMAGE) {
		    /* The following is a kludge used to temporarily implement
		     * the logical image cursor read.  In the future this will
		     * be eliminated, and the c_rcursor call below (cursor
		     * mode) will be used for stdimage as well as for stdgraph.
		     * The present code (IMDRCUR) goes directly to the display
		     * server to get the cursor value, bypassing cursor mode
		     * and the (currently nonexistent) stdimage kernel.
		     */
		    char    str[SZ_LINE+1], keystr[10];
		    int     wcs, key;
		    float   x, y;

		    if (c_imdrcur ("stdimage",
			&x,&y,&wcs,&key,str,SZ_LINE, 1, 1) == EOF) {
			query_status = NULL;

		    } else {
			if (isprint(key) && !isspace(key))
			    sprintf (keystr, "%c", key);
			else
			    sprintf (keystr, "\\%03o", key);
			sprintf (buf, "%.3f %.3f %d %s %s\n",
			    x, y, wcs, keystr, str);
		        query_status = (char *) ((XINT) strlen(buf));
		    }

		} else if (c_rcursor (cursor, buf, SZ_PROMPTBUF) == EOF) {
		    query_status = NULL;
		} else
		    query_status = (char *) ((XINT) strlen(buf));

	    } else if (pp->p_type & PT_UKEY) {
		/* Read a user keystroke command from the terminal.
		 */
		pp->p_flags &= ~P_LEOF;
		if (c_rdukey (buf, SZ_PROMPTBUF) == EOF)
		    query_status = NULL;
		else
		    query_status = (char *) ((XINT) strlen(buf));

	    } else {
text_query:	fd = spf_open (buf, SZ_PROMPTBUF);
		pquery (pp, fdopen(fd,"a"));
		spf_close (fd);

		c_stgputline ((XINT)STDOUT, buf);
		if (c_stggetline ((XINT)STDIN, buf, SZ_PROMPTBUF) > 0)
		    query_status = (char *) ((XINT) strlen(buf));
		else
		    query_status = NULL;
	    }

	    ip = buf;

	    /* Set o to the current value of the parameter.  Beware that some
	     * of the logical branches which follow assume that struct o has
	     * been initialized to the current value of the parameter.
	     */
	    if (pp->p_type & PT_LIST)
		setopundef (&o);
	    else if (arrflag) {
		paramget(pp, FN_VALUE);
		poffset (offset);
		o = popop();
	    } else
		o = pp->p_valo;

	    /* Handle eof, a null-length line (lone carriage return),
	     * and line with more than SZ_LINE chars.  Ignore leading whitespace
	     * if basic type is not string.
	     */
	    if (query_status == NULL) {
		/* Typing eof will use current value (as will a lone
		 * newline) but if param is a list, it is a meaningful
		 * answer.
		 */
		if (pp->p_type & PT_LIST) {
		    closelist (pp);		/* close an existing file */
		    pp->p_flags |= P_LEOF;
		    o = makeop (eofstr, OT_STRING);
		    break;
		}
		goto testval;
	    }

	    /* Ignore leading whitespace if it is not significant for this
	     * datatype.  Do this before testing for empty line, so that a
	     * return such as " \n" is equivalent to "\n".  I.e., do not
	     * penalize the user if they type the space bar by accident before
	     * typing return to accept the default value.
	     */
	    if (bastype != OT_STRING || (pp->p_type & (PT_FILNAM|PT_PSET)))
		while (*ip == ' ' || *ip == '\t')
		    ip++;

	    if (*ip == '\n') {
		/* Blank lines usually just accept the current value
		 * but if the param is a string and is undefined,
		 * it sets the string to a (defined) nullstring.
		 */
		*ip = '\0';
		if (bastype == OT_STRING && opundef (&o))
		    o = makeop (ip, bastype);
		else
		    goto testval;
	    }

	    if ((nlp = index (ip, '\n')) != NULL)
		*nlp = '\0';			/* cancel the newline	*/
	    else
		goto testval;

	    /* Finally, we have handled the pathological cases...
	     */
	    if ((pp->p_type & PT_LIST) &&
		(!strcmp (ip,eofstr) || !strcmp (ip,"eof"))) {

		closelist (pp);
		pp->p_flags |= P_LEOF;
		o = makeop (eofstr, OT_STRING);
		break;

	    } else {
		if (arrflag) {
		    /* In querying for arrays we may set more than one
		     * element of the array in a single query.  However
		     * we must set the first element.  So we will pretend
		     * to be a scalar until that first element is set
		     * and then enter a loop where we may set other
		     * elements.
		     */
		    abuf = ip;
		    ip = nextstr(&abuf, stdin);
		    if (ip == NULL  ||  ip == (char *) ERR  ||  ip == undefval)
			goto testval;
		}

		o = makeop (ip, bastype);
	    }

testval:
	    /* If parameter value is in range, we are done.  If it is out of
	     * range and we are a batch job or an interactive terminal job,
	     * print an error message and request that the user enter a legal
	     * value.  If the CL is being run taking input from a file, abort,
	     * else we will go into a loop reading illegal values from the
	     * input file and printing out lots of error messages.
	     */
	    if (inrange (pp, &o))
		break;
	    else if (batch)
		eprintf ("\n[%d] %s", bkgno, oormsg);
	    else if (isatty (fileno (stdin)))
		eprintf ("%s\n", oormsg);
	    else
		cl_error (E_UERR, oormsg);
	}

	if (!(pp->p_type & PT_LIST)) {
	    /* update param with new value.
	     */
	    if (cldebug) {
		eprintf ("changing `%s.p_val' to ", pp->p_name);
		fprop (stderr, &o);
		eprintf ("\n");
	    }

	    pushop (&o);
	    paramset (pp, FN_VALUE);
	    pp->p_flags |= P_QUERY;
	}

	pushop (&o);

	if (arrflag  &&  query_status != NULL  &&  *ip != '\0') {
	    /* If we have an array assign values until something
	     * is used up or until we hit any error.
	     */
	    n_ele = 1;
	    forever {
		if (n_ele >= max_ele)		/* End of array. */
		    break;
		ip = nextstr(&abuf, stdin);

		if (ip == NULL)			/* End of query line. */
		    break;

		if (ip == (char *) ERR) {	/* Error on query line. */
		    eprintf("Error loading array value.\n");
		    break;
		}

		if (ip != undefval) {
		    o = makeop (ip, bastype);
		    if ( ! inrange (pp, &o) ) {	/* Not in range. */
			eprintf("Array value outside range.\n");
			break;
		    }

		    offset++;			/* Next element in array. */
		    poffset (offset);

		    pushop (&o);
		    paramset (pp, FN_VALUE);
		} else
		    offset++;

		n_ele++;
	    }
	}
Esempio n. 18
0
/* GQUERY -- Determine if the value of a parameter given by the user is OK.
 * Also, store the new value in the parameter; in the case of a list
 * structured parameter, the new value is the name of a new list file.
 * This routine is called by EPARAM to verify that the new parameter value
 * is inrange and set the new value if so.
 */
char *
gquery (
  struct param *pp,
  char	*string
)
{
	register char *ip;
	char	buf[SZ_LINE];
	char	*query_status, *nlp, *errmsg;
	int	arrflag, offset, bastype, batch;
	struct	operand o;
	char	*strcpy(), *index();

	bastype = pp->p_type & OT_BASIC;
	batch   = firstask->t_flags & T_BATCH;
	arrflag = pp->p_type & PT_ARRAY;

	if (arrflag)
	    offset = getoffset(pp);

	if (batch) {
	    errmsg = e1;
	    return (errmsg);
	} else
	    query_status = strcpy (buf, string);

	ip = buf;

	/* Set o to the current value of the parameter.  Beware that some
	 * of the logical branches which follow assume that struct o has
	 * been initialized to the current value of the parameter.
	 */
	if (pp->p_type & PT_LIST) {
	    setopundef (&o);
	} else if (arrflag) {
	    poffset (offset);
	    paramget (pp, FN_VALUE);
	    o = popop ();
	} else
	    o = pp->p_valo;

	/* Handle eof, a null-length line (lone carriage return),
	 * and line with more than SZ_LINE chars.  Ignore leading whitespace
	 * if basic type is not string.
	 */
	if (query_status == NULL)
	    goto testval;

	/* Ignore leading whitespace if it is not significant for this
	 * datatype.  Do this before testing for empty line, so that a
	 * return such as " \n" is equivalent to "\n".  I.e., do not
	 * penalize the user if they type the space bar by accident before
	 * typing return to accept the default value.
	 */
	if (bastype != OT_STRING || (pp->p_type & PT_LIST))
	    while (*ip == ' ' || *ip == '\t')
		ip++;

	if (*ip == '\n') {
	    /* Blank lines usually just accept the current value
	     * but if the param in a string and is undefined,
	     * it sets the string to a (defined) nullstring.
	     */
	    if (bastype == OT_STRING && opundef (&o)) {
		*ip = '\0';
		o = makeop (ip, bastype);
	    } else
		goto testval;
	}

	/* Cancel the newline. */
	if ((nlp = index (ip, '\n')) != NULL)
	    *nlp = '\0';

	/* Finally, we have handled the pathological cases.
	 */
	if (pp->p_type & PT_LIST)
	    o = makeop (string, OT_STRING);
	else
	    o = makeop (ip, bastype);

testval:   
	if (*string == '@')
	    errmsg = "OK";
	else if (pp->p_type & PT_LIST)
	    errmsg = "OK";
	else if (inrange (pp, &o))
	    errmsg = "OK";
	else {
	    errmsg = e2;
	    return (errmsg);
	}

	if (cldebug) {
	    eprintf ("changing `%s.p_val' to ", pp->p_name);
	    fprop (stderr, &o);
	    eprintf ("\n");
	}

	/* Update param with new value.
	 */
	pushop (&o);
	if (arrflag)
	    poffset (offset);

	paramset (pp, FN_VALUE);
	pp->p_flags |= P_SET;

	return ("OK");
}