/* User defined Functions (i.e. Dynamical systems description) management */ #include "common.h" #include "large.h" #include "datalib.h" #include "archive.h" #include "function.h" #include "file.h" #include "help.h" #include "visual.h" #include "diagram.h" #include "curve.h" #include "param.h" #include "userfunc.h" extern Global(CharPtr PNTR) FunctionTxt; /* defined in text.c */ enum { /* see setup.c, init[], /function */ EDITWINDOW, /* 38 20 ! textwidth textheight */ SELSYST_C, CONTEXT_C, /* Compiling, please wait... */ EDIT_C, /* Editing... */ EXPORT_C, /* Export parameters */ IMPORT_C, /* Import parameters */ EXPORTING_C, /* Exporting */ IMPORTING_C, /* Importing */ ERROR_T, DERI_T, DERIN_T, DERIS_T, DERIU_T, DERI1_T, DERI2_T, DERI3_T, DERI4_T, DERI5_T, FUNC_M, FUNCH_I, FUNCV_I, SEL_T, NAME1, /* First character of a name is not a letter */ NAMEDIM, /* Dimension must be a constant>1 enclosed in brackets, e.g. x[10] */ PHASE, /* Specify at least one phase variable */ COMPNUM, /* number of vars must be ... */ EXPORT_T, /* Export to file */ IMPORT_T, /* Import from file */ EXPORTOF_B, /* Export out file */ IMPORTOF_B, /* Import in file */ EXPORTD_T, /* Export diagrams */ EXPORTDN_B, /* don't export */ EXPORTDI_B, /* initial points */ EXPORTDF_B /* everything */ } FunctionTxtIndex; /*------------------------------------------------------------*/ /* Lines which begin different parts of dyn sys specification */ enum {I_INCLUDE,I_FUNCTIONS,I_DEFINES,I_RHS,I_AUX}; Local(Int2Ptr) StartLine; /* 1(include), 1(funcs), VCsep(defs), 1(rhs+undefs), AuxNum 1 */ Local(BoolPtr) KindLine; /* 1(I_INCLUDE), 1(I_FUNCTIONS), VCsep(I_DEFINES), 1(I_RHS), AuxNum (I_AUX) */ /*--------------------------------*/ /* Aux functions data (see below) */ Local(Int2) AuxNum=0; /* number of Aux functions in system's specification */ typedef struct { CharPtr MenuName; CharPtr Prompt; CharPtr FuncName; CharPtr Header; CharPtr Tail; CharPtr Defs; CharPtr Undefs; CharPtr DepVars; CharPtr IndepVars; Int2 index; /* to fitem array */ Int2 parent; /* for ..._Deri, i=1,2,3,4,5 */ Int2 flags; #define COMPULSORY 1 /* function must be specified */ } AuxFuncDesc, PNTR AuxFuncDescPtr; Local(AuxFuncDescPtr) AuxFuncDescs=NULL; /*-------------------------------------------------------*/ /* Select functions to be current. Called from Main Menu */ Global(DataLib) ArchivesLib; Global(int) MaxDerOrder; /* Edit routine (DataLibShow) */ Local(DataLibNotify) EditCreatePost; /* pointer to DataLibShow Post routine */ Local(DataLibPtr) EditDataLib; /* DataLib being edited */ Local(WindoW) wEdit; Local(TexT) tEdit; /* rhs control provided by CreateEditor */ Local(Boolean) DeclHasBeenChanged=FALSE; typedef struct { time_t last; /* of declarations or RHS */ time_t lastDecl; /* of declarations */ } LastUpdateDate; Local(LastUpdateDate) upDate; Local(Boolean) RecompileRequest=FALSE; /* Data and functions related to check whether the user tries to change the description of current dynamical system while it has a diagram with stored curve. If he change a number of phase/par/time vars these curves must be removed */ Local(Int1) CurveExists; /* phase/par/time DialogText */ Local(CharPtr PNTR) Input; /* 0..VCsep-1,PART_FUNC,0..AuxNum-1 */ Local(TexT) PNTR Text; /* 0..VCsep,funcs */ /* Processes next curve */ Local(Int2) ProcessCurve(DataLibPtr dlDiag) { if (CurveExists) { /* delete next curve */ DeleteCurve(dlDiag); return 0; } else { /* mark that there is a curve */ CurveExists=1; return -1; } } /* Processes next diagram */ Local(Int2) ProcessDiagram(DataLibPtr dl) { DataLibVar(Diagram); CharPtr pName; Int2 rc=0; Boolean s_r=!CurveExists; GetParam(SFS_CURRENTS,"DIRECTORY"); pName=DataLibReadVRecord(dl,NULL); StrCat(ParBuf,pName); _MemFree(pName); if (!DataLibOpen(&Diagram,ParBuf)) { if (s_r) DataLibSavePos(&Diagram); while (!DataLibUp(&Diagram)); rc=DataLibEnum(&Diagram,ProcessCurve,TRUE); DeleteFilters(&Diagram); if (s_r) DataLibRestorePos(&Diagram); DataLibClose(&Diagram); } return rc; } /* if CurveExists==0: Set it to 1 if there is a diagram with a curve if CurveExists==1: Delete all curves from all diagrams */ Local(void) EnumCurves(DataLibPtr dl) { CharPtr libn; Boolean s_r=!CurveExists; Boolean cur=!DataLibIsClosed(&DiagramLib); if (cur) { libn=_StringSave(DiagramLib.FileName); DataLibClose(&DiagramLib); /* otherwise Enum will open another copy */ } if (s_r) DataLibSavePos(dl); DataLibEnum(dl,ProcessDiagram,TRUE); if (s_r) DataLibRestorePos(dl); if (cur) { DataLibOpen(&DiagramLib,libn); _MemFree(libn); } } /* Check whether there is a curve. Called when the user changes phase/par/time conrtol for the firts time */ Local(void) VarCheck(TexT t) { if (CurveExists==1) { GetParam(SFS_KERNELERRORS,"ED_VARS"); /* Delete all curves? */ if (myMessage(MSG_YN,ParBuf)==ANS_YES) { /* Temporary build class definitions for AllocateData */ DataLibUp(EditDataLib); VisFull=FALSE; ActivateVisualizer(EditDataLib); DataLibDown(EditDataLib); EnumCurves(EditDataLib); DataLibUp(EditDataLib); DeactivateVisualizer(EditDataLib); DataLibDown(EditDataLib); VisFull=TRUE; CurveExists=0; Select(t); } else { CurveExists=2; /* do not delete, but don't ask anymore */ } } } /* Called by the editor just prior replace operation */ Local(Boolean) VarChecker(TexT t, CharPtr find, CharPtr replace) { Int2 i; for (i=0; i<3; i++) if (t==Text[i] && CurveExists || t==tEdit) { if (StrPBrk(find," ,") || !replace[0] || StrPBrk(replace," ,_")) { myWarning("ED_VARREP"); return FALSE; /* don't replace */ } } return TRUE; /* go on and replace */ } Local(Boolean) NewSystem; /* TRUE - aCreate, FALSE - aEdit */ Local(Int2) CreateGroup(Int2 i, GrouP g, CharPtr partition, CharPtr prompt, TxtActnProc callback) { CharPtr vp; vp=DataLibReadVRecord(EditDataLib,partition); if (vp) { StaticPrompt(g,prompt,0,dialogTextHeight,NULL,'l'); Text[i]=DialogText(g,vp,1,callback); Input[i]=_StringSave(vp); SetTextSelect(Text[i],EditTextSelect,NULL); _MemFree(vp); return 0; } else return 1; } Local(void) DestroyGroup(Int2 i, CharPtr partition) { size_t len; len=StringLen(Input[i])+1; if (len>1) DataLibWriteVRecord(EditDataLib,partition,Input[i],len); Input[i]=_MemFree(Input[i]); } Local(void) CheckAndCorrect(TexT t, Boolean (*Check)(Char)) { CharPtr p; size_t len; int pos; len=TextLength(t)+1; p=_MemNew(len); if (!p) { myWarning("ED_MEM"); return; } GetTitle(t,p,len); for (pos=0; pos0) continue; o=DerOrd(i); if (o<0 && AuxFuncDescs[i].flags&COMPULSORY) { myWarning("FU_NO",AuxFuncDescs[i].Prompt); /* don't return here: let Content save what has already been specificed */ /***return 1;***/ /* editor will not be terminated */ } if (o<0 || o>=DERMAX) continue; if (Miscdata.Der[o]==DER_USER) { myWarning("AD_UD",AuxFuncDescs[i].Prompt); /* don't return here: let Content save what has already been specificed */ /***return 1;***/ /* editor will not be terminated */ } } DataLibDeletePartitions(EditDataLib, PART_FUNC,PART_RHS, PART_DATE,PART_MISC, NULL); for (i=0; iParentDirPtr,EditDataLib->CurDirPtr); } } } else RecompileRequest=FALSE; DataLibUp(EditDataLib); /* Remove Edit window and terminate Edit processing */ /* Remove before call callback because it may create another Editor window */ Remove(wEdit); Text=_MemFree(Text); for (i=0; i=0; ii--) { Miscdata.Der[ii]=DER_SYM; SetValue(DerGroup[ii],DER_SYM+1); } n=0; } else n=i; for (ii=i; ii>=n; ii--) { for (j=0; j2+AuxNum) Miscdata.ShowFunc=1; if (Miscdata.Suspend!=SUSPEND_NEVER && Miscdata.Suspend!=SUSPEND_SPECIAL && Miscdata.Suspend!=SUSPEND_EACH) Miscdata.Suspend=SUSPEND_SPECIAL; } else { for (i=0; iDirName,NULL); sscanf(FunctionTxt[EDITWINDOW],"%i %i",&width,&height); MainGroup=InitLargeWindow(wEdit); SetGroupSpacing(MainGroup,3,sysLineHeight2); Text=_MemNew(ARRAYSIZE(TexT,VCsep+1)); Input=_MemNew(ARRAYSIZE(CharPtr,VCsep+1+AuxNum)); /* If the Editor is called in response to unsuccessfull compilation - show a list of errors */ if (DynLibErrors) { CharPtr p; FILE PNTR err; Char b[150],line[150]; int num; err=FileOpen(GetParam(SFS_COMPILER,"LOGFILE"),"rt"); g=HiddenGroup(MainGroup,0,2,NULL); StaticPrompt(g,FunctionTxt[ERROR_T],0,0,NULL,'l'); lEdit=SingleList(g,width,5,ErrorListActn); ErrorLines=BSNew(0); /* Compiler's messages */ while (FileGets(b,sizeof(b),err)) if (IsErrorLine(b,&num,line)) { if ((p=StrChr(line,'\n'),p)) *p='\0'; ListItem(lEdit,line); BSWrite(ErrorLines,&num,sizeof(num)); } /* Linker's messages */ rewind(err); GetParamString(SFS_COMPILER,"LERRLINEI"); while (FileGets(b,sizeof(b),err)) if (sscanf(b,ParBuf,line)==1) { /* Error! */ if ((p=StrChr(line,'\n'),p)) *p='\0'; ListItem(lEdit,line); num=10000; BSWrite(ErrorLines,&num,sizeof(num)); } FileClose(err); } else lEdit=NULL; /* Go to subdirectory; aEditNotify will return to the level */ if (DataLibDown(dl)) goto error0; /* Last update date */ DataLibFind(dl,PART_DATE); DataLibRead(dl,(CharPtr)&upDate,sizeof(upDate)); /* Create Phase/Par/Time variables related controls */ g=HiddenGroup(MainGroup,2,0,NULL); for (NewSystem=TRUE, i=0; i>1; GetNextPosition(gr,&pt); pt.x+=off; SetNextPosition(gr,pt); for (j=0; j<3; j++) { b[i][j]=RadioButton(gr,""); if (j==1) { if (i>2 && !ed) Hide(b[i][1]); if (DisableAutodif) Disable(b[i][1]); } } DerGroup[i]=gr; SetValue(gr,Miscdata.Der[i]+1); Hide(gr); /* Show: see below */ } for (i=0; i<3; i++) { AlignObjects(ALIGN_LOWER,(HANDLE)p[i],(HANDLE)b[0][i], (HANDLE)b[1][i],(HANDLE)b[2][i], (HANDLE)b[3][i],(HANDLE)b[4][i], NULL); AlignObjects(ALIGN_UPPER,(HANDLE)p[i],(HANDLE)b[0][i], (HANDLE)b[1][i],(HANDLE)b[2][i], (HANDLE)b[3][i],(HANDLE)b[4][i], NULL); } GetNextPosition(MainGroup,&ept); vp=DataLibReadVRecord(EditDataLib,PART_RHS); if (!vp) goto error; PushContext(HLP_RHS,NULL,FunctionTxt[EDIT_C]); tEdit=CreateEditor(MainGroup,vp,width,height,aEditNotify,CheckInputFuncs); _MemFree(vp); EditorSetRepCheck(VarChecker); mstack[dstack=0]=PulldownMenu(wEdit,FunctionTxt[FUNC_M]); fitem[1]=CommandItem(mstack[dstack],FunctionTxt[FUNCH_I],FuncProc); SeparatorItem(mstack[dstack]); fitem[2]=CommandItem(mstack[dstack],FunctionTxt[FUNCV_I],FuncProc); fitemn=3; for (i=0; i=0 && Miscdata.Der[j]!=DER_USER) Disable(fitem[fitemn]); if (j>=0) Show(DerGroup[j]); fitemn++; } switch (cc) { case '}': dstack--; break; case '-': SeparatorItem(mstack[dstack]); break; } } PrevCh=1; /* New hide unneeded */ for (i=MaxDerOrder; i>1,SystemFont,FALSE,CheckInputFuncs); SetTextSelect(Text[VCsep],EditTextSelect,NULL); for (i=-1; i=0) { sprintf(ParBuf,"%s%s",PART_SYSFUNC,AuxFuncDescs[i].FuncName); vp=DataLibReadVRecord(EditDataLib,ParBuf); } else vp=DataLibReadVRecord(EditDataLib,PART_FUNC); if (!vp) goto error; if (i==Miscdata.ShowFunc-3) { SetTitle(Text[VCsep],vp); } Input[VCsep+1+i]=vp; Hide(Text[VCsep]); } #if _UNIX /* Without this FuncProc would not resize and AlignObjects does not align */ RealizeWindow(wEdit); #endif AlignObjects(ALIGN_RIGHT,(HANDLE)(Text[0]),(HANDLE)tEdit,(HANDLE)group, #if !_UNIX (HANDLE)lEdit, /* may be NULL, must preceed the last argument */ #endif NULL); for (i=0; i<=VCsep; i++) { AlignObjects(ALIGN_RIGHT,(HANDLE)(tEdit),(HANDLE)(Text[i]),NULL); } if (Miscdata.ShowFunc==1) { if (DynLibErrors) for (i=-1; iNameFirstChar==' ') { /* Data DirEntry */ pfn=DataLibReadVRecord(dlArch,NULL); /* get diagram's file name */ if (pfn && *pfn) { ParamEraseLibs(pfn,FALSE); unlink(pfn); FreeFileName(pfn); /* Free unique filename */ } _MemFree(pfn); } else { /* Group DirEntry */ DataLibDown(dlArch); DataLibEnum(dlArch,DelFuncCallback,FALSE); DataLibUp(dlArch); } DataLibDelete(dlArch); return 0; } Local(Int2) aDelete(DataLibPtr dl, DataLibNotify post) { CharPtr pfn; Int2 i; /* Are the active functions deleting? */ if (dl->SelectedDirPtr==dl->CurDirPtr) { dl->SelectedDirPtr=0; DataLibSetSelected(dl); DeactivateFunction(); } /* Go to internal level */ DataLibDown(dl); /* Delete Dynamic Linked Library (executable code), if any */ pfn=DataLibReadVRecord(dl,PART_LIB); if (pfn && *pfn) { FreeFileName(pfn); /* Free unique filename */ unlink(pfn); } _MemFree(pfn); /* Delete all the internal partitions */ DataLibDeletePartitions(dl,PART_RHS,PART_FUNC, PART_DATE,PART_LIB,PART_MISC, NULL); for (i=0; iPost) wp->Post(wp->DataLib,res); PopContext(); _MemFree(wp); Remove(w); } Global(CharPtr) ImportCollectLines(FILE PNTR in) { CharPtr p; Char c; p=NULL; while (TRUE) { c=fgetc(in); ungetc(c,in); if (c==SECPRF[0]) break; fgets(ParBuf,PAR_BUF,in); #if _WIN StrCpy(ParBuf+StrLen(ParBuf)-1,"\r\n"); #endif if (p) { p=_MemMore(p,StrLen(p)+StrLen(ParBuf)+1); StrCat(p,ParBuf); } else { p=_MemNew(StrLen(ParBuf)+1); StrCpy(p,ParBuf); } } fgets(ParBuf,PAR_BUF,in); /* skip term line */ return p; } Local(void) aImportOk(ButtoN b) { WindoW w; ImportWorkPtr wp; FILE PNTR in; CharPtr p; MiscData md; int n,m; Int2 res=1,i; Char buf[200]; Boolean defdgm=TRUE; w=ParentWindow(b); wp=GetWindowExtra(w); Disable(wp->btns); GetTitle(wp->file,ParBuf,PAR_BUF); StrTrim(ParBuf); in=fopen(ParBuf,"rt"); if (in==NULL) { myWarning("_Open",ParBuf); goto end; } if (ImportFuncCode(in,FALSE)) goto end1; *ParBuf=NAMEDIR_CHAR; if (fscanf(in,"System: %[^\n]\n",ParBuf+1)!=1) { myWarning("IF_NOT",10); goto end1; } sprintf(buf,"%s '%s'...",FunctionTxt[IMPORTING_C],ParBuf+1); PushContext(NULL,NULL,buf); StrCat(ParBuf," (imported "); DayTimeStr(ParBuf+StrLen(ParBuf),TRUE,TRUE); StrCat(ParBuf,")"); DataLibCreate(wp->DataLib,ParBuf); DataLibDown(wp->DataLib); buf[sizeof(buf)-1]='\0'; while (fgets(ParBuf,PAR_BUF,in)) { StrTrim(ParBuf); if (ParBuf[0]!=SECPRF[0]) { myWarning("IF_NOT",11); goto end2; } switch (ParBuf[1]) { case '=': /* incorporate to partition */ StrTrim(ParBuf+2); StrNCpy(buf+1,ParBuf+2,sizeof(buf)-2); buf[0]=HIDDEN_CHAR; p=ImportCollectLines(in); StrTrim(p); if (*p) DataLibWriteVRecord(wp->DataLib,buf,p,StrLen(p)+1); _MemFree(p); break; case 'u': /* user function */ UserFuncImport(wp->DataLib,in); fgets(ParBuf,PAR_BUF,in); /* skip delimiter */ break; case 'm': /* Misc partition */ DataLibCreate(wp->DataLib,PART_MISC); fscanf(in," der%i=",&m); m=MIN(DERMAX,m); for (i=0; iDataLib,(CharPtr)&md,sizeof(md)); fgets(ParBuf,PAR_BUF,in); /* skip delimiter */ break; case 'w': /* windows */ WindowsImport(wp->DataLib,in); fgets(ParBuf,PAR_BUF,in); /* skip delimiter */ break; case 'd': /* diagrams */ DiagramsImport(wp->DataLib,in,FALSE); defdgm=FALSE; break; default: myWarning("IF_NOT",12); goto end2; } } /* date */ time(&upDate.last); upDate.lastDecl=upDate.last; DataLibCreate(wp->DataLib,PART_DATE); DataLibWrite(wp->DataLib,(CharPtr)&upDate,sizeof(upDate)); /* default diagram */ if (defdgm) { DataLibCreate(wp->DataLib,NAMEDIR_STR"diagram"); if (dCreate(wp->DataLib,NULL)) DataLibDelete(wp->DataLib); else DataLibSetUserPtr(wp->DataLib,wp->DataLib->ParentDirPtr,wp->DataLib->CurDirPtr); } res=0; end2:; DataLibUp(wp->DataLib); PopContext(); end1:; fclose(in); end:; aImportTerm(b,res); } Local(void) aImportCancel(ButtoN b) { aImportTerm(b,1); } #if _WIN #pragma argsused #endif Local(void) aImportHelp(ButtoN b) { Help(NULL); } Local(void) aImportInFile(ButtoN b) { WindoW w; Char ext[20]; ImportWorkPtr wp; w=ParentWindow(b); wp=GetWindowExtra(w); StrCpy(ext,GetParam(SFS_EXTENSIONS,"ES")); *ParBuf='\0'; if (myGetInputFileName(ParBuf,PAR_BUF,ext)) { SetTitle(wp->file,ParBuf); } Select(w); } Local(Int2) aImport(DataLibPtr dl, DataLibNotify post) { WindoW wE; GrouP g; ImportWorkPtr wp; wp=_MemNew(sizeof(*wp)); wp->Post=post; wp->DataLib=dl; PushContext(HLP_IMPORTSYS,NULL,FunctionTxt[IMPORT_C]); wE=FixedWindow(-50,-50,-sysCharWidth,-sysLineHeight,"",NULL); SetWindowExtra(wE,wp,NULL); g=NormalGroup(wE,3,0,FunctionTxt[IMPORT_T],NULL,NULL); SetGroupMargins(g,sysCharWidth,sysLineHeight2); SetGroupSpacing(g,sysCharWidth,sysLineHeight2); wp->file=DialogText(g,"",25,NULL); PushButton(g,FunctionTxt[IMPORTOF_B],aImportInFile); wp->btns=TermButtons(wE,g,aImportOk,aImportCancel,aImportHelp); Show(wE); SelectText(wp->file,0,0); return 0; } /* Export routine (DataLibShow) */ /* Code system's characteristics */ Global(void) ExportFuncCode(FILE PNTR out, Boolean full) { int sysclass,i,d; DayTimeStr(ParBuf,TRUE,TRUE); fprintf(out,"Exported %s %s\n",IMEX_VERSION,ParBuf); SysClassInfo(FALSE,ParBuf,&sysclass); fprintf(out,"Class: %s %i\n",ParBuf,sysclass); if (full) { fprintf(out,"Fcode: %i:",(int)VCsep); for (i=0; iPost) wp->Post(wp->DataLib,res); PopContext(); _MemFree(wp); Remove(w); } Local(void) aExportOk(ButtoN b) { WindoW w; Int2 i; ExportWorkPtr wp; CharPtr p; FILE PNTR out; w=ParentWindow(b); wp=GetWindowExtra(w); Disable(wp->btns); GetTitle(wp->file,ParBuf,PAR_BUF); StrTrim(ParBuf); out=fopen(ParBuf,"wt"); if (!out) { myWarning("_Open",ParBuf); Enable(wp->btns); return; } sprintf(ParBuf,"%s '%s'...",FunctionTxt[EXPORTING_C],wp->DataLib->DirName+1); PushContext(NULL,NULL,ParBuf); /* Psudo-activate visualizer to make names known */ VisFull=FALSE; ActivateVisualizer(wp->DataLib); /* Create export file header */ ExportFuncCode(out,FALSE); /* only class info */ fprintf(out,"System: %s\n",wp->DataLib->DirName+1); DataLibDown(wp->DataLib); /* 1. Names specified by the user */ for (i=0; iDataLib,ParBuf)==0) { p=DataLibReadVRecord(wp->DataLib,NULL); fprintf(out,SECPRF"= %s\n%s\n"SECPRF"\n",ParBuf+1,p); _MemFree(p); } } /* 2. RHS and local functions */ if (DataLibFind(wp->DataLib,PART_RHS)==0) { p=DataLibReadVRecord(wp->DataLib,NULL); fprintf(out,SECPRF"= %s\n%s\n"SECPRF"\n",PART_RHS+1,p); _MemFree(p); } if (DataLibFind(wp->DataLib,PART_FUNC)==0) { p=DataLibReadVRecord(wp->DataLib,NULL); fprintf(out,SECPRF"= %s\n%s\n"SECPRF"\n",PART_FUNC+1,p); _MemFree(p); } /* 3. Aux functions */ for (i=0; iDataLib,ParBuf)==0) { p=DataLibReadVRecord(wp->DataLib,NULL); fprintf(out,SECPRF"= %s\n%s\n"SECPRF"\n",ParBuf+1,p); _MemFree(p); } } /* 4. User functions */ if (DataLibFind(wp->DataLib,PART_UDFUNC)==0) { fprintf(out,SECPRF"u %s\n",PART_UDFUNC+1); UserFuncExport(wp->DataLib,out); fprintf(out,SECPRF"\n"); } /* 5. MiscData */ if (DataLibFind(wp->DataLib,PART_MISC)==0) { MiscData md; DataLibRead(wp->DataLib,(CharPtr)&md,sizeof(md)); fprintf(out,SECPRF"m %s\n der%i=",PART_MISC+1,(int)DERMAX); for (i=0; iDataLib,PART_WIN)==0) { fprintf(out,SECPRF"w %s\n",PART_WIN+1); WindowsExport(wp->DataLib,out); fprintf(out,SECPRF"\n"); } /* 7. Diagrams */ if (wp->diagram) { i=GetValue(wp->diagram); /* see EXPORTDx_B constants */ if (i>1) { fprintf(out,SECPRF"d diagrams\n"); DiagramsExport(wp->DataLib,out,i); fprintf(out,SECPRF"\n"); } } fclose(out); DataLibUp(wp->DataLib); /* Psudo-deactivate visualizer */ DeactivateVisualizer(wp->DataLib); VisFull=TRUE; /* That's all */ PopContext(); aExportTerm(b,0); } Local(void) aExportCancel(ButtoN b) { aExportTerm(b,1); } #if _WIN #pragma argsused #endif Local(void) aExportHelp(ButtoN b) { Help(NULL); } Local(void) aExportOutFile(ButtoN b) { WindoW w; Char def[PAR_BUF]; ExportWorkPtr wp; w=ParentWindow(b); wp=GetWindowExtra(w); GetTitle(wp->file,def,PAR_BUF); *ParBuf='\0'; if (myGetOutputFileName(ParBuf,PAR_BUF,def)) { SetTitle(wp->file,ParBuf); } Select(w); } /* Called if there is at least one diagram associated with the system being exported */ #if _WIN #pragma argsused #endif Local(Int2) DiagramExists(DataLibPtr dl) { return -1; /* abort enumeration, i.e. there is a diagram */ } Local(Int2) aExport(DataLibPtr dl, DataLibNotify post) { WindoW wE; GrouP g,gf,gd; ExportWorkPtr wp; CharPtr p; wp=_MemNew(sizeof(*wp)); wp->Post=post; wp->DataLib=dl; PushContext(HLP_EXPORTSYS,NULL,FunctionTxt[EXPORT_C]); wE=FixedWindow(-50,-50,-sysCharWidth,-sysLineHeight,dl->DirName,NULL); SetWindowExtra(wE,wp,NULL); g=HiddenGroup(wE,0,5,NULL); SetGroupMargins(g,0,0); SetGroupSpacing(g,sysCharWidth,sysLineHeight2); gf=NormalGroup(g,2,0,FunctionTxt[EXPORT_T],NULL,NULL); SetGroupMargins(gf,sysCharWidth,sysLineHeight2); SetGroupSpacing(gf,sysCharWidth,sysLineHeight2); StrCpy(ParBuf,dl->DirName+1); p=StrChr(ParBuf,' '); if (p) *p='\0'; GetParamAppend(SFS_EXTENSIONS,"ES"); wp->file=DialogText(gf,ParBuf,25,NULL); PushButton(gf,FunctionTxt[EXPORTOF_B],aExportOutFile); wp->diagram=NULL; if (DataLibDown(dl)==0) { if (DataLibEnum(dl,DiagramExists,FALSE)<0) { wp->diagram=gd=NormalGroup(g,3,0,FunctionTxt[EXPORTD_T],NULL,NULL); SetGroupMargins(gd,sysCharWidth,sysLineHeight2); SetGroupSpacing(gd,sysCharWidth,sysLineHeight2); RadioButton(gd,FunctionTxt[EXPORTDN_B]); RadioButton(gd,FunctionTxt[EXPORTDI_B]); RadioButton(gd,FunctionTxt[EXPORTDF_B]); SetValue(gd,3); } DataLibUp(dl); } wp->btns=TermButtons(wE,g,aExportOk,aExportCancel,aExportHelp); Show(wE); SelectText(wp->file,0,0); return 0; } /* Final termination of Functions selection in any case */ Local(void) TerminateSelection(void) { if (!RecompileRequest) DataLibClose(&ArchivesLib); UnlockAll(); /* Unlock all menus */ /* Windows associated with newly selected functions did not exist when LockAll was called. So they are not locked and must be refreshed explicitly */ RefreshMenus(); } /* Notification routine called by DataLibShow when the user selects or cancels */ #if _WIN #pragma argsused #endif Local(void) SelectNotify(DataLibPtr dl, Int2 res) { switch (res) { case NOTIFY_DESELECT: PopContext(); /* waitning selection */ DeactivateFunction(); break; case NOTIFY_CANCEL: PopContext(); /* waitning selection */ case NOTIFY_SELECT: ActivateFunction(); /* this also Unlocks(MainMenuLock) in any case */ ClassRecordNewFunc(TRUE); } } /* Called from the Main menu */ #if _WIN #pragma argsused #endif Global(void) SelectFunction(Int2 index) { LockAll(); /* lock second time becaus otherwise it would be unlocked immediatedly after return */ if (DataLibOpen(&ArchivesLib,ArchivesName)) return; PushContext(HLP_FUNCTION,NULL,FunctionTxt[SELSYST_C]); DeactivateFunction(); if (DataLibShow(&ArchivesLib,FunctionTxt[SEL_T],SelectNotify,"nu-r-d-ie-g", aCreate,aEdit,NULL,aDelete,aImport,aExport)) { /* failed */ TerminateSelection(); } } /* Determines status of menu item */ #if _WIN #pragma argsused #endif Global(Boolean) SelectFunction_Status(Int2 index) { return *ArchivesName; } /*----------------*/ /* Compile a file */ Local(PostProcPtr) UserPostProc; Local(Char) CompLogFile[20]; /* Check whether a compiler has terminated */ Local(Boolean) HasCompilerTerminated(void) { /* NOTE: CompLogFile is loaded just prior returning from Compile */ return access(CompLogFile,0)==0; /* TRUE if compiler's log file exists */ } Local(time_t) CompBegin; Global(Boolean) IsErrorLine(CharPtr line, int PNTR num, CharPtr msg) { CharPtr p,copy; int pos; Boolean ret=FALSE; /* There may be no 'tmp_sys.c' in the error message (for example, when an error is in a file #included from RHS). So we skip the following check. GetParam(SFS_COMPILER,"SOURCE"); GetParamAppend(SFS_EXTENSIONS,"C"); if (StrStr(line,ParBuf)) */ { copy=_StringSave(line); StringLower(copy); if (StrStr(copy,"error") #ifdef _UNIX_R6K /* AIX c compiler doesn't place "error" into messages... */ || StrStr(copy," (s) ") #endif /* _UNIX_R6K */ ) { p=StrStr(copy,"line"); pos=0; if (p) { p=line+(Int2)(p-copy); p+=StrLen("line"); sscanf(p,"%i%*[^ ]%n",num,&pos); StrCpy(msg,p+pos); ret=TRUE; } else { sscanf(line,"%*[^1-9]%i%*[^ ]%n",num,&pos); if (pos) { StrCpy(msg,line+pos); ret=TRUE; } } } _MemFree(copy); } return ret; } /* Post-compilation processing. Check compiler or/and linke errors */ Local(Int2) CheckCompileErrors(void) { Char b[150],line[150]; int linenum=-1; FILE PNTR err; Boolean Errors=FALSE; err=FileOpen(GetParam(SFS_COMPILER,"LOGFILE"),"rt"); if (err) { /* Check compiler errors */ while (FileGets(b,sizeof(b),err)) if (IsErrorLine(b,&linenum,line)) { Errors=TRUE; break; } if (!Errors) { /* Check linker errors */ rewind(err); GetParamString(SFS_COMPILER,"LERRLINEI"); while (FileGets(b,sizeof(b),err)) if (sscanf(b,ParBuf,line)==1) { /* Error! */ Errors=TRUE; break; } } FileClose(err); } /* no errlog file => no errors in rhs */ PopContext(); /* compiling... */ ShowDuration(CompBegin); return UserPostProc(Errors,line,linenum); } Global(Int2) Compile(CharPtr cmd, PostProcPtr userproc) { Int2 rc; UserPostProc=userproc; CompBegin=StartDuration(); /* Compilation started at */ GetParam(SFS_COMPILER,"LOGFILE"); if (cmd) unlink(ParBuf); /* erase logfile */ StrCpy(CompLogFile,ParBuf); /* for HasCompilerTerminated */ rc=ExecuteCommand(cmd ? GetParam(SFS_COMPILER,cmd): cmd, HasCompilerTerminated,CheckCompileErrors); SetParam(SFS_COMPILER,"DIFF","n"); return rc; } /*----------------------------------------------------*/ /* Create executable codes for the selected functions */ #define DIM_F "%n [%n %i ]%n" /* format used for dimension parsing */ #define ID_F "%*[a-zA-Z0-9_()]"DIM_F /* id[dim] */ #define GRO_F "{%*[^}]}"DIM_F /* {id id ...}[dim] */ /* Enumerates all the names from a list in the given partition */ Global(Int2) EnumNames(DataLibPtr dl, CharPtr partition, ProcessName process) { CharPtr p; CharPtr pr; int pos_id_e,pos_num,pos_e,dim; NamesError rc=(NamesError)0; pr=p=DataLibReadVRecord(dl,partition); for (; *p && !rc; ) { pos_e=-1; sscanf(p," %n",&pos_e); p+=pos_e; if (pos_e<0 || !*p) break; /* only trailing blanks. !*p for cc */ pos_id_e=pos_num=pos_e=0; dim=1; if (IS_ALPHA(*p) || *p==*GRO_F) { sscanf(p, *p==*GRO_F ? GRO_F : ID_F ,&pos_id_e,&pos_num,&dim,&pos_e); if (pos_id_e==0) pos_e=pos_id_e=(int)StrLen(p); /* last/only name is right-justified */ else if (pos_num==0) pos_e=pos_id_e; /* no [ after name */ else if (pos_e==0 || dim<2) rc=NE_DIM; } else rc=NE_NOTALPHA; if (process) process(p,pos_id_e,dim); p+=pos_e; pos_e=-1; sscanf(p," ,%n",&pos_e); if (pos_e>=0) p+=pos_e; } _MemFree(pr); return rc; } Local(FILE PNTR) Source; /* output file with C source */ Local(Int2) LineCount; /* EnumNames callback for RHS */ Local(CharPtr) pRhs; Local(NamesError) Err; Local(Int2) GenerateErrorFile(NamesError er, ...); #if _WIN #pragma argsused #endif Local(void) SubstituteRhs(CharPtr name, int len, int dim) { CharPtr what; CharPtr with; Int2 reps; Err=0; with=_MemNew(len+2); if (!with) { myWarning("ED_MEM"); return; } sprintf(with,"%.*s_",len,name); what=_MemNew(len+2); if (!what) { myWarning("ED_MEM"); return; } sprintf(what,"%.*s'",len,name); pRhs=StrSubstitute(pRhs,what,with,TRUE,&reps); /* change whole id only */ _MemFree(with); _MemFree(what); } Global(Boolean) ProcessIncludeFile(CharPtr fn, struct stat *statbuf) { struct stat fstatbuf; FILE PNTR f; Char ifn[PATH_MAX]; Char parBuf[PAR_BUF]; Boolean res=FALSE; if (!fn || !fn[0]) return res; if (stat(fn,&fstatbuf)==0) { if (difftime(fstatbuf.st_mtime,statbuf->st_mtime)>0) { *statbuf=fstatbuf; res=TRUE; } f=fopen(fn,"r"); if (f) { while (!feof(f)) { if (!fgets(parBuf,PAR_BUF,f)) break; if (sscanf(parBuf,"# include \"%[^\"]\"",ifn)==1) res|=ProcessIncludeFile(ifn,statbuf); } fclose(f); } } return res; } /* Determines whether recompilation required */ Global(Boolean) MustRecompile(DataLibPtr arch, DataLibPtr lib, CharPtr partition, Boolean fullcheck, NewerIncludePtr NewerIncludes) { CharPtr pfn; CharPtr pw; struct stat statbuf; Boolean recompile=TRUE; DataLibDown(arch); DataLibFind(arch,PART_DATE); DataLibRead(arch,(CharPtr)&upDate,sizeof(upDate)); /* date of last update of system */ pfn=DataLibReadVRecord(lib,partition); if (*pfn) { /* File name was assigned && */ if (stat(pfn,&statbuf)==0) { /* File exists && */ recompile=difftime(fullcheck ? upDate.last : upDate.lastDecl, statbuf.st_mtime)>0; /* code created later */ if (!recompile && NewerIncludes) recompile=NewerIncludes(&statbuf); } } else { /* Executable does not exist */ _MemFree(pfn); AssignFileName(); /* Assign unique filename */ GetParamAppend(SFS_EXTENSIONS,"LIB"); /* Append the extension to it */ DataLibWriteVRecord(lib,partition,ParBuf,StrLen(ParBuf)+1); pfn=_StringSave(ParBuf); } DataLibUp(arch); if (recompile) { pw=StrStr(pfn,GetParam(SFS_EXTENSIONS,"LIB")); if (pw) *pw='\0'; SetParam(SFS_COMPILER,"TARGET",pfn); } _MemFree(pfn); return recompile; } Global(CharPtr) CountLinesAndErase_r(CharPtr p, Char c, Int2Ptr LineCount) { CharPtr q; Int2 l; if (c=='\r' && (!(l=StrLen(p)) || p[l-1]!='\n')) { p=_MemMore(p,l+2); StrCat(p,"\n"); } if (c=='\r') for (q=p; (q=StrChr(q,c),q); ) StrCpy(q,q+1); if (LineCount) for (q=p; (q=StrChr(q,'\n'),q); (*LineCount)++, q++); return p; } /* Create errlog file in cases when CreateCText fails */ #ifdef VAR_ARGS Local(Int2) GenerateErrorFile(er, va_alist) NamesError er; va_dcl #else Local(Int2) GenerateErrorFile(NamesError er,...) #endif { va_list argptr; FILE PNTR errlog; Int2 pt; switch (er) { case NE_NOTALPHA: pt=NAME1; break; case NE_DIM: pt=NAMEDIM; break; case NE_PHASE: pt=PHASE; break; case NE_COMPNUM: pt=COMPNUM; break; default: pt=-1; } #ifdef VAR_ARGS va_start(argptr); #else va_start(argptr,er); #endif vsprintf(ParBuf,FunctionTxt[pt],argptr); va_end(argptr); SetParam(SFS_COMPILER,"CURERMSG",ParBuf); errlog=FileOpen(GetParam(SFS_COMPILER,"LOGFILE"),"at"); fprintf(errlog,GetParam(SFS_COMPILER,"CERRLINEO",(int)LineCount-1)); FileClose(errlog); return 1; } #if _WIN #pragma argsused #endif Local(void) IncLineCount(CharPtr name, int len, int dim) { LineCount++; } /* Build #include and #defines */ Global(CharPtr) BuildH(void) { Int2 i,d,l; Char buf[100],clname[50]; GetParam(SFS_COMPILER,"HEADER"); l=StrLen(ParBuf); for (i=0; i') res=rel[1]=='=' ? o>=n : o>n; else res=rel[0]=='=' ? o==n : o!=n; if (!res) { o=LineCount; LineCount=-i; /* -number of control */ rc=GenerateErrorFile(NE_COMPNUM,rel,n); LineCount=o; continue; } } } if (rc) goto error; LineCount=rhsline; /* Header for rhs. [-1] is correct! */ fputs(CountLinesAndErase_r(AuxFuncDescs[-1].Header,'\n',&LineCount),Source); /* Get RHS specification */ StartLine[1+1+VCsep]=LineCount; KindLine[1+1+VCsep]=I_RHS; pRhs=DataLibReadVRecord(&ArchivesLib,PART_RHS); /* strip comments from RHS */ for (p=pRhs; (p=StringStr(p,"//"))!=NULL; p=q) { q=StrChr(p,'\n'); MemFill(p,' ',q ? (size_t)(q-p) : StrLen(p)); } for (p=pRhs; (p=StringStr(p,"/*"))!=NULL; p=q) { q=StrStr(p,"*/"); MemFill(p,' ',q ? (size_t)(q-p)+2 : StrLen(p)); } pRhs=CountLinesAndErase_r(pRhs,'\r',&LineCount); /* Substitute each x' with appropriate FUNC_NAME component */ *ParBuf=HIDDEN_CHAR; sscanf(VCptr[0],"%*i %s",ParBuf+1); /* Phase must be the first in the list */ EnumNames(&ArchivesLib,ParBuf,SubstituteRhs); if (Err) { rc=1; } fwrite(pRhs,StrLen(pRhs),1,Source); _MemFree(pRhs); /* undefs for previously defined names. [-1] is correct! */ q=AuxFuncDescs[-1].Undefs; if (q) { q=ExpandClassDef(_StringSave(q),EA_NO); fputs(q=CountLinesAndErase_r(q,'\r',&LineCount),Source); _MemFree(q); } /* Tail for rhs. [-1] is correct! */ fputs(CountLinesAndErase_r(AuxFuncDescs[-1].Tail,'\n',&LineCount),Source); /* #include for derivatives */ #if ED for (i=0; i=0 && Miscdata.Der[o]!=DER_USER) { StartLine[i+1+1+VCsep+1]=LineCount; continue; } sprintf(ParBuf,"%s%s",PART_SYSFUNC,AuxFuncDescs[i].FuncName); p=DataLibReadVRecord(&ArchivesLib,ParBuf); if (*p) { fputs(CountLinesAndErase_r(AuxFuncDescs[i].Header,'\n',&LineCount),Source); q=AuxFuncDescs[i].Defs; if (q) { q=ExpandClassDef(_StringSave(q),EA_NO); fputs(q=CountLinesAndErase_r(q,'\r',&LineCount),Source); _MemFree(q); } StartLine[i+1+1+VCsep+1]=LineCount; p=CountLinesAndErase_r(p,'\r',&LineCount); fwrite(p,StrLen(p),1,Source); fputs(CountLinesAndErase_r(AuxFuncDescs[i].Tail,'\n',&LineCount),Source); q=AuxFuncDescs[i].Undefs; if (q) { q=ExpandClassDef(_StringSave(q),EA_NO); fputs(q=CountLinesAndErase_r(q,'\r',&LineCount),Source); _MemFree(q); } } else StartLine[i+1+1+VCsep+1]=LineCount; _MemFree(p); } StartLine[AuxNum+1+1+VCsep+1]=LineCount; KindLine[AuxNum+1+1+VCsep+1]=I_AUX; error:; /* C source has been created */ FileClose(Source); /* Clean up everything */ DataLibUp(&ArchivesLib); DeactivateVisualizer(&ArchivesLib); VisFull=TRUE; return rc; } Local(Boolean) CheckIncludes1(CharPtr str, struct stat *statbuf) { int pos; Boolean res=FALSE; Char ifn[PATH_MAX]; for (; (str=StrChr(str,'#'),str); str+=pos) { pos=-1; if (sscanf(str,"# include \"%[^\"]\"%n",ifn,&pos)==1 && pos>0) res|=ProcessIncludeFile(ifn,statbuf); else pos=1; } return res; } /* Are #include files newer than compiled code? */ Local(Boolean) CheckIncludes(struct stat *statbuf) { CharPtr pRhs,pFun,pAux; Int2 i,o; Boolean res=FALSE; /* Rhs */ pRhs=DataLibReadVRecord(&ArchivesLib,PART_RHS); if (*pRhs) res|=CheckIncludes1(pRhs,statbuf); _MemFree(pRhs); /* Local functions */ pFun=DataLibReadVRecord(&ArchivesLib,PART_FUNC); if (*pFun) res|=CheckIncludes1(pFun,statbuf); _MemFree(pFun); /* Aux functions, if any */ for (i=0; i=0 && Miscdata.Der[o]!=DER_USER) continue; sprintf(ParBuf,"%s%s",PART_SYSFUNC,AuxFuncDescs[i].FuncName); pAux=DataLibReadVRecord(&ArchivesLib,ParBuf); if (*pAux) res|=CheckIncludes1(pAux,statbuf); _MemFree(pAux); } return res; } /*-----------------------------------------------------------------*/ /* Make selected functions active, i.e. accessable by applications */ Global(AuxFuncPtr) PNTR AuxFuncs; Local(CharPtr) ReadAndCatLines(CharPtr b, Int2Ptr n) { CharPtr p; p=NULL; do { GetLine(b); (*n)--; if (StrCmp(b,"/*")) { if (p) { p=_MemMore(p,StrLen(p)+StrLen(b)+1); StrCat(p,b); } else p=_StringSave(b); } else break; } while (TRUE); return p; } Global(void) BuildAuxFunc(Boolean go) { Int2 i,n,parent; Char b[PAR_BUF]; if (go) { n=CountLines(); AuxNum=0; while (n>0) { i=AuxNum; if (AuxNum++) AuxFuncDescs=_MemMore(AuxFuncDescs,ARRAYSIZE(AuxFuncDesc,AuxNum)); else AuxFuncDescs=_MemNew(ARRAYSIZE(AuxFuncDesc,1)); AuxFuncDescs[i].flags=0; GetLine(b); AuxFuncDescs[i].MenuName=_StringSave(b); GetLine(b); AuxFuncDescs[i].Prompt=_StringSave(b); GetLine(b); if (b[StrLen(b)-1]=='+') { AuxFuncDescs[i].flags|=COMPULSORY; b[StrLen(b)-1]='\0'; } AuxFuncDescs[i].FuncName=_StringSave(b); if (DerOrd(i)) { parent=i-1; AuxFuncDescs[i].parent=0; } else AuxFuncDescs[i].parent=parent; GetLine(b); AuxFuncDescs[i].Header=_StringSave(b); AuxFuncDescs[i].Defs=ReadAndCatLines(b,&n); GetLine(b); AuxFuncDescs[i].Tail=_StringSave(b); AuxFuncDescs[i].Undefs=ReadAndCatLines(b,&n); n-=5; /* menuname,prompt,funcname,header,tail */ GetLine(b); AuxFuncDescs[i].DepVars=_StringSave(b); n--; AuxFuncDescs[i].IndepVars=ReadAndCatLines(b,&n); } AuxNum--; /* Hide descriptor of RHS which must be the first */ AuxFuncDescs++; AuxFuncs=_MemNew(AuxNum*sizeof(AuxFuncPtr)); } else { AuxNum=0; AuxFuncDescs=NULL; } } Global(void) FreeAuxFunc(void) { Int2 i; if (AuxFuncDescs) { AuxNum++; /* Free also descriptor of RHS */ AuxFuncDescs--; for (i=0; i=DERMAX) continue; if (Miscdata.Der[o]==DER_SYM) { if (mem) { mem=FALSE; myMessageSetUser(ShowErrFile); GetParam(SFS_COMPILER,"LOGFILE"); StrCat(ParBuf,"1"); myWarning("AD_ERR",AuxFuncDescs[i].Prompt); myMessageSetUser(NULL); } continue; } if (Miscdata.Der[o]==DER_USER) { myWarning("AD_UD",AuxFuncDescs[i].Prompt); continue; } } } DataLibUp(&ArchivesLib); if (error) { FunctionsHandle=LibraryUnlock(FunctionsHandle); } else { UpdateInfoInMainWindow(MWI_SYSTEM,ArchivesLib.DirName+1); ParamInit(); ActivateVisualizer(&ArchivesLib); ActivateUserFunc(&ArchivesLib); /* Call it AFTER Visualizer to allow it to build class table */ ActivateDiagram(&ArchivesLib); /* AFTER curve types have been chosen: Let windows know about that (e.g. this allows 1D stairs get parameter values and therefore to draw RHS) */ NotifyAboutNewInitPoint(); } } else { ArchivesLib.SelectedDirPtr=0; DataLibSetSelected(&ArchivesLib); } TerminateSelection(); } /* Callback for List of errors. List is created by aEdit when DynLibErrors!=0 */ Local(void) ErrorListActn(LisT l) { TexT t; int Line; /* not Int2! - see aEdit */ size_t Len; Int2 SPos,i; CharPtr cp; CharPtr p; Line=GetValue(l)-1; BSSeek(ErrorLines,(Int4)(Line*sizeof(Line)),SEEK_SET); BSRead(ErrorLines,&Line,sizeof(Line)); t=tEdit; /* just for the case Line exceeds number of lines generated */ if (Line<0) { t=Text[-Line-1]; Line=0; } else for (i=0; i<=1+1+VCsep+1+AuxNum; i++) if (Line0) Line--; for (cp=p; Line--; ) { cp=StrChr(cp,'\n'); if (cp) cp++; else break; } SPos=(Int2)(cp ? cp-p : StrRChr(p,'\n') ? StrRChr(p,'\n')-p : StrLen(p)); SelectText(t,SPos,SPos); _MemFree(p); } } /* Post routine for aEdit; it is called after the user finished his correction of functions specification after unsuccessful compilation */ Local(void) ErrorsAreCorrected(DataLibPtr dl, Int2 res) { ErrorLines=BSFree(ErrorLines); if (res) { RecompileRequest=FALSE; MakeActive(FALSE); } else { /* pushed OK - try to activate functions once more */ RecompileRequest=TRUE; DataLibClose(dl); ActivateFunction(); } } /* Erases functional parameters lib */ Local(Int2) EraseParLib(DataLibPtr dlArch) { CharPtr pfn; pfn=DataLibReadVRecord(dlArch,NULL); /* lib's file name */ DataLibUp(dlArch); /* for MustRecompile */ ParamEraseLibs(pfn,TRUE); /* if older then declarations */ DataLibDown(dlArch); /* for MustRecompile */ _MemFree(pfn); return 0; } /* Post-compilation processing */ #if _WIN #pragma argsused #endif Local(Int2) ProcessFunctionsErrors(Boolean errors, CharPtr text, int linenum) { CharPtr p; if (errors) { /* errors */ DynLibErrors=1; /* remove dll, if any */ DataLibDown(&ArchivesLib); unlink(p=DataLibReadVRecord(&ArchivesLib,PART_LIB)); _MemFree(p); DataLibUp(&ArchivesLib); /* Create Edit window and allow the user to correct his stuff */ if (aEdit(&ArchivesLib,ErrorsAreCorrected)) /* cannot create */ MakeActive(FALSE); /* make inactive */ RecompileRequest=TRUE; } else { /* no errors */ RecompileRequest=FALSE; StartLine=_MemFree(StartLine); KindLine=_MemFree(KindLine); /* We have to postpone the processing of successful compilation until return from Compile to avoid recursive call to ExecuteCommand */ } return errors ? 1 : 0; } typedef EntryPtr(Int2,AutoDifPtr,(CharPtr PNTR,Uint1Ptr)); /* Paramenters for contdiff, see contdiff.c */ Local(CharPtr PNTR) BuildDerParam(void) { CharPtr PNTR Param; CharPtr names; Int2 i,j,o; /* count functions (except derivatives) */ names=_MemNew(1000); for (o=0, i=-1; i=0) { Param[j++]=_StringSave(""); /* no local functions */ sprintf(ParBuf,"%s%s",PART_SYSFUNC,AuxFuncDescs[i].FuncName); Param[j++]=DataLibReadVRecord(&ArchivesLib,ParBuf); } else j+=2; for (o=0, i++; i=0; i++, o++) { #if ED if (o