Exemplo n.º 1
0
static void initPeriodic(void)
{
    dbMenu *pmenu = dbFindMenu(pdbbase, "menuScan");
    double quantum = epicsThreadSleepQuantum();
    int i;

    if (!pmenu) {
        errlogPrintf("initPeriodic: menuScan not present\n");
        return;
    }
    nPeriodic = pmenu->nChoice - SCAN_1ST_PERIODIC;
    papPeriodic = dbCalloc(nPeriodic, sizeof(periodic_scan_list*));
    periodicTaskId = dbCalloc(nPeriodic, sizeof(void *));
    for (i = 0; i < nPeriodic; i++) {
        periodic_scan_list *ppsl = dbCalloc(1, sizeof(periodic_scan_list));
        const char *choice = pmenu->papChoiceValue[i + SCAN_1ST_PERIODIC];
        double number;
        char *unit;
        int status = epicsParseDouble(choice, &number, &unit);

        ppsl->scan_list.lock = epicsMutexMustCreate();
        ellInit(&ppsl->scan_list.list);
        ppsl->name = choice;
        if (status || number == 0) {
            errlogPrintf("initPeriodic: Bad menuScan choice '%s'\n", choice);
            ppsl->period = i;
        }
        else if (!*unit ||
                 !epicsStrCaseCmp(unit, "second") ||
                 !epicsStrCaseCmp(unit, "seconds")) {
            ppsl->period = number;
        }
        else if (!epicsStrCaseCmp(unit, "minute") ||
                 !epicsStrCaseCmp(unit, "minutes")) {
            ppsl->period = number * 60;
        }
        else if (!epicsStrCaseCmp(unit, "hour") ||
                 !epicsStrCaseCmp(unit, "hours")) {
            ppsl->period = number * 60 * 60;
        }
        else if (!epicsStrCaseCmp(unit, "Hz") ||
                 !epicsStrCaseCmp(unit, "Hertz")) {
            ppsl->period = 1 / number;
        }
        else {
            errlogPrintf("initPeriodic: Bad menuScan choice '%s'\n", choice);
            ppsl->period = i;
        }
        number = ppsl->period / quantum;
        if ((ppsl->period < 2 * quantum) ||
            (number / floor(number) > 1.1)) {
            errlogPrintf("initPeriodic: Scan rate '%s' is not achievable.\n",
                choice);
        }
        ppsl->scanCtl = ctlPause;
        ppsl->loopEvent = epicsEventMustCreate(epicsEventEmpty);

        papPeriodic[i] = ppsl;
    }
}
Exemplo n.º 2
0
epicsShareFunc int
epicsParseFloat(const char *str, float *to, char **units)
{
    double value, abs;
    int status = epicsParseDouble(str, &value, units);

    if (status)
        return status;

    abs = fabs(value);
    if (value > 0 && abs <= FLT_MIN)
        return S_stdlib_underflow;
    if (finite(value) && abs >= FLT_MAX)
        return S_stdlib_overflow;

    *to = (float) value;
    return 0;
}
Exemplo n.º 3
0
/* postfix
 *
 * convert an infix expression to a postfix expression
 */
epicsShareFunc long
    postfix(const char *psrc, char *pout, short *perror)
{
    ELEMENT stack[80];
    ELEMENT *pstacktop = stack;
    const ELEMENT *pel;
    int operand_needed = TRUE;
    int runtime_depth = 0;
    int cond_count = 0;
    char * const pdest = pout;
    char *pnext;

    if (psrc == NULL || *psrc == '\0' ||
	pout == NULL || perror == NULL) {
	if (perror) *perror = CALC_ERR_NULL_ARG;
	if (pout) *pout = END_EXPRESSION;
	return -1;
    }

    /* place the expression elements into postfix */
    *pout = END_EXPRESSION;
    *perror = CALC_ERR_NONE;

    while (get_element(operand_needed, &psrc, &pel)) {
	switch (pel->type) {

	case OPERAND:
	    *pout++ = pel->code;
	    runtime_depth += pel->runtime_effect;
	    operand_needed = FALSE;
	    break;

        case LITERAL_OPERAND:
            runtime_depth += pel->runtime_effect;

            psrc -= strlen(pel->name);
            if (pel->code == LITERAL_DOUBLE) {
                double lit_d;
                epicsInt32 lit_i;

                if (epicsParseDouble(psrc, &lit_d, &pnext)) {
                    *perror = CALC_ERR_BAD_LITERAL;
                    goto bad;
                }
                psrc = pnext;
                lit_i = (int) lit_d;
                if (lit_d != (double) lit_i) {
                    *pout++ = pel->code;
                    memcpy(pout, &lit_d, sizeof(double));
                    pout += sizeof(double);
                } else {
                    *pout++ = LITERAL_INT;
                    memcpy(pout, &lit_i, sizeof(epicsInt32));
                    pout += sizeof(epicsInt32);
                }
            }
            else {
                epicsUInt32 lit_ui;

                assert(pel->code == LITERAL_INT);
                if (epicsParseUInt32(psrc, &lit_ui, 0, &pnext)) {
                    *perror = CALC_ERR_BAD_LITERAL;
                    goto bad;
                }
                psrc = pnext;
                *pout++ = LITERAL_INT;
                memcpy(pout, &lit_ui, sizeof(epicsInt32));
                pout += sizeof(epicsInt32);
            }

            operand_needed = FALSE;
            break;

	case STORE_OPERATOR:
	    if (pout == pdest || pstacktop > stack ||
		*--pout < FETCH_A || *pout > FETCH_L) {
		*perror = CALC_ERR_BAD_ASSIGNMENT;
		goto bad;
	    }
	    /* Convert fetch into a store on the stack */
	    *++pstacktop = *pel;
	    pstacktop->code = STORE_A + *pout - FETCH_A;
	    runtime_depth -= 1;
	    operand_needed = TRUE;
	    break;

	case UNARY_OPERATOR:
	case VARARG_OPERATOR:
	    /* Move operators of >= priority to the output */
	    while ((pstacktop > stack) &&
		   (pstacktop->in_stack_pri >= pel->in_coming_pri)) {
		*pout++ = pstacktop->code;
		if (pstacktop->type == VARARG_OPERATOR) {
		    *pout++ = 1 - pstacktop->runtime_effect;
		}
		runtime_depth += pstacktop->runtime_effect;
		pstacktop--;
	    }

	    /* Push new operator onto stack */
	    pstacktop++;
	    *pstacktop = *pel;
	    break;

	case BINARY_OPERATOR:
	    /* Move operators of >= priority to the output */
	    while ((pstacktop > stack) &&
		   (pstacktop->in_stack_pri >= pel->in_coming_pri)) {
		*pout++ = pstacktop->code;
		if (pstacktop->type == VARARG_OPERATOR) {
		    *pout++ = 1 - pstacktop->runtime_effect;
		}
		runtime_depth += pstacktop->runtime_effect;
		pstacktop--;
	    }

	    /* Push new operator onto stack */
	    pstacktop++;
	    *pstacktop = *pel;

	    operand_needed = TRUE;
	    break;

	case SEPERATOR:
	    /* Move operators to the output until open paren */
	    while (pstacktop->name[0] != '(') {
		if (pstacktop <= stack+1) {
		    *perror = CALC_ERR_BAD_SEPERATOR;
		    goto bad;
		}
		*pout++ = pstacktop->code;
		if (pstacktop->type == VARARG_OPERATOR) {
		    *pout++ = 1 - pstacktop->runtime_effect;
		}
		runtime_depth += pstacktop->runtime_effect;
		pstacktop--;
	    }
	    operand_needed = TRUE;
	    pstacktop->runtime_effect -= 1;
	    break;

	case CLOSE_PAREN:
	    /* Move operators to the output until matching paren */
	    while (pstacktop->name[0] != '(') {
		if (pstacktop <= stack+1) {
		    *perror = CALC_ERR_PAREN_NOT_OPEN;
		    goto bad;
		}
		*pout++ = pstacktop->code;
		if (pstacktop->type == VARARG_OPERATOR) {
		    *pout++ = 1 - pstacktop->runtime_effect;
		}
		runtime_depth += pstacktop->runtime_effect;
		pstacktop--;
	    }
	    pstacktop--;	/* remove ( from stack */
	    /* if there is a vararg operator before the opening paren,
	       it inherits the (opening) paren's stack effect */
	    if ((pstacktop > stack) &&
		pstacktop->type == VARARG_OPERATOR) {
		pstacktop->runtime_effect = (pstacktop+1)->runtime_effect;
		/* check for no arguments */
		if (pstacktop->runtime_effect > 0) {
		    *perror = CALC_ERR_INCOMPLETE;
		    goto bad;
		}
	    }
	    break;

	case CONDITIONAL:
	    /* Move operators of > priority to the output */
	    while ((pstacktop > stack) &&
		   (pstacktop->in_stack_pri > pel->in_coming_pri)) {
		*pout++ = pstacktop->code;
		if (pstacktop->type == VARARG_OPERATOR) {
		    *pout++ = 1 - pstacktop->runtime_effect;
		}
		runtime_depth += pstacktop->runtime_effect;
		pstacktop--;
	    }

	    /* Add new element to the output */
	    *pout++ = pel->code;
	    runtime_depth += pel->runtime_effect;

	    /* For : operator, also push COND_END code to stack */
	    if (pel->name[0] == ':') {
		if (--cond_count < 0) {
		    *perror = CALC_ERR_CONDITIONAL;
		    goto bad;
		}
		pstacktop++;
		*pstacktop = *pel;
		pstacktop->code = COND_END;
		pstacktop->runtime_effect = 0;
	    } else {
		cond_count++;
	    }

	    operand_needed = TRUE;
	    break;

	case EXPR_TERMINATOR:
	    /* Move everything from stack to the output */
	    while (pstacktop > stack) {
		if (pstacktop->name[0] == '(') {
		    *perror = CALC_ERR_PAREN_OPEN;
		    goto bad;
		}
		*pout++ = pstacktop->code;
		if (pstacktop->type == VARARG_OPERATOR) {
		    *pout++ = 1 - pstacktop->runtime_effect;
		}
		runtime_depth += pstacktop->runtime_effect;
		pstacktop--;
	    }

	    if (cond_count != 0) {
		*perror = CALC_ERR_CONDITIONAL;
		goto bad;
	    }
	    if (runtime_depth > 1) {
		*perror = CALC_ERR_TOOMANY;
		goto bad;
	    }

	    operand_needed = TRUE;
	    break;

	default:
	    *perror = CALC_ERR_INTERNAL;
	    goto bad;
	}

	if (runtime_depth < 0) {
	    *perror = CALC_ERR_UNDERFLOW;
	    goto bad;
	}
	if (runtime_depth >= CALCPERFORM_STACK) {
	    *perror = CALC_ERR_OVERFLOW;
	    goto bad;
	}
    }

    if (*psrc != '\0') {
	*perror = CALC_ERR_SYNTAX;
	goto bad;
    }

    /* Move everything from stack to the output */
    while (pstacktop > stack) {
	if (pstacktop->name[0] == '(') {
	    *perror = CALC_ERR_PAREN_OPEN;
	    goto bad;
	}
	*pout++ = pstacktop->code;
	if (pstacktop->type == VARARG_OPERATOR) {
	    *pout++ = 1 - pstacktop->runtime_effect;
	}
	runtime_depth += pstacktop->runtime_effect;
	pstacktop--;
    }
    *pout = END_EXPRESSION;

    if (cond_count != 0) {
	*perror = CALC_ERR_CONDITIONAL;
	goto bad;
    }
    if (operand_needed || runtime_depth != 1) {
	*perror = CALC_ERR_INCOMPLETE;
	goto bad;
    }
    return 0;

bad:
    *pdest = END_EXPRESSION;
    return -1;
}