Files
SAPFOR/dvm/fdvm/trunk/Sage/lib/newsrc/toolsann.c

1044 lines
20 KiB
C
Raw Normal View History

2023-09-14 19:43:13 +03:00
/*********************************************************************/
/* pC++/Sage++ Copyright (C) 1993,1995 */
/* Indiana University University of Oregon University of Rennes */
/*********************************************************************/
/**************************************************************************
* * * Annotation toolbox for Sigma * * * * *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "compatible.h" /* Make different system compatible... (PHB) */
#ifdef SYS5
#include <string.h>
#else
#include <strings.h>
#endif
#include "macro.h"
#include "ext_lib.h"
#include "ext_low.h"
#define ASYMBOLEXT "_%d_" /* must have a %d field for number */
#define MAX_ANNOTATION 10000
#define ForCOMMENTSTART "C$ann\0" /* For fortran Must start with big C */
#define ForCOMMENTCONT "C$cont\0" /* idem */
#define C_COMMENTSTART "//$ann\0" /* For C Must start with big / */
#define C_COMMENTCONT "-+-++++--\0" /* not in C */
#ifdef __SPF
extern void addToCollection(const int line, const char *file, void *pointer, int type);
extern void removeFromCollection(void *pointer);
#endif
int TRACEANN = 0;
/* Assertion Tab */
extern int Number_of_proc;
extern PTR_FILE pointer_on_file_proj;
extern PTR_LLND ANNOTATE_NODE;
extern char *STRINGTOPARSE;
extern int LENSTRINGTOPARSE;
extern int PTTOSTRINGTOPARSE;
extern PTR_BFND ANNOTATIONSCOPE;
extern PTR_TYPE global_int_annotation;
extern char AnnExTensionNumber[];
2024-10-04 15:26:19 +03:00
extern int yyparse_annotate(void);
2023-09-14 19:43:13 +03:00
/* FORWARD DECLARATION */
int Get_Scope_Of_Annotation();
void Propagate_defined_value();
int Set_The_Define_Field();
char *Unparse_Annotation();
PTR_LLND Parse_Annotation();
char *
Remove_Ann_Cont(str)
char *str;
{
int i =0;
int j;
if (str == NULL)
return NULL;
if (Check_Lang_Fortran(cur_proj))
{ /* does not apply to C */
while (str[i] != '\0')
{
if (str[i] == 'C')
{
if (strncmp(&(str[i]),ForCOMMENTCONT,strlen(ForCOMMENTCONT)) == 0)
{
for (j = 0; j < (int)strlen(ForCOMMENTCONT); j++)
str[i+j] = ' ';
i = i+j;
}
}
i++;
}
}
return str;
}
/* Init annotation System, mainly gathers annotation */
/* we use array to store annotation can be modify to count the size and alloc
things */
static char *Annotation_PT[MAX_ANNOTATION]; /* the string */
static PTR_BFND Annotation_BIFND[MAX_ANNOTATION]; /* the bif node next */
PTR_LLND Annotation_LLND[MAX_ANNOTATION]; /* result of unparse */
static PTR_CMNT Annotation_CMNT[MAX_ANNOTATION]; /* to the comment */
static int Annotation_Def[MAX_ANNOTATION]; /* is it define */
static int Nb_Annotation; /* number of annotation found */
static char *Defined_Value_Str[MAX_ANNOTATION];
static int Defined_Value_Value[MAX_ANNOTATION];
/* Indicate if comment is an annotation */
2024-10-04 15:26:19 +03:00
int Is_Annotation(str)
2023-09-14 19:43:13 +03:00
char *str;
{
if (!str)
return FALSE;
if (Check_Lang_Fortran(cur_proj))
{
if (strncmp(ForCOMMENTSTART,str, strlen(ForCOMMENTSTART)) == 0)
return TRUE;
else
return FALSE;
} else
{
if (strncmp(C_COMMENTSTART,str, strlen(C_COMMENTSTART)) == 0)
return TRUE;
else
return FALSE;
}
}
2024-10-04 15:26:19 +03:00
int Is_Annotation_Cont(str)
2023-09-14 19:43:13 +03:00
char *str;
{
if (!str)
return FALSE;
if (!Check_Lang_Fortran(cur_proj))
return FALSE;
if (strncmp(ForCOMMENTCONT,str, strlen(ForCOMMENTCONT)) == 0)
return TRUE;
else
return FALSE;
}
char *
Get_Annotation_String(str)
char * str;
{
char * pt, *pt1;
int i,goahead;
char * stra = NULL;
pt = str;
if (!str)
return NULL;
while((*pt != '\0') && (*pt != '['))
{
pt++;
}
if (*pt != '[')
Message("Annotation failed",0);
/* count the length */
pt1 = pt;
i = 0;
goahead = TRUE;
while(goahead)
{
goahead = FALSE;
while((*pt1 != '\0') && (*pt1 != '\n'))
{
pt1++;
i++;
}
if (*pt1 != '\0')
{
if (Is_Annotation_Cont(pt1+1))
{
goahead = TRUE;
pt1++;
i++;
}
}
}
if (i > 1024)
{
stra = (char *) xmalloc(i+2);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,stra, 0);
#endif
memset(stra, 0, i+2);
}
else
{
stra = (char *) xmalloc(1024);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,stra, 0);
#endif
memset(stra, 0,1024);
}
strncpy(stra,pt,i);
stra = Remove_Carriage_Return(stra);
stra = Remove_Ann_Cont(stra);
return stra;
}
/* basically got to the carriage return */
char *
Get_to_Next_Annotation_String(str)
char *str;
{
char * pt;
pt = str;
if (!Check_Lang_Fortran(cur_proj))
return NULL;
pt++; /* avoid pb of looping */
while((*pt != '\0'))
{
if (*pt == 'C')
{
if (strncmp(pt,ForCOMMENTSTART, strlen(ForCOMMENTSTART)) == 0)
break;
}
pt++;
}
if (*pt == '\n')
pt++;
if (*pt == '\0')
return NULL;
return pt;
}
/* basically go thrue the program and parse annotation, and set
if they are defined */
2024-10-04 15:26:19 +03:00
int initAnnotation()
2023-09-14 19:43:13 +03:00
{
PTR_CMNT cmnt;
PTR_BFND ptbif;
int count =0;
int i;
char *str;
global_int_annotation = GetAtomicType(T_INT);
memset((char *) Annotation_PT, 0, sizeof(char) *MAX_ANNOTATION);
memset((char *) Annotation_BIFND, 0, sizeof(PTR_BFND) *MAX_ANNOTATION);
memset((char *) Annotation_LLND, 0, sizeof(PTR_LLND) *MAX_ANNOTATION);
memset((char *) Annotation_CMNT, 0, sizeof(PTR_CMNT) *MAX_ANNOTATION);
memset((char *) Annotation_Def, 0, sizeof(int) *MAX_ANNOTATION);
ptbif = PROJ_FIRST_BIF();
count =0;
while (ptbif)
{
if (BIF_CMNT(ptbif))
{
cmnt = BIF_CMNT(ptbif);
str = CMNT_STRING(cmnt);
while (str)
{
if (Is_Annotation(str))
{
Annotation_PT[count] = Get_Annotation_String(str);
Annotation_CMNT[count] = cmnt;
Annotation_BIFND[count] = ptbif;
count++;
if (MAX_ANNOTATION <= count)
{
Message("Too many annotations",0);
exit(1);
}
}
str = Get_to_Next_Annotation_String(str);
}
}
ptbif = BIF_NEXT(ptbif);
}
Nb_Annotation = count;
for (i=0; i < Nb_Annotation; i++)
{
if (TRACEANN) printf("See annotation %s\n",Annotation_PT[i]);
}
/* unparse the annotation */
if (TRACEANN) printf("---------------------------------------------\n\n\n");
for (i=0; i < Nb_Annotation; i++)
{
sprintf(AnnExTensionNumber,ASYMBOLEXT,i);
Annotation_LLND[i] = Parse_Annotation(Annotation_PT[i],
Annotation_BIFND[i]);
if (!Annotation_LLND[i])
Message("Annotation Parse Error",BIF_LINE(Annotation_BIFND[i]));
if (TRACEANN) printf("Unparse :: %s\n",Unparse_Annotation(Annotation_LLND[i]));
}
if (TRACEANN) printf("---------------------------------------------\n\n\n");
/* setup which annotation is defined */
Set_The_Define_Field();
/* propagate the defined value */
Propagate_defined_value();
if (TRACEANN)
{
PTR_BFND first,last;
printf("---------------------------------------------\n\n\n");
for (i=0; i < Nb_Annotation; i++)
{
Get_Scope_Of_Annotation(i,&first,&last);
if (first)
printf("A(%d) Scope first (line %d) :: %s", i,BIF_LINE(first), funparse_bfnd(first));
if (last)
printf("A(%d) Scope last (line %d) :: %s", i, BIF_LINE(last), funparse_bfnd(last));
}
}
/* unparse the annotation */
if (TRACEANN)
{
printf("---------------------------------------------\n\n\n");
for (i=0; i < Nb_Annotation; i++)
{
printf("Unparse :: %s\n",Unparse_Annotation(Annotation_LLND[i]));
}
}
return 1;
}
PTR_LLND
Parse_Annotation(string,scope)
char * string;
PTR_BFND scope;
{
PTTOSTRINGTOPARSE = 0;
STRINGTOPARSE = string;
ANNOTATIONSCOPE = scope;
ANNOTATE_NODE = NULL;
LENSTRINGTOPARSE = strlen(string) +1;
yyparse_annotate();
return ANNOTATE_NODE;
}
PTR_LLND
Get_Define_Field(ann)
PTR_LLND ann;
{
PTR_LLND pt;
int i;
if (!ann)
return(NULL);
pt = ann;
for(i =0 ; i < 0; i++)
pt = NODE_OPERAND1(pt);
return(NODE_OPERAND0(pt));
}
char *
Get_Define_Label_Field(ann)
PTR_LLND ann;
{
PTR_LLND pt;
pt = ann;
if(!pt)
return NULL;
if (!NODE_OPERAND0(pt))
return NULL;
/* it a function call name with one parameter */
pt = NODE_OPERAND0 (NODE_OPERAND0(pt));
/* pt is Expr_list */
if (pt && NODE_OPERAND0(pt))
return(NODE_STRING_POINTER(NODE_OPERAND0(pt)));
else
return NULL;
}
char *
Get_Label_Field(ann)
PTR_LLND ann;
{
PTR_LLND pt;
int i;
if(!ann)
return NULL;
pt = ann;
for(i =0 ; i < 1; i++)
pt = NODE_OPERAND1(pt);
if (!NODE_OPERAND0(pt))
return NULL;
/* it a function call name with one parameter */
pt = NODE_OPERAND0 (NODE_OPERAND0(pt));
/* pt is Expr_list */
if (pt && NODE_OPERAND0(pt))
return(NODE_STRING_POINTER(NODE_OPERAND0(pt)));
else
return NULL;
}
PTR_LLND
Get_ApplyTo_Field(ann)
PTR_LLND ann;
{
PTR_LLND pt;
int i;
if(!ann)
return NULL;
pt = ann;
for(i =0 ; i < 2; i++)
pt = NODE_OPERAND1(pt);
if(!pt)
return NULL;
if (!NODE_OPERAND0(pt))
return NULL;
/* it a function call name with one parameter */
pt = NODE_OPERAND0 (NODE_OPERAND0(pt));
/* pt is Expr_list */
if (pt && NODE_OPERAND0(pt))
return(NODE_OPERAND0(pt));
else
return NULL;
}
PTR_LLND
Get_ApplyToIf_Field(ann)
PTR_LLND ann;
{
PTR_LLND pt;
int i;
pt = ann;
for(i =0 ; i < 2; i++)
pt = NODE_OPERAND1(pt);
if(!pt)
return NULL;
if (!NODE_OPERAND0(pt))
return NULL;
/* it a function call name with two parameters, we want the second one */
pt = NODE_OPERAND0 (NODE_OPERAND0(pt));
/* pt is Expr_list */
if (pt && NODE_OPERAND1(pt))
return(NODE_OPERAND0(NODE_OPERAND1(pt)));
else
return NULL;
}
PTR_LLND
Get_LocalVar_Field(ann)
PTR_LLND ann;
{
PTR_LLND pt;
int i;
if(!ann)
return NULL;
pt = ann;
for(i =0 ; i < 3; i++)
pt = NODE_OPERAND1(pt);
return(NODE_OPERAND0(pt));
}
PTR_LLND
Get_Annotation_Field(ann)
PTR_LLND ann;
{
PTR_LLND pt;
int i;
if(!ann)
return NULL;
pt = ann;
for(i =0 ; i < 4; i++)
pt = NODE_OPERAND1(pt);
return(NODE_OPERAND0(pt));
}
char *
Get_Annotation_Field_Label(ann)
PTR_LLND ann;
{
PTR_LLND pt;
if (!ann)
return NULL;
pt = Get_Annotation_Field(ann);
if (!pt)
return NULL;
if (NODE_CODE(pt) != FUNC_CALL)
{
Message("Pb in annotation field",0);
return NULL;
}
return Get_Function_Name_For_Call(pt);
}
char *
Unparse_Annotation(ann)
PTR_LLND ann;
{
char *str;
char temp[256];
if(!ann)
return NULL;
str = (char *) xmalloc(1024);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,str, 0);
#endif
sprintf(str,"[");
if (Get_Define_Label_Field(ann))
{
sprintf(temp,"IfDef(\"%s\");",Get_Define_Label_Field(ann));
strcat(str,temp);
}
if (Get_Label_Field(ann))
{
sprintf(temp,"Label(\"%s\");",Get_Label_Field(ann));
strcat(str,temp);
}
if (Get_ApplyTo_Field(ann))
{ /* need more than that */
sprintf(temp,"ApplyTo( %s) ",Remove_Carriage_Return(cunparse_llnd(Get_ApplyTo_Field(ann))));
strcat(str,temp);
if (Get_ApplyToIf_Field(ann))
{
sprintf(temp,"If ( %s) ;",Remove_Carriage_Return(cunparse_llnd(Get_ApplyToIf_Field(ann))));
strcat(str,temp);
} else
strcat(str,";");
}
if (Get_LocalVar_Field(ann))
{
sprintf(temp,"%s; ",Remove_Carriage_Return(cunparse_llnd(Get_LocalVar_Field(ann))));
strcat(str,temp);
}
if (Get_Annotation_Field(ann))
{
sprintf(temp,"%s",Remove_Carriage_Return(cunparse_llnd(Get_Annotation_Field(ann))));
strcat(str,temp);
}
strcat(str,"]");
return(str);
}
char *
Does_Annotation_Defines(ann, value)
int *value;
PTR_LLND ann;
{
PTR_LLND pt,pt1;
char *name;
int *res1;
if (! (pt = Get_Annotation_Field(ann)))
return NULL;
name = Get_Function_Name_For_Call(pt);
if(strcmp(name,"Define") == 0)
if ((pt1 = Get_First_Parameter_For_Call(pt)))
{
res1 = evaluateExpression(Get_Second_Parameter_For_Call(pt));
if (res1[0] != -1)
*value = res1[1];
return NODE_STRING_POINTER(pt1);
}
return NULL;
}
/* set all the annotation that are defined */
int Set_The_Define_Field()
{
int i,j;
char *str, *tsrt;
int value;
int found;
/* set up those field
Annotation_Def[]
char *Defined_Value_Str[MAX_ANNOTATION];
int Defined_Value_Value[MAX_ANNOTATION];
*/
for (i = 0; i < Nb_Annotation; i++)
{
if (Get_Define_Field(Annotation_LLND[i]) == NULL)
{
/* independant defined */
if (TRACEANN)
printf("Annotation Defined : %s\n", tsrt = Unparse_Annotation(Annotation_LLND[i]));
#ifdef __SPF
removeFromCollection(tsrt);
#endif
free(tsrt);
Annotation_Def[i] = TRUE;
/* check if it defined something */
Defined_Value_Str[i] =
Does_Annotation_Defines(Annotation_LLND[i]
, &value);
Defined_Value_Value[i] = value;
}
}
/* end of initial setup */
/* propagate forward only */
for (i=0; i< Nb_Annotation ; i++)
{
str = Get_Define_Label_Field(Annotation_LLND[i]);
if (str)
{ /* look if the word is defined */
found = FALSE;
for (j = i-1; j>= 0 ; j--)
{
if (Defined_Value_Str[j])
{
if (strcmp(str,Defined_Value_Str[j]) == 0)
{
found = TRUE;
break;
}
}
}
if (found)
{
Annotation_Def[i] = TRUE;
if (TRACEANN) printf("Annotation Defined : %s\n",Unparse_Annotation(Annotation_LLND[i]));
/* check if it defined something */
Defined_Value_Str[i] =
Does_Annotation_Defines(Annotation_LLND[i]
, &value);
Defined_Value_Value[i] = value;
}
}
}
return 0;
}
/* return the annotation with label -1 for not found */
int
Get_Annotation_With_Label(str)
char *str;
{ int i;
char *strc;
for (i=0; i < Nb_Annotation; i++)
{
strc = Get_Label_Field(Annotation_LLND[i]);
if (strc)
{
if (strcmp(strc, str) == 0)
{
return i;
}
}
}
return -1;
}
/* Compute the first and last bif node a annotation applies */
int Get_Scope_Of_Annotation(nb,first,last)
int nb;
PTR_BFND *first, *last;
{
PTR_LLND ann,f1,f2;
PTR_LLND field_apply;
char *str;
int nb2;
ann = Annotation_LLND[nb];
if (!ann)
{
*first = NULL;
*last = NULL;
return FALSE;
}
if (!Annotation_Def[nb])
{
*first = NULL;
*last = NULL;
return TRUE;
}
/* the first case is easy */
field_apply = Get_ApplyTo_Field(ann);
if (!field_apply)
{
*first = Annotation_BIFND[nb];
*last = Annotation_BIFND[nb];
return TRUE;
}
/* depend on */
f1 = field_apply;
if (!f1)
{
*first = Annotation_BIFND[nb];
*last = Annotation_BIFND[nb];
return FALSE;
}
switch(NODE_CODE(f1))
{
case VAR_REF:
Message("Function Call in Get_Scope_Of_Annotation not yet implemented, sorry",0);
break;
case STRING_VAL :
str = NODE_STRING_POINTER(f1);
if (strcmp(str,"NextStmt") == 0)
{
*first = Annotation_BIFND[nb];
*last = Annotation_BIFND[nb];
return TRUE;
}
if (strcmp(str,"NextAnnotation") == 0)
{
*first = Annotation_BIFND[nb];
*last = Annotation_BIFND[nb+1];
if (*last == NULL)
*last = Get_Last_Node_Of_Project();
return TRUE;
}
if (strcmp(str,"EveryWhere") == 0)
{
*first = PROJ_FIRST_BIF();
*last = Get_Last_Node_Of_Project();
return TRUE;
}
if (strcmp(str,"Follow") == 0)
{
*first = Annotation_BIFND[nb];
*last = Get_Last_Node_Of_Project();
return TRUE;
}
if (strcmp(str,"CurrentScope") == 0)
{
*first = BIF_CP(Annotation_BIFND[nb]);
if (*first)
*last = getLastNodeOfStmt(*first);
else
*last = NULL;
return TRUE;
}
Message("Pb in Get_Scope_Of_Annotation",0);
break;
case EXPR_LIST :
*first = Annotation_BIFND[nb];
if (NODE_OPERAND0(f1))
{
f2 = NODE_OPERAND0(f1);
if (f2 && (NODE_CODE(f2) == STRING_VAL))
{
str = NODE_STRING_POINTER(f2);
nb2 = Get_Annotation_With_Label(str);
if (nb2!= -1)
{
*first = Annotation_BIFND[nb2];
} else
Message("Pb in Get_Scope_Of_Annotation",0);
} else
Message("Pb in Get_Scope_Of_Annotation",0);
}
f2 = NODE_OPERAND0(NODE_OPERAND1(f1));
if (f2 && (NODE_CODE(f2) == STRING_VAL))
{
str = NODE_STRING_POINTER(f2);
nb2 = Get_Annotation_With_Label(str);
if (nb2!= -1)
{
*last = getNodeBefore(Annotation_BIFND[nb2]);
} else
Message("Pb in Get_Scope_Of_Annotation",0);
} else
Message("Pb in Get_Scope_Of_Annotation",0);
break;
default:
{
Message("Pb in Get_Scope_Of_Annotation",0);
return FALSE;
}
}
return TRUE;
}
/* for all defined value, propagate forward */
void Propagate_defined_value()
{
int i;
int j;
PTR_LLND val;
char *str;
for (i=0 ; i< Nb_Annotation ; i++)
{
if (Defined_Value_Str[i])
{
val = makeInt(Defined_Value_Value[i]);
str = Defined_Value_Str[i];
for (j = i+1 ; j< Nb_Annotation ; j++)
{
if (Annotation_LLND[j])
if (Get_Annotation_Field_Label(Annotation_LLND[j]))
{
if (strcmp(Get_Annotation_Field_Label(Annotation_LLND[j]),
"Define") != 0)
Replace_String_In_Expression(NODE_OPERAND1(NODE_OPERAND1(Annotation_LLND[j])), str, val);
} else
Replace_String_In_Expression(NODE_OPERAND1(NODE_OPERAND1(Annotation_LLND[j])), str, val);
}
}
}
}
/* return NULL if not annotation of kind apply, otherwise return the
llnd expression corresponding to the annotation
Very dumb version, but simple one (warning, because of label an annotation
does not apply where it is necessarely, except for defined annotation )*/
PTR_LLND
Does_Annotation_Apply(kind,bif)
char *kind;
PTR_BFND bif;
{
int i;
PTR_BFND first,last;
for (i=0 ; i< Nb_Annotation ; i++)
{
if (Annotation_Def[i])
{
if (kind)
{
if (strcmp(Get_Annotation_Field_Label(Annotation_LLND[i]), kind) == 0)
{
if (Get_Scope_Of_Annotation(i,&first,&last))
{
if (isItInSection(first, last, bif))
return Get_Annotation_Field(Annotation_LLND[i]);
}
}
}else
{
if (Get_Scope_Of_Annotation(i,&first,&last))
{
if (isItInSection(first, last, bif))
return Get_Annotation_Field(Annotation_LLND[i]);
}
}
}
}
return NULL;
}
PTR_LLND
Get_Annotation_Field_List_For_Stmt(bif)
PTR_BFND bif;
{
int i;
PTR_BFND first,last;
PTR_LLND list = NULL, pt =NULL;
for (i=0 ; i< Nb_Annotation ; i++)
{
if (Annotation_Def[i])
{
if (Get_Scope_Of_Annotation(i,&first,&last))
{
if (isItInSection(first, last, bif))
{
if (!list)
{
list = newExpr(EXPR_LIST,NULL,
Get_Annotation_Field(Annotation_LLND[i]),
NULL);
pt = list;
}else
{
NODE_OPERAND1(pt) = newExpr(EXPR_LIST,NULL,
Get_Annotation_Field(Annotation_LLND[i]),
NULL);
pt = NODE_OPERAND1(pt);
}
}
}
}
}
return list;
}
PTR_LLND
Get_Annotation_List_For_Stmt(bif)
PTR_BFND bif;
{
int i;
PTR_BFND first,last;
PTR_LLND list = NULL, pt =NULL;
for (i=0 ; i< Nb_Annotation ; i++)
{
if (Annotation_Def[i])
{
if (Get_Scope_Of_Annotation(i,&first,&last))
{
if (isItInSection(first, last, bif))
{
if (!list)
{
list = newExpr(EXPR_LIST,NULL,
Annotation_LLND[i],
NULL);
pt = list;
}else
{
NODE_OPERAND1(pt) = newExpr(EXPR_LIST,NULL,
Annotation_LLND[i],
NULL);
pt = NODE_OPERAND1(pt);
}
}
}
}
}
return list;
}
/* Access functions */
int
Get_Number_of_Annotation()
{
return Nb_Annotation;
}
PTR_BFND
Get_Annotation_Bif(id)
int id;
{
return Annotation_BIFND[id];
}
PTR_LLND
Get_Annotation_Expr(id)
int id;
{
return Annotation_LLND[id];
}
char *
Get_String_of_Annotation(id)
int id;
{
return Annotation_PT[id];
}
PTR_CMNT
Get_Annotation_Comment(id)
int id;
{
return Annotation_CMNT[id];
}
int
Is_Annotation_Defined(id)
int id;
{
return Annotation_Def[id];
}
char *
Annotation_Defines_string(id)
int id;
{
return Defined_Value_Str[id];
}
int
Annotation_Defines_string_Value(id)
int id;
{
return Defined_Value_Value[id];
}