📄 hshell.c
字号:
} } printf("\n");}/* EXPORT->GetConfig: return a list of selected config values */int GetConfig(char *user, Boolean incGlob, ConfParam **list, int max){ ConfigEntry *e; int found = 0; /* Specific ones first */ if (user!=NULL) for (e=confList; e!= NULL; e=e->next){ if (e->param.user!=NULL && strcmp(e->param.user,user)==0) { ++found; if (list != NULL) { if (found>max) HError(5071,"GetConfig: more than %d for user %s%s", max,user==NULL?"<null>":user,incGlob?"with globals":""); *list++ = &e->param; } } } /* Then append globals */ if (incGlob || user==NULL) for (e=confList; e!= NULL; e=e->next){ if (e->param.user==NULL) { ++found; if (list != NULL) { if (found>max) HError(5071,"GetConfig: more than %d for user %s%s", max,user==NULL?"<null>":user,incGlob?"with globals":""); *list++ = &e->param; } } } return found;}/* FindConfParm: return index of conf parameter with given name and kind*/static int FindConfParm(ConfParam **list,int size,char *name,ConfKind kind){ int i; for (i=0; i<size; i++) if (strcmp(list[i]->name,name)==0){ if (kind != AnyCKind && list[i]->kind != kind && !(list[i]->kind==IntCKind && kind==FltCKind)) HError(5072,"FindConfParm: %s is %s but should be type %s", name,cfkmap[list[i]->kind],cfkmap[kind]); list[i]->seen=TRUE; return i; } return -1;}/* EXPORT->HasConfParm: true if parameter exists with given name */Boolean HasConfParm(ConfParam **list, int size, char *name){ return (FindConfParm(list,size,name,AnyCKind) != -1);}/* EXPORT->GetConfStr: return string parameter with given name */Boolean GetConfStr(ConfParam **list,int size,char *name,char *str){ int i; if ((i = FindConfParm(list,size,name,StrCKind)) != -1){ strcpy(str,list[i]->val.s); return TRUE; } return FALSE;}/* EXPORT->GetConfBool: return Boolean parameter with given name */Boolean GetConfBool(ConfParam **list,int size,char *name, Boolean *b){ int i; if ((i = FindConfParm(list,size,name,BoolCKind)) != -1){ *b = list[i]->val.b; return TRUE; } return FALSE;}/* EXPORT->GetConfInt: return integer parameter with given name */Boolean GetConfInt(ConfParam **list,int size,char *name, int *ival){ int i; if ((i = FindConfParm(list,size,name,IntCKind)) != -1){ *ival = list[i]->val.i; return TRUE; } return FALSE;}/* EXPORT->GetConfFlt: return float parameter with given name */Boolean GetConfFlt(ConfParam **list,int size,char *name, double *fval){ int i; if ((i = FindConfParm(list,size,name,FltCKind)) != -1){ *fval = (list[i]->kind==FltCKind)?list[i]->val.f:list[i]->val.i; return TRUE; } return FALSE;}/* ------------------ Argument Processing -------------------- *//* Arguments are processed in sequence by calls to Getxxx(). The enum type ArgKind is used to indicate the kind of the next argument SWITCHARG - any str starting with '-' char FLOATARG - any str which is a valid number and contains a '.' INTARG - any str which is a valid number and is not a FLOATARG STRINGARG - any str in double quotes or not one of the above NOARG - returned when all arguments processed Each of the Getxxx() functions will return value of next arg in form specified by xxx, an error is reported if next arg is not of the required type except that an int will be converted to a float if requested. The list of args is actually a copy from which the standard HShell options -C and -S have been removed. If a script file is set, then the contents of the script file are effectively appended to the command line. However, the actual strings returned for args in the script are volatile and should be copied by the host program where necessary.*/static int argcount; /* total args = argc */static int nextarg=1; /* next arg to return in GetxxxArg */static char *defargs[2]={ "<Uninitialised>", "" };static char **arglist=defargs;/* actual arg list */static FILE *script = NULL; /* script file if any */static int scriptcount = 0; /* num words in script */static char scriptBuf[256]; /* buffer for current script arg */static Boolean scriptBufLoaded = FALSE;static Boolean wasQuoted; /* true if next arg was quoted */static ConfParam *cParm[MAXGLOBS]; /* config parameters */static int nParm = 0;/* ScriptWord: return next word from script */static char * ScriptWord(void){ int ch,qch,i; i=0; ch=' '; while (isspace(ch)) ch = fgetc(script); if (ch==EOF) return NULL; if (ch=='\'' || ch=='"'){ qch = ch; ch = fgetc(script); while (ch != qch && ch != EOF) { scriptBuf[i++] = ch; /* #### ge: should check for overflow of scriptBuf */ ch = fgetc(script); } if (ch==EOF) HError(5051,"ScriptWord: Closing quote missing in script file"); wasQuoted = TRUE; } else { do { scriptBuf[i++] = ch; ch = fgetc(script); }while (!isspace(ch) && ch != EOF); wasQuoted = FALSE; } scriptBuf[i] = '\0'; scriptBufLoaded = TRUE; return scriptBuf;} /* GetNextArg: from either command line or script file */static char * GetNextArg(Boolean step){ char *s; if (argcount>nextarg){ s = arglist[nextarg]; wasQuoted = FALSE; } else if (scriptBufLoaded) s = scriptBuf; else s = ScriptWord(); if (step) { ++nextarg; scriptBufLoaded = FALSE; } return s;}/* EXPORT->NumArgs: Number of actual cmd line arguments left unprocessed */int NumArgs(void){ return argcount+scriptcount-nextarg;}/* EXPORT->NextArg: Kind of next argument */ArgKind NextArg(void){ char *s,*p; if (NumArgs() == 0) return NOARG; s = GetNextArg(FALSE); if (wasQuoted) return STRINGARG; if (NumHead(s)){ strtod(s,&p); if (p==NULL || *p == '\0'){ if (strchr(s,'.') == NULL) return INTARG; else return FLOATARG; } } if (*s=='-') return SWITCHARG; return STRINGARG;}/* ArgError: called when next arg is different to requested arg or no more args are left */static void ArgError(char *s){ if (NextArg()==NOARG) HError(5020,"ArgError: %s arg requested but no args left",s); else HError(5021,"ArgError: %s arg requested but next is %s",s,GetNextArg(FALSE));}/* EXPORT->GetStrArg: get string arg */char * GetStrArg(void){ char *s; if (NextArg() != STRINGARG) ArgError("String"); s = GetNextArg (TRUE); if (extendedFileNames) s = RegisterExtFileName (s); return s;} /* EXPORT->GetSwtArg: get switch arg */char * GetSwtArg(void){ if (NextArg() != SWITCHARG) ArgError("Switch"); return GetNextArg(TRUE)+1;}/* EXPORT->GetIntArg: get int arg */int GetIntArg(void){ int i; char *s; if (NextArg() != INTARG) ArgError("Int"); s = GetNextArg(TRUE); if (sscanf(s,"%i",&i) !=1) HError(5090,"GetIntArg: Integer Argument %s",s); return i;}/* EXPORT->GetLongArg: get long arg */long GetLongArg(void){ long i; char *s; if (NextArg() != INTARG) ArgError("int"); s = GetNextArg(TRUE); if (sscanf(s,"%li",&i) !=1) HError(5090,"GetLongArg: Integer Argument %s",s); return i;}/* EXPORT->GetFltArg: get float arg */float GetFltArg(void){ int k = NextArg(); if (k != INTARG && k != FLOATARG) ArgError("Float"); return atof(GetNextArg(TRUE));}/* EXPORT->GetChkedInt: range checked version of GetIntArg */int GetChkedInt(int min, int max, char * swtname){ int val; if (NextArg() != INTARG) HError(5021,"GetChkedInt: Integer Arg Required for %s option",swtname); val=GetIntArg(); if (val<min || val>max) HError(5022,"GetChkedInt: Integer arg out of range in %s option",swtname); return val;}/* EXPORT->GetChkedLong: range checked version of GetIntArg */long GetChkedLong(long min, long max, char * swtname){ long val; if (NextArg() != INTARG) HError(5021,"GetChkedLong: Integer Arg Required for %s option",swtname); val=GetLongArg(); if (val<min || val>max) HError(5022,"GetChkedLong: Long arg out of range in %s option",swtname); return val;}/* EXPORT->GetChkedFlt: range checked version of GetFltArg */float GetChkedFlt(float min, float max, char * swtname){ float val; if (NextArg() != INTARG && NextArg() != FLOATARG) HError(5021,"GetChkedFlt: Float Arg Required for %s option",swtname); val=GetFltArg(); if (val<min || val>max) HError(5022,"GetChkedFlt: Float arg out of range in %s option",swtname); return val;}/* EXPORT->GetIntEnvVar: get integer environment variable */Boolean GetIntEnvVar(char *envVar, int *value){ char *env; if ((env = getenv(envVar)) == NULL) return FALSE; *value = atoi(env); return TRUE;}static char *CheckFn(char *fn);/* SetScriptFile: open script file and count words in it */ReturnStatus SetScriptFile(char *fn){ CheckFn(fn); if ((script = fopen(fn,"r")) == NULL){ /* Don't care if text/binary */ HRError(5010,"SetScriptFile: Cannot open script file %s",fn); return(FAIL); } while (ScriptWord() != NULL) ++scriptcount; rewind(script); scriptBufLoaded = FALSE; return(SUCCESS);}/* -------------------- Input Files/Pipes -------------------- */static char *filtermap[] = { "HWAVEFILTER", "HPARMFILTER", "HLANGMODFILTER", "HMMLISTFILTER", "HMMDEFFILTER", "HLABELFILTER", "HNETFILTER", "HDICTFILTER", "LGRAMFILTER", "LWMAPFILTER", "LCMAPFILTER", "LMTEXTFILTER", "HNOFILTER", "HWAVEOFILTER", "HPARMOFILTER", "HLANGMODOFILTER", "HMMLISTOFILTER", "HMMDEFOFILTER", "HLABELOFILTER", "HNETOFILTER", "HDICTOFILTER", "LGRAMOFILTER", "LWMAPOFILTER", "LCMAPOFILTER", "HNOOFILTER"};/* FilterSet: returns true and puts filter cmd in s if configuration parameter or environment variable set */static Boolean FilterSet(IOFilter filter, char *s){ char *env; if ((env = getenv(filtermap[filter])) != NULL){ strcpy(s,env); return TRUE; } else if (GetConfStr(cParm,nParm,filtermap[filter],s)) return TRUE; else return FALSE;}/* EXPORT->SubstFName: subst fname for $, if any, in s */void SubstFName(char *fname, char *s){ char *p; char buf[1028]; while ((p=strchr(s,'$')) != NULL){ *p = '\0'; ++p; strcpy(buf,s); strcat(buf,fname); strcat(buf,p); strcpy(s,buf); }}static int maxTry = 1;#ifdef WIN32#define popen _popen#define pclose _pclose#endif/* EXPORT->FOpen: return either a file or a pipe */FILE *FOpen(char *fname, IOFilter filter, Boolean *isPipe){ FILE *f; int i; Boolean isInput; char mode[8],cmd[1028]; if (filter <= NoFilter){ /* then input */ isInput = TRUE; strcpy(mode,"r"); /* May be binary */ } else { isInput = FALSE; strcpy(mode,"w"); /* May be binary */ } #ifndef NOPIPES if (FilterSet(filter,cmd)){ SubstFName(fname,cmd); f = (FILE *)popen(cmd,mode); *isPipe = TRUE; if (trace&T_IOP) printf("HShell: FOpen - file %s %s pipe %s\n", fname,isInput?"<-":"->",cmd); return f; }#endif *isPipe = FALSE; strcat(mode,"b"); for (i=1; i<=maxTry; i++){ f = fopen(fname,mode); if (f!=NULL) return f;#ifdef UNIX if (i<maxTry) sleep(5);#endif if (trace&T_IOP) printf("HShell: FOpen - try %d failed on %s in mode %s\n", i,fname,mode); } return NULL;}/* EXPORT->FClose: close the given file or pipe */void FClose(FILE *f, Boolean isPipe){#ifndef NOPIPES if (isPipe){ pclose(f); return; }#endif if (fclose(f) != 0) HError (5010, "FClose: closing file failed");}/* EXPORT->InitSource: initialise a source */ReturnStatus InitSource(char *fname, Source *src, IOFilter filter){ CheckFn(fname); strcpy(src->name,fname); if ((src->f = FOpen(fname, filter, &(src->isPipe))) == NULL){ HRError(5010,"InitSource: Cannot open source file %s",fname); return(FAIL); } src->pbValid = FALSE; src->chcount = 0; return(SUCCESS);}/* EXPORT->AttachSource: attach a source to a file */void AttachSource(FILE *file, Source *src){ src->f=file; strcpy(src->name,"attachment"); src->isPipe=TRUE; src->pbValid = FALSE; src->chcount = 0;}/* EXPORT->CloseSource: close a source */void CloseSource(Source *src){ FClose(src->f,src->isPipe);}/* EXPORT->SrcPosition: return string giving position in src */char *SrcPosition(Source src, char *s){ int i,line,col,c; long pos; if (src.isPipe || src.chcount>100000) sprintf(s,"char %d in %s",src.chcount,src.name); else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -