/**************************************************************** * init_value: ****************************************************************/ static int init_value( /* Return: initial "processing" status */ struct cduValue *val /* <m> value structure */ ) { int sts; struct cduKeyword *key; sts = 0; if (!val) return(0); /*------------------------------------------------------- * Free any old values which might be attached ... *------------------------------------------------------*/ str_free1_dx(&val->val_dsc); val->valA_substring = 0; /*-------------------------------------------------------- * Init keywords ... *-------------------------------------------------------*/ if (key = val->valA_userType) { for ( ; key->keyA_name ; key++) key->keyL_status = init_value(key->keyA_value); } /*-------------------------------------------------------- * Check for default value. *-------------------------------------------------------*/ if (val->valA_default) { str_copy_dx(&val->val_dsc,val->valA_default); val->valA_substring = val->val_dsc.dscA_pointer; sts = CLI_STS_DEFAULTED; } return(sts); }
/**************************************************************** * mdsdcl_do_command: * Effectively, the main MDSDCL routine ... ****************************************************************/ int mdsdcl_do_command( void *command /* <r:opt> command -- cstring or dsc */ ) { int tblidx; int sts,stsParse; int tried_indirect = 0; struct _mdsdcl_io *io; static char doMacro[12]; static DYNAMIC_DESCRIPTOR(dsc_cmd); struct _mdsdcl_ctrl *ctrl = &MdsdclGetThreadStatic()->ctrl; #ifdef vms extern int MDSDCL$MSG_TO_RET(); extern int MDSDCL$OUT_OF_BAND_AST(); #endif /*--------------------------------------------------------------- * Executable: *--------------------------------------------------------------*/ LockMdsShrMutex(&mdsdclMutex,&mdsdclMutex_initialized); if (!ctrl->tbladr[0]) mdsdcl_initialize(ctrl); tblidx = ctrl->tables; if (!doMacro[0]) { /* first time ... */ sprintf(doMacro,"DO %cMACRO ",'/'); } io = ctrl->ioLevel + ctrl->depth; if (command) { str_trim(&io->last_command,command); str_copy_dx(&dsc_cmd,&io->last_command); mdsdcl_insert_symbols(io->ioParameter,&dsc_cmd); } else { str_free1_dx(&io->last_command); str_free1_dx(&dsc_cmd); } /*------------------------------------------------------- * Try each table in turn ... *------------------------------------------------------*/ for ( ; tblidx>0 ; tblidx--) { do { stsParse = mdsdcl_dcl_parse(&dsc_cmd,ctrl,tblidx); } while(stsParse == CLI_STS_NOCOMD); /* 25-Feb-03: ignore blank lines -- TRG */ if (~stsParse & 1) { if ((stsParse == CLI_STS_EOF) || (stsParse == CLI_STS_NOCOMD)) { UnlockMdsShrMutex(&mdsdclMutex); return(stsParse); } else if (stsParse == MDSDCL_STS_INDIRECT_EOF) { UnlockMdsShrMutex(&mdsdclMutex); return(stsParse); /*--------------------> return */ } } io = ctrl->ioLevel + ctrl->depth; if (!dsc_cmd.dscA_pointer) str_copy_dx(&dsc_cmd,&io->last_command); if (stsParse & 1) { /* Try to dispatch the routine ... */ sts = cli_dispatch(ctrl); if (sts != CLI_STS_INVROUT) { if (ctrl->verify && sts != 3) displayCmdline(dsc_cmd.dscA_pointer); if (~sts & 1) { if (dsc_cmd.dscA_pointer) MdsMsg(0,"--> failed on line '%s'", dsc_cmd.dscA_pointer); mdsdcl_close_indirect_all(); } UnlockMdsShrMutex(&mdsdclMutex); return(sts); /*--------------------> return */ } } } /*------------------------------------------------------- * Command not found in any table: try it as a macro ... *------------------------------------------------------*/ if (ctrl->verify) displayCmdline(dsc_cmd.dscA_pointer); tblidx = 1; /* i.e., the table for DO/MACRO */ str_prefix(&dsc_cmd,doMacro); sts = mdsdcl_dcl_parse(&dsc_cmd,ctrl,tblidx); if (sts & 1) { /* Try to dispatch the macro ... */ sts = cli_dispatch(ctrl); } else if (sts == CLI_STS_IVQUAL) { MdsMsg(0,"No such command"); /* CLI_STS_IVQUAL msg is suppressed * by cli_process_qualifier() */ } if (~sts & 1) mdsdcl_close_indirect_all(); UnlockMdsShrMutex(&mdsdclMutex); return(sts); /*--------------------> return */ }
/**************************************************************** * cli_get_value: ****************************************************************/ int cli_get_value( /* Return: status */ void *entity /* <r> entity name: dsc or c-string */ ,struct descriptor *dsc_ret /* <w> return value descriptor */ ) { int k; int sts; char entityString[128]; char *p,*p2; struct cduEntity *e; struct cduValue *val; static struct descriptor dsc_util = { 0,DSC_K_DTYPE_T,DSC_K_CLASS_S,0}; if (!currentSyntax) return(CLI_STS_IVREQTYP); make_entityString(entity,entityString,sizeof(entityString)); /*----------------------------------------------------- * Check for "special" entities ... *----------------------------------------------------*/ p = 0; if (!strcmp(entityString,"$LINE")) p = dsc_cmdline.dscA_pointer; else if (!strcmp(entityString,"$VERB")) p = currentSyntax->vrbA_name; if (p) { str_copy_dx(dsc_ret,p); return(1); /*------------> return: special */ } /*-------------------------------------------------------- * Find requested entity and return its value ... *-------------------------------------------------------*/ e = find_entity(entityString,(void *)currentParameters); if (!e) e=find_entity(entityString,(void *)currentQualifiers); if (!e || !e->entL_status) return(CLI_STS_ABSENT); val = e->entA_value; if (!val) return(CLI_STS_IVREQTYP); /* if (val->valL_flags & VAL_M_USER_DEFINED_TYPE) /* return(CLI_STS_IVREQTYP); /* */ if (!val->valA_substring) return(CLI_STS_ABSENT); /*------------------------------------------------ * Return 'value' string to caller ... *-----------------------------------------------*/ if (val->valL_flags & VAL_M_LIST) { p = val->valA_substring; p2 = strpbrk(p,"\01\02"); /* find delimter char */ k = p2 ? (p2-p) : strlen(p); dsc_util.dscW_length = k; dsc_util.dscA_pointer = p; sts = str_copy_dx(dsc_ret,&dsc_util); val->valA_substring = p2; } else { int slen=strlen(val->valA_substring)+1; int len=sizeof(struct descriptor)>slen?sizeof(struct descriptor):slen; char *tmp=strcpy(memset(malloc(len),0,len),val->valA_substring); sts = str_copy_dx(dsc_ret,tmp); free(tmp); val->valA_substring = 0; } #ifdef vms if (val->valL_flags & VAL_M_DELTATIME) { /* VMS deltatime only ... */ p = strchr(dsc_ret->dscA_pointer,'-'); if (p) *p = ' '; /*..replace '-' with blank */ p = dsc_ret->dscA_pointer; k = strlen(p); if (k < dsc_ret->dscW_length) memset(p+k,' ',dsc_ret->dscW_length - k); } #endif if (!val->valA_substring) return(1); /*-------------> return: Normal */ if (*val->valA_substring == '\01') /* "Comma" delimiter */ { val->valA_substring++; return(CLI_STS_COMMA); } if (*val->valA_substring == '\02') /* "Plus" delimiter */ { val->valA_substring++; return(CLI_STS_CONCAT); } return(cli_error(CLI_STS_BADLINE,"cli_get_value error ???")); }
/***************************************************************** * set_value: *****************************************************************/ static int set_value( /* Return: CLI_STS_xxxx */ char **pp /* <m> current location in cmd line */ ,struct cduValue *val /* <m> the value struct */ ) { int keycnt; int opt; int sts; char *p; struct cmd_struct *cmd; struct cduKeyword *key; static DYNAMIC_DESCRIPTOR(dsc_temp); if ((val->valL_flags & VAL_M_LIST) && **pp=='(') sts = readCliValueList(pp,val); else sts = cliToken(pp,&val->val_dsc,val->valL_flags); if (~sts & 1) return(cli_error(CLI_STS_BADLINE,"Invalid data in line")); val->valA_substring = val->val_dsc.dscA_pointer; /*======================================================= * Keywords ? *======================================================*/ if (!val->valA_userType) return(CLI_STS_PRESENT); /*--------------- Nope: return */ /*------------------------------------------------------- *...yes: check each input for keyword ... *------------------------------------------------------*/ cmd = make_lookup_keyword(val->valA_userType); p = val->val_dsc.dscA_pointer; str_free1_dx(&dsc_temp); keycnt = 0; for ( ; p ; keycnt++) { if (keycnt) { /* skip separator character */ if (*p=='\01' || *p=='\02') { str_append(&dsc_temp,(*p=='\01')?"\01":"\02"); p++; } else { fprintf(stderr,"Illegal separator character!\n"); #ifdef vms lib$signal(SS$_DEBUG); #endif } } opt = cmd_lookup(&p,cmd,0,NOMSG,0); if (opt) { key = val->valA_userType + (opt-1); key->keyL_status = CLI_STS_PRESENT; str_append(&dsc_temp,key->keyA_name); continue; /* back to top of loop ... */ } /*------------------------------------------------------- * Check for negated keyword ... *------------------------------------------------------*/ if (toupper(p[0])=='N' && toupper(p[1])=='O') { p += 2; opt = cmd_lookup(&p,cmd,0,NOMSG,0); if (opt) { key = val->valA_userType + (opt-1); if (!(key->keyL_flags & KEY_M_NEGATABLE)) { free(cmd); return(cli_error(CLI_STS_NOTNEGATABLE,"not negatable")); } key->keyL_status = CLI_STS_NEGATED; str_append(&dsc_temp,key->keyA_name); continue; /* back to top of loop ... */ } } free(cmd); return(CLI_STS_IVKEYW); /*---> return: Invalid keyword */ /* Note: this can be a legal sts. For example "DEFINE"'s * P2 might be the keyword "SERVER" or a macro name. * The latter would appear as an "invalid keyword". *------------------------------------------------------*/ } /*======================================================== * Ok -- all keywords were checked ... *=======================================================*/ free(cmd); str_copy_dx(&val->val_dsc,&dsc_temp); str_free1_dx(&dsc_temp); if (key->keyA_syntax) { if (keycnt == 1) { sts = key->keyL_status; /* save status */ setCurrentSyntax(FALSE,key->keyA_syntax); key->keyL_status = sts; } else fprintf(stderr,"Keyword syntax specified, but keycnt=%d\n", keycnt); } return((keycnt==1) ? key->keyL_status : CLI_STS_PRESENT); }
/*************************************************************** * cliToken: * Get token, as described by CLI flags ***************************************************************/ int cliToken( char **pp /* <m> addr of ptr to char string */ ,struct descriptor *dsc_ret /* <w> return token here */ ,int flags /* <r> cli flags, describing data type */ ) { int k; int sts; int typeflag; char c; char *p,*p2; char util[1024]; static char legalMdsChars[] = "0123456789._-:;*?%\\"; static struct descriptor dscUtil = { sizeof(util)-1,DSC_K_DTYPE_T,DSC_K_CLASS_S,0}; typeflag = flags & 0x0FFF; p = *pp = nonblank(*pp); if (!p) return(0); dscUtil.dscA_pointer = util; /* set addr in dscUtil descrip */ if (!typeflag || typeflag==VAL_M_QUOTED_STRING || typeflag==VAL_M_USER_DEFINED_TYPE) sts = ascToken(&p,&dscUtil,0,legalMdsChars); else if (typeflag == VAL_M_FILE) sts = ascFilename(&p,&dscUtil,0); else if (typeflag == VAL_M_NUMBER) { if (isdigit(*p) || (*p=='-' && isdigit(*(p+1)))) { sts = longToken(&p,&dscUtil,0,0); } else if (*p == '%') { c = toupper(*(p+1)); p2 = p + 2; /* first char of putative number */ if (c == 'X') { for ( ; isxdigit(*p2) ; p2++) ; } else if (c == 'O') { /* octal number ... */ for ( ; isdigit(*p2) && *p2<='7' ; p2++) ; } k = p2 - p; /* number of chars scanned */ if (k == 2) sts = 0; /*..invalid number */ else { if (k > dscUtil.dscW_length) k = dscUtil.dscW_length; strncpy(dscUtil.dscA_pointer,p,k); if (k < dscUtil.dscW_length) dscUtil.dscA_pointer[k] = '\0'; l2un(dscUtil.dscA_pointer,0,k); p = nonblank(p2); sts = CLI_STS_NORMAL; } } } else if (typeflag == VAL_M_DELTATIME) { sts = deltatimeToken(&p,&dscUtil,0,0); } else if (typeflag == VAL_M_REST_OF_LINE) { k = strlen(p); if (k > dscUtil.dscW_length) k = dscUtil.dscW_length; strncpy(dscUtil.dscA_pointer,p,k); if (k < dscUtil.dscW_length) dscUtil.dscA_pointer[k] = '\0'; p = 0; sts = CLI_STS_NORMAL; } else { printf("\n*ERR* cliToken can't handle typeflag %04X\n\n", typeflag); exit(0); } /*================================================ * Return to caller ... *===============================================*/ str_copy_dx(dsc_ret,&dscUtil); if (sts & 1) *pp = nonblank(p); return(sts); }
/**************************************************************** * mdsdcl_dcl_parse: *****************************************************************/ int mdsdcl_dcl_parse( /* Returns CLI_STS_xxx status */ void *command /* <r:opt> command string */ ,struct _mdsdcl_ctrl *ctrl /* <m> control structure */ ,int tabidx /* <r> cmd table idx, 1-based */ ) { int indirect_flag; int nbytes; int sts; char *p; struct _mdsdcl_io *io; struct descriptor *dsc; static char *cmd; /* addr of private cmd string */ static int maxcmd; /* current length of cmd[] */ static char doIndirect[16]; static DYNAMIC_DESCRIPTOR(dsc_filename); #ifdef vms extern mdsdcl$dcl_parse_handler(); #endif #ifdef vms if (tabidx > 1) lib$establish(lib$sig_to_ret); else lib$establish(mdsdcl$dcl_parse_handler); #endif if (!doIndirect[0]) { /* first time ... */ sprintf(doIndirect,"DO %cINDIRECT",QUALIFIER_CHARACTER); } /*------------------------------------------------------- * Copy optional "command" to cmd, checking for '@' ... *------------------------------------------------------*/ if (command && (is_cdescr(command) || is_ddescr(command))) { dsc = command; p = nonblank(dsc->dscA_pointer); } else p = nonblank(command); if (!p) { /* command string is null ... */ sts = cli_dcl_parse(0,ctrl->tbladr[tabidx-1], mdsdcl_get_input,mdsdcl_get_input,&ctrl->prompt); dsc = cli_addr_cmdline_dsc(); io = ctrl->ioLevel + ctrl->depth; str_copy_dx(&io->last_command,dsc); } else { /* else, p is start of command string ... */ nbytes = 0; if (indirect_flag = (*p == '@')) { p = nonblank(p+1); /* skip the '@' */ nbytes = sizeof(doIndirect) - 1; if (!ascFilename(&p,&dsc_filename,0)) return(MdsMsg(MDSDCL_STS_INDIRECT_ERROR, "Illegal filename: %s",p?p:"")); nbytes += strlen(dsc_filename.dscA_pointer) + 3; /* 2 quotes + blank */ } nbytes += p ? strlen(p) + 1 : 0; if (nbytes > maxcmd) { /*----- allocate enough space for cmd[] ------*/ maxcmd = (nbytes>79) ? nbytes : 79; if (cmd) free(cmd); cmd = malloc(maxcmd); if (!cmd) { fprintf(stderr,"mdsdcl_dcl_parse: Out of space!\n"); exit(0); } } if (indirect_flag) sprintf(cmd,"%s \"%s\" %s", doIndirect,dsc_filename.dscA_pointer,p?p:""); else strcpy(cmd,p?p:""); sts = cli_dcl_parse(cmd,ctrl->tbladr[tabidx-1], mdsdcl_get_input,mdsdcl_get_input,&ctrl->prompt); } return(sts); }