📄 qcalc.c
字号:
/****************************************************************************** Product: Quantum Calculator Example* Last Updated for Version: 3.4.00* Date of the Last Update: Sep 03, 2007** Q u a n t u m L e a P s* ---------------------------* innovating embedded systems** Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved.** This software may be distributed and modified under the terms of the GNU* General Public License version 2 (GPL) as published by the Free Software* Foundation and appearing in the file GPL.TXT included in the packaging of* this file. Please note that GPL Section 2[b] requires that all works based* on this software must also be made publicly available under the terms of* the GPL ("Copyleft").** Alternatively, this software may be distributed and modified under the* terms of Quantum Leaps commercial licenses, which expressly supersede* the GPL and are specifically designed for licensees interested in* retaining the proprietary status of their code.** Contact information:* Quantum Leaps Web site: http://www.quantum-leaps.com* e-mail: info@quantum-leaps.com*****************************************************************************/#include "qep_port.h"#include "qcalc.h"#include "qassert.h"#include <string.h>#include <stdlib.h>#include <stdio.h>Q_DEFINE_THIS_FILE#define KEY_UNKNOWN '?'#define KEY_PLUS '+'#define KEY_MINUS '-'#define KEY_MULT '*'#define KEY_DIVIDE '/'/*..........................................................................*/void QCalc_ctor(QCalc *me) { QHsm_ctor_(&me->super_, (QState)&QCalc_initial);}/*..........................................................................*/char const *QCalc_getDisplay(QCalc const *me) { return me->display_;}/*..........................................................................*/void QCalc_clear_(QCalc *me) { memset(me->display_, ' ', DISP_WIDTH - 1); me->display_[DISP_WIDTH - 1] = '0'; me->display_[DISP_WIDTH] = '\0'; me->len_ = 0;}/*..........................................................................*/void QCalc_insert_(QCalc *me, int keyId) { if (me->len_ == 0) { me->display_[DISP_WIDTH - 1] = (char)keyId; ++me->len_; } else if (me->len_ < (DISP_WIDTH - 1)) { memmove(&me->display_[0], &me->display_[1], DISP_WIDTH - 1); me->display_[DISP_WIDTH - 1] = (char)keyId; ++me->len_; } else { }}/*..........................................................................*/void QCalc_negate_(QCalc *me) { QCalc_clear_(me); me->display_[DISP_WIDTH - 2] = '-';}/*..........................................................................*/int QCalc_eval_(QCalc *me) { int ok = 1; double result = 0.0; switch (me->opKey_) { case KEY_PLUS: { result = me->operand1_ + me->operand2_; break; } case KEY_MINUS: { result = me->operand1_ - me->operand2_; break; } case KEY_MULT: { result = me->operand1_ * me->operand2_; break; } case KEY_DIVIDE: { if ((me->operand2_ < -1e-10) || (1e-10 < me->operand2_)) { result = me->operand1_ / me->operand2_; } else { strcpy(me->display_, "Error 0"); /* divide by zero */ ok = 0; } break; } default: { Q_ERROR(); break; } } if (ok) { if ((-1.0e10 < result) && (result < 1.0e10)) { sprintf(me->display_, "%14.11g", result); } else { strcpy(me->display_, "Error 1"); /* Result out of range */ ok = 0; } } return ok;}/* HSM definition ----------------------------------------------------------*/void QCalc_initial(QCalc *me, QEvent const *e) { (void)e; /* suppress the "unreferenced parameter" warning */ me->operand1_ = 0.0; me->operand2_ = 0.0; me->opKey_ = KEY_UNKNOWN; QCalc_clear_(me); Q_INIT(&QCalc_on);}/*..........................................................................*/QSTATE QCalc_on(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "on-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "on-EXIT"); return (QSTATE)0; } case Q_INIT_SIG: { QCalc_updateState(me, "on-INIT"); Q_INIT(&QCalc_ready); return (QSTATE)0; } case C_SIG: { QCalc_clear_(me); Q_TRAN_STA(&QCalc_on); /* self-transition */ return (QSTATE)0; } case TERMINATE_SIG: { QCalc_exit(me); return (QSTATE)0; } } return (QSTATE)&QHsm_top;}/*..........................................................................*/QSTATE QCalc_error(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "error-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "error-EXIT"); return (QSTATE)0; } } return (QSTATE)&QCalc_on;}/*..........................................................................*/QSTATE QCalc_ready(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "ready-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "ready-EXIT"); return (QSTATE)0; } case Q_INIT_SIG: { QCalc_updateState(me, "ready-INIT"); Q_INIT(&QCalc_begin); return (QSTATE)0; } case DIGIT_0_SIG: { QCalc_clear_(me); Q_TRAN(&QCalc_zero1); return (QSTATE)0; } case DIGIT_1_9_SIG: { QCalc_clear_(me); QCalc_insert_(me, ((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc_int1); return (QSTATE)0; } case POINT_SIG: { QCalc_clear_(me); QCalc_insert_(me, (int)'0'); QCalc_insert_(me, (int)'.'); Q_TRAN(&QCalc_frac1); return (QSTATE)0; } case OPER_SIG: { me->operand1_ = strtod(me->display_, (char **)0); me->opKey_ = ((QCalcEvt *)e)->keyId; Q_TRAN(&QCalc_opEntered); return (QSTATE)0; } } return (QSTATE)&QCalc_on;}/*..........................................................................*/QSTATE QCalc_result(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "result-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "result-EXIT"); return (QSTATE)0; } } return (QSTATE)&QCalc_ready;}/*..........................................................................*/QSTATE QCalc_begin(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "begin-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "begin-EXIT"); return (QSTATE)0; } case OPER_SIG: { if (((QCalcEvt *)e)->keyId == KEY_MINUS) { Q_TRAN(&QCalc_negated1); return (QSTATE)0; /* event handled */ } break; } } return (QSTATE)&QCalc_ready;}/*..........................................................................*/QSTATE QCalc_negated1(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "negated1-ENTRY"); QCalc_negate_(me); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "negated1-EXIT"); return (QSTATE)0; } case OPER_SIG: { if (((QCalcEvt *)e)->keyId == KEY_MINUS) { ; /* explicitly ignore */ return (QSTATE)0; /* event handled */ } break; } case CE_SIG: { QCalc_clear_(me); Q_TRAN(&QCalc_begin); return (QSTATE)0; } case DIGIT_0_SIG: { QCalc_insert_(me, ((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc_zero1); return (QSTATE)0; } case DIGIT_1_9_SIG: { QCalc_insert_(me, ((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc_int1); return (QSTATE)0; } case POINT_SIG: { QCalc_insert_(me, ((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc_frac1); return (QSTATE)0; } } return (QSTATE)&QCalc_on;}/*..........................................................................*/QSTATE QCalc_negated2(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -