📄 multifun.c
字号:
} theList = (struct multifield *) DOToPointer(theValue); /*=========================*/ /* Return the new segment. */ /*=========================*/ SetpType(returnValue,MULTIFIELD); SetpValue(returnValue,theList); if (GetDOBegin(theValue) > GetDOEnd(theValue)) { SetpDOBegin(returnValue,GetDOBegin(theValue)); } else { SetpDOBegin(returnValue,GetDOBegin(theValue) + 1); } SetpDOEnd(returnValue,GetDOEnd(theValue)); }/*************************************//* NthFunction: H/L access routine *//* for the nth$ function. *//*************************************/globle void NthFunction( void *theEnv, DATA_OBJECT_PTR nth_value) { DATA_OBJECT value1, value2; struct multifield *elm_ptr; long long n; /* 6.04 Bug Fix */ if (EnvArgCountCheck(theEnv,"nth$",EXACTLY,2) == -1) { SetpType(nth_value,SYMBOL); SetpValue(nth_value,(void *) EnvAddSymbol(theEnv,"nil")); return; } if ((EnvArgTypeCheck(theEnv,"nth$",1,INTEGER,&value1) == FALSE) || (EnvArgTypeCheck(theEnv,"nth$",2,MULTIFIELD,&value2) == FALSE)) { SetpType(nth_value,SYMBOL); SetpValue(nth_value,(void *) EnvAddSymbol(theEnv,"nil")); return; } n = DOToLong(value1); /* 6.04 Bug Fix */ if ((n > GetDOLength(value2)) || (n < 1)) { SetpType(nth_value,SYMBOL); SetpValue(nth_value,(void *) EnvAddSymbol(theEnv,"nil")); return; } elm_ptr = (struct multifield *) GetValue(value2); SetpType(nth_value,GetMFType(elm_ptr,n + GetDOBegin(value2) - 1)); SetpValue(nth_value,GetMFValue(elm_ptr,n + GetDOBegin(value2) - 1)); }/* ------------------------------------------------------------------ * SubsetFunction: * This function compares two multi-field variables * to see if the first is a subset of the second. It * does not consider order. * * INPUTS: Two arguments via argument stack. First is the sublist * multi-field variable, the second is the list to be * compared to. Both should be of type MULTIFIELD. * * OUTPUTS: TRUE if the first list is a subset of the * second, else FALSE * * NOTES: This function is called from H/L with the subset * command. Repeated values in the sublist must also * be repeated in the main list. * ------------------------------------------------------------------ */globle intBool SubsetpFunction( void *theEnv) { DATA_OBJECT item1, item2, tmpItem; long i,j,k; if (EnvArgCountCheck(theEnv,"subsetp",EXACTLY,2) == -1) return(FALSE); if (EnvArgTypeCheck(theEnv,"subsetp",1,MULTIFIELD,&item1) == FALSE) return(FALSE); if (EnvArgTypeCheck(theEnv,"subsetp",2,MULTIFIELD,&item2) == FALSE) return(FALSE); if (GetDOLength(item1) == 0) return(TRUE); if (GetDOLength(item2) == 0) return(FALSE); for (i = GetDOBegin(item1) ; i <= GetDOEnd(item1) ; i++) { SetType(tmpItem,GetMFType((struct multifield *) GetValue(item1),i)); SetValue(tmpItem,GetMFValue((struct multifield *) GetValue(item1),i)); if (! FindDOsInSegment(&tmpItem,1,&item2,&j,&k,NULL,0)) { return(FALSE); } } return(TRUE); }/****************************************//* MemberFunction: H/L access routine *//* for the member$ function. *//****************************************/globle void MemberFunction( void *theEnv, DATA_OBJECT_PTR result) { DATA_OBJECT item1, item2; long j, k; result->type = SYMBOL; result->value = EnvFalseSymbol(theEnv); if (EnvArgCountCheck(theEnv,"member$",EXACTLY,2) == -1) return; EnvRtnUnknown(theEnv,1,&item1); if (EnvArgTypeCheck(theEnv,"member$",2,MULTIFIELD,&item2) == FALSE) return; if (FindDOsInSegment(&item1,1,&item2,&j,&k,NULL,0)) { if (j == k) { result->type = INTEGER; result->value = (void *) EnvAddLong(theEnv,j); } else { result->type = MULTIFIELD; result->value = EnvCreateMultifield(theEnv,2); SetMFType(result->value,1,INTEGER); SetMFValue(result->value,1,EnvAddLong(theEnv,j)); SetMFType(result->value,2,INTEGER); SetMFValue(result->value,2,EnvAddLong(theEnv,k)); SetpDOBegin(result,1); SetpDOEnd(result,2); } } }/***************************************//* FindDOsInSegment: *//***************************************//* 6.05 Bug Fix */intBool FindDOsInSegment( DATA_OBJECT_PTR searchDOs, int scnt, DATA_OBJECT_PTR value, long *si, long *ei, long *excludes, int epaircnt) { long mul_length,slen,i,k; /* 6.04 Bug Fix */ int j; mul_length = GetpDOLength(value); for (i = 0 ; i < mul_length ; i++) { for (j = 0 ; j < scnt ; j++) { if (GetType(searchDOs[j]) == MULTIFIELD) { slen = GetDOLength(searchDOs[j]); if (MVRangeCheck(i+1L,i+slen,excludes,epaircnt)) { for (k = 0L ; (k < slen) && ((k + i) < mul_length) ; k++) if ((GetMFType(GetValue(searchDOs[j]),k+GetDOBegin(searchDOs[j])) != GetMFType(GetpValue(value),k+i+GetpDOBegin(value))) || (GetMFValue(GetValue(searchDOs[j]),k+GetDOBegin(searchDOs[j])) != GetMFValue(GetpValue(value),k+i+GetpDOBegin(value)))) break; if (k >= slen) { *si = i + 1L; *ei = i + slen; return(TRUE); } } } else if ((GetValue(searchDOs[j]) == GetMFValue(GetpValue(value),i + GetpDOBegin(value))) && (GetType(searchDOs[j]) == GetMFType(GetpValue(value),i + GetpDOBegin(value))) && MVRangeCheck(i+1L,i+1L,excludes,epaircnt)) { *si = *ei = i+1L; return(TRUE); } } } return(FALSE); }/******************************************************//* MVRangeCheck: *//******************************************************/static intBool MVRangeCheck( long si, long ei, long *elist, int epaircnt){ int i; if (!elist || !epaircnt) return(TRUE); for (i = 0 ; i < epaircnt ; i++) if (((si >= elist[i*2]) && (si <= elist[i*2+1])) || ((ei >= elist[i*2]) && (ei <= elist[i*2+1]))) return(FALSE); return(TRUE);}#if (! BLOAD_ONLY) && (! RUN_TIME)/******************************************************//* MultifieldPrognParser: Parses the progn$ function. *//******************************************************/static struct expr *MultifieldPrognParser( void *theEnv, struct expr *top, char *infile) { struct BindInfo *oldBindList,*newBindList,*prev; struct token tkn; struct expr *tmp; SYMBOL_HN *fieldVar = NULL; SavePPBuffer(theEnv," "); GetToken(theEnv,infile,&tkn); /* ================================ Simple form: progn$ <mf-exp> ... ================================ */ if (tkn.type != LPAREN) { top->argList = ParseAtomOrExpression(theEnv,infile,&tkn); if (top->argList == NULL) { ReturnExpression(theEnv,top); return(NULL); } } else { GetToken(theEnv,infile,&tkn); if (tkn.type != SF_VARIABLE) { if (tkn.type != SYMBOL) goto MvPrognParseError; top->argList = Function2Parse(theEnv,infile,ValueToString(tkn.value)); if (top->argList == NULL) { ReturnExpression(theEnv,top); return(NULL); } } /* ========================================= Complex form: progn$ (<var> <mf-exp>) ... ========================================= */ else { fieldVar = (SYMBOL_HN *) tkn.value; SavePPBuffer(theEnv," "); top->argList = ParseAtomOrExpression(theEnv,infile,NULL); if (top->argList == NULL) { ReturnExpression(theEnv,top); return(NULL); } GetToken(theEnv,infile,&tkn); if (tkn.type != RPAREN) goto MvPrognParseError; PPBackup(theEnv); /* PPBackup(theEnv); */ SavePPBuffer(theEnv,tkn.printForm); SavePPBuffer(theEnv," "); } } if (CheckArgumentAgainstRestriction(theEnv,top->argList,(int) 'm')) goto MvPrognParseError; oldBindList = GetParsedBindNames(theEnv); SetParsedBindNames(theEnv,NULL); IncrementIndentDepth(theEnv,3); ExpressionData(theEnv)->BreakContext = TRUE; ExpressionData(theEnv)->ReturnContext = ExpressionData(theEnv)->svContexts->rtn; PPCRAndIndent(theEnv); top->argList->nextArg = GroupActions(theEnv,infile,&tkn,TRUE,NULL,FALSE); DecrementIndentDepth(theEnv,3); PPBackup(theEnv); PPBackup(theEnv); SavePPBuffer(theEnv,tkn.printForm); if (top->argList->nextArg == NULL) { ClearParsedBindNames(theEnv); SetParsedBindNames(theEnv,oldBindList); ReturnExpression(theEnv,top); return(NULL); } tmp = top->argList->nextArg; top->argList->nextArg = tmp->argList; tmp->argList = NULL; ReturnExpression(theEnv,tmp); newBindList = GetParsedBindNames(theEnv); prev = NULL; while (newBindList != NULL) { if ((fieldVar == NULL) ? FALSE : (strcmp(ValueToString(newBindList->name),ValueToString(fieldVar)) == 0)) { ClearParsedBindNames(theEnv); SetParsedBindNames(theEnv,oldBindList); PrintErrorID(theEnv,"MULTIFUN",2,FALSE); EnvPrintRouter(theEnv,WERROR,"Cannot rebind field variable in function progn$.\n"); ReturnExpression(theEnv,top); return(NULL); } prev = newBindList; newBindList = newBindList->next; } if (prev == NULL) SetParsedBindNames(theEnv,oldBindList); else prev->next = oldBindList; if (fieldVar != NULL) ReplaceMvPrognFieldVars(theEnv,fieldVar,top->argList->nextArg,0); return(top);MvPrognParseError: SyntaxErrorMessage(theEnv,"progn$"); ReturnExpression(theEnv,top); return(NULL); }/**********************************************//* ReplaceMvPrognFieldVars: Replaces variable *//* references found in the progn$ function. *//**********************************************/static void ReplaceMvPrognFieldVars( void *theEnv, SYMBOL_HN *fieldVar, struct expr *theExp, int depth) { size_t flen; flen = strlen(ValueToString(fieldVar)); while (theExp != NULL) { if ((theExp->type != SF_VARIABLE) ? FALSE : (strncmp(ValueToString(theExp->value),ValueToString(fieldVar), (STD_SIZE) flen) == 0)) { if (ValueToString(theExp->value)[flen] == '\0') { theExp->type = FCALL; theExp->value = (void *) FindFunction(theEnv,"(get-progn$-field)"); theExp->argList = GenConstant(theEnv,INTEGER,EnvAddLong(theEnv,(long long) depth)); } else if (strcmp(ValueToString(theExp->value) + flen,"-index") == 0) { theExp->type = FCALL; theExp->value = (void *) FindFunction(theEnv,"(get-progn$-index)"); theExp->argList = GenConstant(theEnv,INTEGER,EnvAddLong(theEnv,(long long) depth)); } } else if (theExp->argList != NULL) { if ((theExp->type == FCALL) && (theExp->value == (void *) FindFunction(theEnv,"progn$"))) ReplaceMvPrognFieldVars(theEnv,fieldVar,theExp->argList,depth+1); else ReplaceMvPrognFieldVars(theEnv,fieldVar,theExp->argList,depth); } theExp = theExp->nextArg; } }#endif/*****************************************//* MultifieldPrognFunction: H/L access */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -