📄 int_procs.c
字号:
/*..........................................................................*//* *//* L a s t W a v e K e r n e l 3 . 0 *//* *//* Copyright (C) 1998-2002 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 "xx_system.h"/*********************************************************************************** * * Managing scriptlines * ***********************************************************************************/COMPSTRUCT NewCompStruct (void){ COMPSTRUCT cs; #ifdef DEBUGALLOCDebugType = "CompStruct";#endif cs = (COMPSTRUCT) Malloc(sizeof(CompStruct)); cs->pos.dollar = NULL; cs->scripts.dollar = NULL; return(cs);}void ClearCompStruct (COMPSTRUCT cs){ SCRIPT *script1; if (cs == NULL) return; if (cs->pos.dollar != NULL) { Free(cs->pos.dollar); cs->pos.dollar = NULL; } if (cs->scripts.dollar != NULL) { for (script1 = cs->scripts.dollar; *script1 != NULL; script1++) DeleteScript(*script1); Free(cs->scripts.dollar); cs->scripts.dollar = NULL; }}void DeleteCompStruct (COMPSTRUCT cs){ if (cs == NULL) return; ClearCompStruct(cs); #ifdef DEBUGALLOCDebugType = "CompStruct";#endif Free(cs); }SCRIPTLINE NewScriptLine(void){ SCRIPTLINE sl; #ifdef DEBUGALLOCDebugType = "ScriptLine";#endif sl = (SCRIPTLINE) (Malloc(sizeof(struct scriptline))); sl->line = NULL; sl->nWords = 0; sl->words = NULL; sl->cs = NULL; sl->flags = 0; sl->proc = NULL; sl->redirect = NULL; return (sl);}void DeleteScriptLine(SCRIPTLINE sl){ int i; if (sl->line) Free(sl->line); if (sl->nWords != 0 && sl->words != NULL) DeleteList(sl->words); if (sl->cs != NULL) { for (i=0;i<sl->nWords;i++) DeleteCompStruct(sl->cs[i]); Free(sl->cs); } if (sl->proc != NULL) DeleteProc(sl->proc);#ifdef DEBUGALLOCDebugType = "ScriptLine";#endif Free(sl);}/* Make script line from beg,end list */#define NMaxScripts 5extern SCRIPT ParseScript__(char *theLine,char flagTemp, char flagEndIsBracket, char flagSubst, char flagBrace, char *flagError);/* Warning : ptrs is a static variable */SCRIPTLINE MakeScriptLine(char *line, int nWords, char **beg, char **end, int nPtrs, char **ptrs, char flagSetv, int redirectWord, char flagSubst){ char **list; SCRIPTLINE sl; int i,j,nd,nw,ns,ns1; SCRIPT script; if (nWords == 0) Errorf("MakeScriptLine() : empty line"); /* First we create the list of words */ list = BegEndStr2List(beg,end); /* Allocation of the script line */ sl = NewScriptLine(); /* Setting the line */ sl->line = CharAlloc(strlen(line)+1); strcpy(sl->line,line); /* Setting the list of words and number of words */ sl->words = list; sl->nWords = nWords; /* Allocation of the COMPSTRUCT if necessary */ if (nPtrs != 0) { sl->cs = Malloc(sizeof(COMPSTRUCT)*nWords); for (nw=0; nw<nWords;nw++) sl->cs[nw] = NULL; } else sl->cs = NULL; /* Setting the flagSetv */ if (flagSetv) sl->flags |= SLSetvFlag; /* Setting the dollar or bracket positions and allocation */ if (nPtrs != 0) { if (**ptrs == '$') sl->flags |= SLDollarFlag; nw = 0; ns = 0; for (i=0; i<nPtrs;) { /* This word has no dollars */ while (nw != nWords-1 && ptrs[i] >= beg[nw+1]) nw++; /* This word has at least 1 dollar or bracket, let's allocate the compStruct */ sl->cs[nw] = NewCompStruct(); /* Counting the number of dollars or brackets and scripts */ ns1 = 0; for (j=i; j<nPtrs;j++) { if (nw != nWords-1 && ptrs[j] >= beg[nw+1]) break; if (**ptrs != '$' || *(ptrs[j]+1) == '[') {ns1++;j++;} } nd = j-i; /* Allocation of the pos.dollar (i.e., pos.bracket) and dollar scripts (i.e., bracket scripts) */ sl->cs[nw]->pos.dollar = Malloc(sizeof(char *)*(nd+1)); if (ns1 != 0) { sl->cs[nw]->scripts.dollar = Malloc(sizeof(SCRIPT *)*(ns1+1)); sl->cs[nw]->scripts.dollar[0] = NULL; } ns += ns1; /* Setting the pos.dollar */ for (j=i;j<i+nd;j++) { sl->cs[nw]->pos.dollar[j-i] = (ptrs[j]-beg[nw])+list[nw]; } sl->cs[nw]->pos.dollar[j-i] = NULL; if (j<i+nd) break; i = j; nw++; } if (i<nPtrs) { DeleteScriptLine(sl); return(NULL); } } /* Setting the scripts */ if (nPtrs != 0 && ns != 0) { for (nw = 0; nw<sl->nWords ; nw++) { if (sl->cs[nw] == NULL || sl->cs[nw]->pos.dollar == NULL) continue; ptrs = sl->cs[nw]->pos.dollar; ns1 = 0; for (i=0;ptrs[i]!=NULL;i++) { if (**ptrs != '$' || *(ptrs[i]+1) == '[') { if (**ptrs != '$') script = ParseScript__(ptrs[i]+1,NO,YES,flagSubst,NO,NULL); else script = ParseScript__(ptrs[i]+2,NO,YES,flagSubst,NO,NULL); if (script == NULL) break; sl->cs[nw]->scripts.dollar[ns1] = script; ns1++; i++; } } if (ptrs[i] != NULL) break; if (ns1 != 0) sl->cs[nw]->scripts.dollar[ns1] = NULL; } if (nw<sl->nWords) { DeleteScriptLine(sl); return(NULL); } } if (redirectWord >= 0) { sl->redirect = sl->words + redirectWord; sl->words[redirectWord] = NULL; } else sl->redirect = NULL; return(sl);}/*********************************************************************************** * * Managing scripts * ***********************************************************************************//* the type */char *scriptType = "&script";/* * The field list */struct field fieldsScript[] = { NULL, NULL, NULL, NULL, NULL};static char *ToStrScript(SCRIPT val,char flagShort){ static char str[30]; sprintf(str,"(&script)"); return(str);}static void PrintScript(VALUE val){ SCRIPT s = (SCRIPT) val; int i; Printf("(&script) {\n"); for (i=0;i<s->nsl;i++) Printf(" %s\n",s->sl[i]->line); Printf("}\n");}static void PrintInfoScript(VALUE val){ Printf(" nScriptLines = %d\n",((SCRIPT) val)->nsl);}/* * The type structure for SCRIPT */TypeStruct tsScript = { "{{{&script} {This corresponds to a script. It can be obtained from a procedure using the 'script' field of a \'&proc' variable. A script can be directly built using the %%`a script` syntax.}}}", /* Documentation */ &scriptType, /* The basic (unique) type name */ NULL, /* The GetType function */ DeleteScript, /* The Delete function */ NewScript, /* The New function */ NULL, /* The copy function */ NULL, /* The clear function */ ToStrScript, /* String conversion */ PrintScript, /* The Print function : print the object when 'print' is called */ PrintInfoScript, /* The PrintInfo function : called by 'info' */ NULL, /* The NumExtract function : used to deal with syntax like 10a */ fieldsScript, /* The list of fields */};void DeleteScript(SCRIPT script){ int i; if (script) { if (script->nRef==0) { Warningf("DeleteScript() : Trying to delete a temporary script\n"); return; } RemoveRefValue(script); if (script->nRef > 0) return; if (script->nsl != 0 && script->sl != NULL) { for (i=0;i<script->nsl;i++) DeleteScriptLine(script->sl[i]); Free(script->sl); }#ifdef DEBUGALLOCDebugType = "Script";#endif Free(script); } }SCRIPT NewScript(void){ SCRIPT script;#ifdef DEBUGALLOCDebugType = "Script";#endif script = (SCRIPT) (Malloc(sizeof(struct script))); InitValue(script,&tsScript); script->nsl = 0; script->sl = NULL; return (script);}/*********************************************************************************** * * Managing the CProcs * ***********************************************************************************//* * Some useful variables */ static LWPROC *theCProcs; /* Sorted Array of all the Commands which are CProcs */static int nCProcs = 0; /* Size of the array */extern CProcTable cprocTables[]; /* The original table commands of the kernel *//* Creating a new command from a ccommand */extern void Warningf1(char *format,...);char *_theDoc = NULL;static char ** MakeDescriptionList(CProcTable *table, int j) { char **help; char *des; if (table->procs[j].description != NULL) des = table->procs[j].description; else { _theDoc = NULL; (*(table->procs[j].function))(NULL); des=_theDoc; } if (des != NULL && ParseWordList_(des,NULL,&help)) return(CopyList(help)); Warningf1("** Error in the help of C-Proc '%s' (in table '%s', in package '%s')\n",table->procs[j].name,table->name,table->packageName); return(Str2List(NULL));}static LWPROC NewProcFromCP(CProcTable *table, int j){ LWPROC c; c = NewProc(); c->name = table->procs[j].name; c->flagSP = NO; c->p.cp = table->procs + j; c->description = MakeDescriptionList(table,j); c->package = CopyStr(table->packageName); c->procTable = table; return(c);}/* Function used to sort the 'theCProcs' array */static int qsortcmp(const void *s1,const void *s2){ LWPROC * pc1 = (LWPROC *) s1; LWPROC * pc2 = (LWPROC *) s2; return(strcmp((*pc1)->name,(*pc2)->name));} /* Function used to search in the 'theCProcs' array */static int bsearchcmp(const void *n,const void *pc){ char *name = (char *) n; LWPROC *pc1 = (LWPROC *) pc; return(strcmp(name,(*pc1)->name));}/* Function to Initialize the ccommands of the kernel */static void InitCProcs(void){ int n; /* We just add the command tables that are in cprocTables */ n = 0; while (cprocTables[n].name != NULL) AddCProcTable(&(cprocTables[n++])); }#define NCCmdTables 200static CPROCTABLE theCCmdTables[NCCmdTables+1]; /* The table commands *//* Function to interactively add some ccommands (they will be stored in the 'theCProcs' array */void AddCProcTable(CProcTable *ccmdTable){ int j,i,n,nb; LWPROC *array; CPROC commands; LWPROC *pc; if (ccmdTable == NULL || ccmdTable->packageName == NULL || ccmdTable->name == NULL) return; commands = ccmdTable->procs; /* Add the command table to the array of all the command tables */ for (i=0;i<=NCCmdTables;i++) { if (theCCmdTables[i] == NULL) break; } if (i == NCCmdTables+1) Errorf("AddCommandTable() : Sorry already too many command tables (should be <=%d)",NCCmdTables); theCCmdTables[i] = ccmdTable; theCCmdTables[i+1] = NULL; /* Count the number of commands in this table */ for (nb = 0;commands[nb].name; nb++); if (nb == 0) return; /* * In the case it is the first table, we just add it and sort it */ if (nCProcs == 0) { theCProcs = (LWPROC *) Malloc(nb*sizeof(LWPROC)); for (n=0,j = 0;commands[j].name; j++) { /* If procedure name not valid then do not define it */ if (!IsValidProcName(commands[j].name)) { Warningf("** Invalid name for C-Proc '%s' (in table '%s', in package '%s') --> was not defined\n",commands[j].name,ccmdTable->name,ccmdTable->packageName); continue; } /* Otherwise, we define it */ theCProcs[n] = NewProcFromCP(ccmdTable,j); n++; } nCProcs = n; qsort(theCProcs,nCProcs,sizeof(LWPROC),&qsortcmp); } /* * Otherwise, we look whether some commands are redefined. * In that case we only keep the last version of it and we set the * name of the old version to NULL (we will have to be careful * when looping on the command names using the 'theCCmdTables' array) */ else { /* Make a new array that will contain everything */ array = Malloc((nCProcs+nb)*sizeof(LWPROC)); for (j=0,n=0;j<nCProcs;j++,n++) array[n] = theCProcs[j]; /* Loop on the commands to add */ for (j = 0;commands[j].name; j++) { /* If procedure name not valid then do not define it */ if (!IsValidProcName(commands[j].name)) { Warningf("** Invalid name for C-Proc '%s' (in table '%s', in package '%s') --> was not defined\n",commands[j].name,ccmdTable->name,ccmdTable->packageName); continue; } /* Does this command already exist ? */ pc = (LWPROC *) bsearch(commands[j].name,theCProcs,nCProcs,sizeof(LWPROC),&bsearchcmp); /* If it does then print a warning and replace the old command */ if (pc != NULL) { Warningf("AddCommandTable() : redefining C-command '%s'\n",commands[j].name); (*pc)->p.cp = commands+j; DeleteList((*pc)->description); (*pc)->description = MakeDescriptionList(ccmdTable,j); } else { array[n]= NewProcFromCP(ccmdTable,j);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -