📄 int_variable.c
字号:
/*..........................................................................*//* *//* L a s t W a v e K e r n e l 3 . 0 *//* *//* Copyright (C) 1998-2003 Emmanuel Bacry. *//* email : lastwave@cmap.polytechnique.fr *//* *//*..........................................................................*//* *//* This program is a free software, you can redistribute it and/or *//* modify it under the terms of the GNU General Public License as *//* published by the Free Software Foundation; either version 2 of the *//* License, or (at your option) any later version *//* *//* This program 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 General Public License for more details. *//* *//* You should have received a copy of the GNU General Public License *//* along with this program (in a file named COPYRIGHT); *//* if not, write to the Free Software Foundation, Inc., *//* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* *//*..........................................................................*/#include "lastwave.h"#include "signals.h"#include "images.h"#include "int_fsilist.h"#include "xx_system.h"/* Maximum variable (or field) name length */#define MaxNameLength 50char *varType = "&var";/***************************************************************** * * (Des)Allocation of Variables * *****************************************************************/ /* * Allocation of a variable */VARIABLE GetVariableHT(HASHTABLE *t, char flagCreate, char *name, char **left, char *flag);static VARIABLE NewVariable(void) { extern TypeStruct tsVar; VARIABLE variable; #ifdef DEBUGALLOCDebugType = "Variable";#endif variable = (VARIABLE) Malloc(sizeof(struct variable)); InitValue(variable,&tsVar); variable->name = NULL; variable->content = NULL; variable->traceVarName = NULL; variable->hashTable = NULL; return(variable);}static VALUE NewVar(void) { return(nullValue);}/* * Desallocation of a variable * * (not to be used by the user) * Delete the variable structure (variable has been removed from hash table already */static void DeleteVariable_(VALUE v){ VARIABLE variable = (VARIABLE) v; VARIABLE var1; RemoveRefValue( variable); if (variable->nRef > 0) return; if (variable->content != NULL) { /* Case the content is not a variable */ if (!IsVariable(variable->content)) DeleteValue(variable->content); /* Case it is a variable */ else { var1 = (VARIABLE) variable->content; /* We must delete var1 if there is just one reference to it or if there are 2 and it is pointing to a null content */ if (var1->nRef == 2 && var1->content == NULL) var1->nRef = 1; if (var1->nRef > 1) RemoveRefValue( var1); else { if (var1->hashTable) GetRemoveElemHashTable(var1->hashTable,var1->name); DeleteVariable_((VALUE) var1); } } } variable->content = NULL; if (variable->nRef <= 0) { if (variable->name != NULL) Free(variable->name); if (variable->traceVarName != NULL) Free(variable->traceVarName); #ifdef DEBUGALLOCDebugType = "Variable";#endif Free(variable); }}/* * Regular desallocation */ void DeleteVariableLevel(LEVEL level, char *name){ VARIABLE var; HASHTABLE t; char *left; char flag; while (level->levelVar != level) level = level->levelVar; t = level->theVariables; var = GetVariableHT(&t,0,name,&left,&flag); if (flag != 0 || *left != '\0') Errorf1(""); GetRemoveElemHashTable(t,var->name); DeleteVariable_((VALUE) var);}void DeleteVariable(char *name){ DeleteVariableLevel(levelCur, name);}/* Delete Variable if it exists */void DeleteVariableIfExistLevel(LEVEL level, char *name){ VARIABLE var; HASHTABLE t; char *left,flag; while (level->levelVar != level) level = level->levelVar; t = level->theVariables; var = GetVariableHT(&t,0,name,&left,&flag); /* case variable does not exist */ if (flag == 2) return; /* Case there is an error */ if (flag != 0 || *left != '\0') Errorf1(""); /* Case we should delete it */ GetRemoveElemHashTable(t,var->name); DeleteVariable_((VALUE) var);}void DeleteVariableIfExist(char *name){ DeleteVariableIfExistLevel(levelCur, name);}/* * String conversion */char *ToStrVar(VARIABLE val, char flagShort){ if (val->content == NULL) return(""); return(ToStrValue(val->content, flagShort));}/* * Print a variable */void PrintVar(VARIABLE val){ if (val->content == NULL) return; PrintValue(val->content);}/* * Print the info of a variable */void PrintInfoVar(VARIABLE val){ if (val->content == NULL) return; PrintInfoValue(val->content);}/* * Get the type of a variable */ static char *GetTypeVar(VALUE val){ if (((VARIABLE) val)->content == NULL) return(NULL); return(GetTypeValue(((VARIABLE) val)->content));}/* * Set a field */static void *SetFieldVar(VALUE v, void **arg){ VARIABLE var = (VARIABLE) v; char *field; FSIList *fsiList; char *type,*type1,**pstrRes; LWFLOAT flt,*pfltRes; VALUE val,*pcont1,*pValueRes; char *equal; extern char *SetStr_(char **str,FSIList *fsiList, LWFLOAT flt, VALUE val,char *equal, char *fieldName); extern char *SetNum_(LWFLOAT *f, LWFLOAT flt, VALUE val,char *equal, char *fieldName); extern void *SendMessage2Num(void *content,int message,void **arg); extern void *SendMessage2Str(void *content,int message,void **arg); extern void *SetFieldArg(VALUE value, void **arg); field = ARG_S_GetField(arg); fsiList = ARG_S_GetFsiList(arg); type = ARG_S_GetRightType(arg); flt = ARG_S_GetRightFloat(arg); val = ARG_S_GetRightValue(arg); equal = ARG_S_GetEqual(arg); pValueRes = ARG_S_GetResPValue(arg); pfltRes = ARG_S_GetResPFloat(arg); pstrRes = ARG_S_GetResPStr(arg); /* There should be no field and no fsiList */ if (field != NULL || fsiList != NULL) { SetErrorf("SetFieldVar() : Weird"); return(NULL); } /* Get a pointer to the variable content and its type */ pcont1 = GetVariablePContent(var,NO); type1 = GetTypeValue(*pcont1); /* Check if we can overwrite the variable with the value */ if (*equal == '=' && !DoesTypeOverwrite(type1,type)) { SetErrorf("Cannot overwrite '%s' variable with '%s' value",type1,type); return(NULL); } /* If the value to set is a variable then we must set it unless it loops !!!! */ if (val != NULL && IsVariable(val)) { if (ValueOf(val) == *pcont1) { SetErrorf("Sorry, no recursive reference allowed"); return(NULL); } DeleteValue(*pcont1); *pcont1 = val; AddRefValue(val); *pValueRes = ValueOf(val); return(GetTypeValue(val)); } /* Get the real content of val */ if (val != NULL) val = ValueOf(val); /*************************** * * Managing operators *=, +=, := ... * ***************************/ /* If variable type is a number and operator is not '=', it must be handled by the SetNum_ routine */ if (*equal != '=' && type1 == numType) { if (SetNum_(&(((NUMVALUE) *pcont1)->f),flt,val,equal,NULL) == NULL) return(NULL); *pfltRes = (((NUMVALUE) *pcont1)->f); return(numType); } /* If variable type is a string and operator is not '=', it must be handled by the SetStr_ routine */ if (*equal != '=' && type1 == strType) { if (SetStr_(&(((STRVALUE) *pcont1)->str),NULL,flt,val,equal,NULL) == NULL) return(NULL); *pstrRes = (((STRVALUE) *pcont1)->str); return(strType); } /* If variable type is a signal and operator is not '=', it must be handled by the SetSignalField_ routine */ if (*equal != '=' && type1 == signaliType) { if (SetSignalField_((SIGNAL) *pcont1,NULL,NULL,flt,val,equal,NULL) == NULL) return(NULL); *pValueRes = *pcont1; return(type1); } /* Other cases */ if (*equal != '=') { return(SetFieldArg(*pcont1,arg)); } /*************************** * * Limit (des)allocation * ***************************/ /* Limit (des)allocation in case of a number */ if (type1 == numType && type == numType && (*pcont1)->nRef == 1) { if (val == NULL) SetNumValue((NUMVALUE) (*pcont1),flt); else SetNumValue((NUMVALUE) (*pcont1),((NUMVALUE) val)->f); *pfltRes = ((NUMVALUE) (*pcont1))->f; return(numType); } /* Limit (des)allocation in case of a range */ if (type1 == rangeType && type == rangeType && (*pcont1)->nRef == 1) { ((RANGE) (*pcont1))->first = ((RANGE) val)->first; ((RANGE) (*pcont1))->step = ((RANGE) val)->step; ((RANGE) (*pcont1))->size = ((RANGE) val)->size; *pValueRes = *pcont1; return(rangeType); } /*************************** * * If the value to set is a variable content with a count ref of 1 then just set it * ***************************/ if (val != NULL && val->nRef == 1) { DeleteValue(*pcont1); *pcont1 = val; AddRefValue(val); *pValueRes = val; return(type1); } /*************************** * * Handle copying if any * ***************************. /* If the value to set is a number then we must create a number content */ if (val == NULL || type == numType) { DeleteValue(*pcont1); *pcont1 = (VALUE) NewNumValue(); if (val == NULL) SetNumValue((NUMVALUE) (*pcont1),flt); else SetNumValue((NUMVALUE) (*pcont1),((NUMVALUE) val)->f); *pfltRes = ((NUMVALUE) *pcont1)->f; return(numType); } /* If the value to set is a string */ if (type == strType) { DeleteValue(*pcont1); *pcont1 = (VALUE) NewStrValue(); SetStrValue((STRVALUE) (*pcont1),((STRVALUE) val)->str); *pstrRes = ((STRVALUE) val)->str; return(strType); } /* If the value to set is a range then we must create a range content */ if (type == rangeType) { DeleteValue(*pcont1); *pcont1 = (VALUE) NewRange(); ((RANGE) (*pcont1))->first = ((RANGE) val)->first; ((RANGE) (*pcont1))->step = ((RANGE) val)->step; ((RANGE) (*pcont1))->size = ((RANGE) val)->size; *pValueRes = *pcont1; return(rangeType); } /*************************** * * Regular case * ***************************/ DeleteValue(*pcont1); *pcont1 = val; AddRefValue(val); *pValueRes = *pcont1; return(type1); }/* * NumExtract */void *NumExtractVar(VALUE v, void **arg){ if (((VARIABLE) v)->content == NULL) return("");/* NumExtractValue(v,arg); ??*/ return(NumExtractValue(((VARIABLE) v)->content,arg));}/* * The field list */struct field fieldsVariable[] = { NULL, NULL, NULL, NULL, NULL};/* * The type structure for VARIABLE */TypeStruct tsVar = { "", /* Documentation */ &varType, /* The basic (unique) type name */ GetTypeVar, /* The GetType function */ DeleteVariable_, /* The Delete function */ NewVar, /* The New function */ NULL, /* The copy function */ NULL, /* The clear function */ ToStrVar, /* String conversion */ PrintVar, /* The Print function : print the object when 'print' is called */ PrintInfoVar, /* The PrintInfo function : called by 'info' */ NumExtractVar, /* The NumExtract function : used to deal with syntax like 10a */ fieldsVariable, /* The list of fields */};/* * Functions to manage types *//* The variables to manage new variable types */#define NVarTypes 100 char *varTypeNames[NVarTypes];TypeStruct *typeStruct[NVarTypes];void *varTypeParseFunctions[NVarTypes];char *typePackage[NVarTypes];int varTypes[NVarTypes];int nVarTypes = 0;/* Get a type from its name */char * GetArgType(char *str){ int i; extern TypeStruct tsNull; if (!strcmp(str,nullType)) return(nullType); if (!strcmp(str,"&str")) return(strType); if (!strcmp(str,strType)) return(strType); if (!strcmp(str,valType)) return(valType); if (!strcmp(str,valobjType)) return(valobjType); if (!strcmp(str,wordType)) return(wordType); if (!strcmp(str,wordlistType)) return(wordlistType); if (!strcmp(str,listType)) return(listType); if (!strcmp(str,listvType)) return(listvType); if (!strcmp(str,rangeType)) return(rangeType);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -