⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edit.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Classic Ladder Project *//* Copyright (C) 2001-2004 Marc Le Douarain *//* mavati@club-internet.fr *//* http://www.multimania.com/mavati/classicladder *//* May 2001 *//* ------ *//* Editor *//* ------ *//* This part of the editor is the one who will not change even if if we use *//* another gui instead of gtk... who know? *//* ------------------------------------------------------------- *//* This library is free software; you can redistribute it and/or *//* modify it under the terms of the GNU Lesser General Public *//* License as published by the Free Software Foundation; either *//* version 2.1 of the License, or (at your option) any later version. *//* This library is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *//* Lesser General Public License for more details. *//* You should have received a copy of the GNU Lesser General Public *//* License along with this library; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <gtk/gtk.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "classicladder.h"#include "global.h"#include "drawing.h"#include "edit.h"#include "editproperties_gtk.h"#include "calc.h"#include "files.h"#include "arithm_eval.h"#include "classicladder_gtk.h"#include "manager.h"#ifdef SEQUENTIAL_SUPPORT#include "edit_sequential.h"#endif/* This array give for each special elements the size used */#define TYPEELERULE 0#define XSIZEELERULE 1#define YSIZEELERULE 2static short int RulesForSpecialElements[5][3] = { {ELE_TIMER, 2, 2},{ELE_MONOSTABLE, 2, 2},{ELE_COMPAR, 3, 1},{ELE_OUTPUT_OPERATE, 3, 1},{-1, -1, -1}			/* end */};int ConvBaseInTextToId(char *text){    int ScanBase = 0;    int BaseFound = BASE_SECS;    do {	if (strcmp(text, CorresDatasForBase[ScanBase].ParamSelect) == 0)	    BaseFound = ScanBase;	ScanBase++;    }    while (ScanBase < NBR_TIMEBASES);    return BaseFound;}int ConvLabelToNumRung(char *LabelName){    int ScanRung = 0;    int RungFound = -1;    int Done = FALSE;    ScanRung = InfosGene->FirstRung;    do {	if (strcmp(RungArray[ScanRung].Label, LabelName) == 0)	    RungFound = ScanRung;	if (ScanRung == InfosGene->LastRung)	    Done = TRUE;	else	    ScanRung = RungArray[ScanRung].NextRung;    }    while (!Done);    return RungFound;}void LoadElementProperties(StrElement * Element){    char TextToWrite[100];    int NumParam;    StrTimer *Timer;    StrMonostable *Monostable;    for (NumParam = 0; NumParam < NBR_PARAMS_PER_OBJ; NumParam++)	SetProperty(NumParam, "---", "");    if (Element) {	switch (Element->Type) {	case ELE_INPUT:	case ELE_INPUT_NOT:	case ELE_RISING_INPUT:	case ELE_FALLING_INPUT:	case ELE_OUTPUT:	case ELE_OUTPUT_NOT:	case ELE_OUTPUT_SET:	case ELE_OUTPUT_RESET:	    strcpy(TextToWrite, DisplayInfo(Element->VarType,		    Element->VarNum));	    SetProperty(0, "Variable", TextToWrite);	    break;	case ELE_OUTPUT_JUMP:	    SetProperty(0, "JumpToLabel", RungArray[Element->VarNum].Label);	    break;	case ELE_OUTPUT_CALL:	    sprintf(TextToWrite, "%d", Element->VarNum);	    SetProperty(0, "Sub-Routine", TextToWrite);	    break;	case ELE_TIMER:	    Timer = &TimerArray[Element->VarNum];	    sprintf(TextToWrite, "%d", Element->VarNum);	    SetProperty(0, "Number", TextToWrite);	    sprintf(TextToWrite, "%s",		CorresDatasForBase[ConvBaseInMilliSecsToId(Timer->Base)].		ParamSelect);	    SetProperty(1, "Base", TextToWrite);	    sprintf(TextToWrite, "%d", Timer->Preset / Timer->Base);	    SetProperty(2, "Preset", TextToWrite);	    break;	case ELE_MONOSTABLE:	    Monostable = &MonostableArray[Element->VarNum];	    sprintf(TextToWrite, "%d", Element->VarNum);	    SetProperty(0, "Number", TextToWrite);	    sprintf(TextToWrite, "%s",		CorresDatasForBase[ConvBaseInMilliSecsToId(Monostable->Base)].		ParamSelect);	    SetProperty(1, "Base", TextToWrite);	    sprintf(TextToWrite, "%d", Monostable->Preset / Monostable->Base);	    SetProperty(2, "Preset", TextToWrite);	    break;	case ELE_COMPAR:	case ELE_OUTPUT_OPERATE:	    strcpy(TextToWrite,		DisplayArithmExpr(EditArithmExpr[Element->VarNum].Expr, 0));	    SetProperty(0, "Expression", TextToWrite);	    break;	}    }}/* Convert a string to a number if >=Min and <=Max *//* return TRUE if okay */int TextToNumber(char *text, int ValMin, int ValMaxi, int *ValFound){    int IsOk = TRUE;    int Value;    Value = atoi(text);    if ((Value < ValMin) || (Value > ValMaxi))	IsOk = FALSE;    if (IsOk)	*ValFound = Value;    return IsOk;}/* Convert a string to variable (type/offset) *//* return TRUE if okay */int TextParserForAVar(char *text, int *VarTypeFound, int *VarOffsetFound){    int TypeFound = -1;		// To avoid warnings.    int OffsetFound;    int IsOk = TRUE;#ifdef SEQUENTIAL_SUPPORT    char *pSearch;#endif    switch (text[0]) {    case 'B':	TypeFound = VAR_MEM_BIT;	if (!TextToNumber(&text[1], 0, NBR_BITS - 1, &OffsetFound))	    IsOk = FALSE;	break;    case 'T':	if (text[strlen(text) - 2] != ',') {	    IsOk = FALSE;	} else {	    switch (text[strlen(text) - 1]) {	    case 'D':		TypeFound = VAR_TIMER_DONE;		break;	    case 'R':		TypeFound = VAR_TIMER_RUNNING;		break;	    default:		IsOk = FALSE;		break;	    }	    text[strlen(text) - 2] = '\0';	    if (!TextToNumber(&text[1], 0, NBR_TIMERS - 1, &OffsetFound))		IsOk = FALSE;	}	break;    case 'M':	if (text[strlen(text) - 2] != ',') {	    IsOk = FALSE;	} else {	    switch (text[strlen(text) - 1]) {	    case 'R':		TypeFound = VAR_MONOSTABLE_RUNNING;		break;	    default:		IsOk = FALSE;		break;	    }	    text[strlen(text) - 2] = '\0';	    if (!TextToNumber(&text[1], 0, NBR_MONOSTABLES - 1, &OffsetFound))		IsOk = FALSE;	}	break;    case 'I':	TypeFound = VAR_PHYS_INPUT;	if (!TextToNumber(&text[1], 0, NBR_PHYS_INPUTS - 1, &OffsetFound))	    IsOk = FALSE;	break;    case 'Q':	TypeFound = VAR_PHYS_OUTPUT;	if (!TextToNumber(&text[1], 0, NBR_PHYS_OUTPUTS - 1, &OffsetFound))	    IsOk = FALSE;	break;    case 'W':	TypeFound = VAR_MEM_WORD;	if (!TextToNumber(&text[1], 0, NBR_WORDS - 1, &OffsetFound))	    IsOk = FALSE;	break;#ifdef SEQUENTIAL_SUPPORT    case 'X':	// verify if there is a ',' after number so that it must be the X..,V 	// 	// form	// instead of X... form.	pSearch = text;	do {	    pSearch++;	}	while (*pSearch >= '0' && *pSearch <= '9' && *pSearch != '\0');	if (*pSearch != ',') {	    TypeFound = VAR_STEP_ACTIVITY;	    if (!TextToNumber(&text[1], 0, NBR_STEPS - 1, &OffsetFound))		IsOk = FALSE;	} else {	    *pSearch = '\0';	    pSearch++;	    switch (*pSearch) {	    case 'V':		TypeFound = VAR_STEP_TIME;		break;	    default:		IsOk = FALSE;		break;	    }	    if (!TextToNumber(&text[1], 0, NBR_STEPS - 1, &OffsetFound))		IsOk = FALSE;	}	break;#endif    default:	IsOk = FALSE;    }    if (IsOk) {	*VarTypeFound = TypeFound;	*VarOffsetFound = OffsetFound;    }    return IsOk;}/* Convert a string of arithmetic expression for the arithm_eval : *//* Variables becomes @type/offset@ *//* Then verify all the expression using arithm_eval *//* return pointer on the new string converted and verified if okay, else NULL */char *TextParserForArithmExpr(char *text, int TypeElement){    static char NewExpr[100];    char Buffer[20];    int ItIsOk = TRUE;    int VarType;    int VarOffset;    char *ErrorMessage = NULL;    char *ptr = text;    strcpy(NewExpr, "");    /* Convert expression for variables authorized */    do {	/* Verify if it is a variable (character and number) */	if (*(ptr + 1) >= '0' && *(ptr + 1) <= '9') {	    switch (*ptr) {	    case 'W':		if (TextParserForAVar(ptr, &VarType, &VarOffset)) {		    sprintf(Buffer, "@%d/%d@", VarType, VarOffset);		    strcat(NewExpr, Buffer);		    do {			ptr++;		    }		    while ((*ptr >= '0') && (*ptr <= '9'));		} else {		    ItIsOk = FALSE;		}		break;	    case 'X':		if (TextParserForAVar(ptr, &VarType, &VarOffset)) {		    if (VarType == VAR_STEP_TIME) {			sprintf(Buffer, "@%d/%d@", VarType, VarOffset);			strcat(NewExpr, Buffer);			do {			    ptr++;			}			while (*ptr != 'V');			ptr++;		    } else {			ItIsOk = FALSE;			ErrorMessage = "Incompatible type of variable";		    }		} else {		    ItIsOk = FALSE;		}		break;	    case 'B':	    case 'T':	    case 'M':	    case 'I':	    case 'Q':		ItIsOk = FALSE;		ErrorMessage = "Incompatible type of variable";		break;	    case '\0':		ItIsOk = FALSE;		ErrorMessage = "Null expression not valid";		break;	    default:		sprintf(Buffer, "%c", *ptr);		strcat(NewExpr, Buffer);		ptr++;		break;	    }	} else {	    sprintf(Buffer, "%c", *ptr);	    strcat(NewExpr, Buffer);	    ptr++;	}    }    while ((*ptr) && ItIsOk);    /* Verify length of the expression */    if (ItIsOk) {	if (strlen(NewExpr) >= ARITHM_EXPR_SIZE) {	    ItIsOk = FALSE;	    ErrorMessage = "Expression too long";	}    }//printf("Parser Arithm ; ItIsOk=%d ; OriExpr=%s ; NewExpr=%s\n",ItIsOk, text, NewExpr);    /* Verify expression converted */    if (ItIsOk) {	if (TypeElement == ELE_OUTPUT_OPERATE)	    ErrorMessage = VerifySyntaxForMakeCalc(NewExpr);	else	    ErrorMessage = VerifySyntaxForEvalCompare(NewExpr);	if (ErrorMessage)	    ItIsOk = FALSE;    }    /* Error Message */    if (ErrorMessage) {	ShowMessageBox("Error", ErrorMessage, "Ok");    }    /* Give result */    if (ItIsOk)	return NewExpr;    else	return NULL;}void SaveElementProperties(){    int IdBase;    int Preset;    int NumRungToJump;    StrTimer *Timer;    StrMonostable *Monostable;    char *NewArithmExpr;    int SubRoutineToCall;#ifdef SEQUENTIAL_SUPPORT    int iCurrentLanguage = SectionArray[InfosGene->CurrentSection].Language;    if (iCurrentLanguage == SECTION_IN_SEQUENTIAL) {	SaveSeqElementProperties();	return;    }#endif    if (EditDatas.ElementUnderEdit) {	switch (EditDatas.ElementUnderEdit->Type) {	case ELE_INPUT:	case ELE_INPUT_NOT:	case ELE_RISING_INPUT:	case ELE_FALLING_INPUT:	case ELE_OUTPUT:	case ELE_OUTPUT_NOT:	case ELE_OUTPUT_SET:	case ELE_OUTPUT_RESET:	    TextParserForAVar(GetProperty(0),		&EditDatas.ElementUnderEdit->VarType,		&EditDatas.ElementUnderEdit->VarNum);	    break;	case ELE_TIMER:	    TextToNumber(GetProperty(0), 0, NBR_TIMERS - 1,		&EditDatas.ElementUnderEdit->VarNum);	    Timer = &TimerArray[EditDatas.ElementUnderEdit->VarNum];	    IdBase = ConvBaseInTextToId(GetProperty(1));	    Timer->Base = CorresDatasForBase[IdBase].ValueInMS;	    strcpy(Timer->DisplayFormat,		CorresDatasForBase[IdBase].DisplayFormat);	    if (TextToNumber(GetProperty(2), 0, 999, &Preset))		Timer->Preset = Preset * Timer->Base;	    break;	case ELE_MONOSTABLE:	    TextToNumber(GetProperty(0), 0, NBR_MONOSTABLES - 1,		&EditDatas.ElementUnderEdit->VarNum);	    Monostable = &MonostableArray[EditDatas.ElementUnderEdit->VarNum];	    IdBase = ConvBaseInTextToId(GetProperty(1));	    Monostable->Base = CorresDatasForBase[IdBase].ValueInMS;	    strcpy(Monostable->DisplayFormat,		CorresDatasForBase[IdBase].DisplayFormat);	    if (TextToNumber(GetProperty(2), 0, 999, &Preset))		Monostable->Preset = Preset * Monostable->Base;	    break;	case ELE_OUTPUT_JUMP:	    NumRungToJump = ConvLabelToNumRung(GetProperty(0));	    if (NumRungToJump >= 0)		EditDatas.ElementUnderEdit->VarNum = NumRungToJump;	    break;	case ELE_OUTPUT_CALL:	    if (TextToNumber(GetProperty(0), 0, NBR_SECTIONS - 1,		    &SubRoutineToCall)) {		if (VerifyIfSubRoutineNumberExist(SubRoutineToCall))		    EditDatas.ElementUnderEdit->VarNum = SubRoutineToCall;	    }	    break;	case ELE_COMPAR:	    NewArithmExpr =		TextParserForArithmExpr(GetProperty(0), ELE_COMPAR);	    if (NewArithmExpr)		strcpy(EditArithmExpr[EditDatas.ElementUnderEdit->VarNum].		    Expr, NewArithmExpr);	    break;	case ELE_OUTPUT_OPERATE:	    NewArithmExpr =		TextParserForArithmExpr(GetProperty(0), ELE_OUTPUT_OPERATE);	    if (NewArithmExpr)		strcpy(EditArithmExpr[EditDatas.ElementUnderEdit->VarNum].		    Expr, NewArithmExpr);	    break;	}	/* display back to show what we have really understand... */	LoadElementProperties(EditDatas.ElementUnderEdit);    }}/* For editing, we do not touch directly the current arithm   expressions. We work on the edit ones. It is only when the   edited rung is applyed that we copy the expressions edited */void CopyCurrentArithmExpr(){    int NumExpr;    for (NumExpr = 0; NumExpr < NBR_ARITHM_EXPR; NumExpr++)	strcpy(EditArithmExpr[NumExpr].Expr, ArithmExpr[NumExpr].Expr);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -