📄 ckucmd.c
字号:
cmp_c[cmddep][2] = np;#endif /* DCMDBUF */ /* Now the buffers themselves. A lot of repititious code... */#ifdef DCMDBUF cp = malloc((int)strlen(cmdbuf)+1); /* 0: Command buffer */ if (cp) strcpy(cp,cmdbuf); cmp[cmddep].b[0] = cp; if (cp == NULL) return(-1); cp = malloc((int)strlen(savbuf)+1); /* 1: Save buffer */ if (cp) strcpy(cp,savbuf); cmp[cmddep].b[1] = cp; if (cp == NULL) return(-1);#ifdef OLDHELP cp = malloc((int)strlen(hlpbuf)+1); /* 2: Help string buffer */ if (cp) strcpy(cp,hlpbuf); cmp[cmddep].b[2] = cp; if (cp == NULL) return(-1);#else cmp[cmddep].b[2] = NULL;#endif /* OLDHELP */ cp = malloc((int)strlen(atmbuf)+1); /* 3: Atom buffer */ if (cp) strcpy(cp,atmbuf); cmp[cmddep].b[3] = cp; if (cp == NULL) return(-1); cp = malloc((int)strlen(atxbuf)+1); /* 4: Expansion buffer */ if (cp) strcpy(cp,atxbuf); cmp[cmddep].b[4] = cp; if (cp == NULL) return(-1); cp = malloc((int)strlen(atybuf)+1); /* 5: Atom buffer copy */ if (cp) strcpy(cp,atybuf); cmp[cmddep].b[5] = cp; if (cp == NULL) return(-1); cp = malloc((int)strlen(filbuf)+1); /* 6: File name buffer */ if (cp) strcpy(cp,filbuf); cmp[cmddep].b[6] = cp; if (cp == NULL) return(-1);#else cp = malloc((int)strlen(cmdbuf)+1); /* 0: Command buffer */ if (cp) strcpy(cp,cmdbuf); cmp_b[cmddep][0] = cp; if (cp == NULL) return(-1); cp = malloc((int)strlen(savbuf)+1); /* 1: Save buffer */ if (cp) strcpy(cp,savbuf); cmp_b[cmddep][1] = cp; if (cp == NULL) return(-1);#ifdef OLDHELP cp = malloc((int)strlen(hlpbuf)+1); /* 2: Help string buffer */ if (cp) strcpy(cp,hlpbuf); cmp_b[cmddep][2] = cp; if (cp == NULL) return(-1);#else cmp_b[cmddep][2] = NULL;#endif /* OLDHELP */ cp = malloc((int)strlen(atmbuf)+1); /* 3: Atom buffer */ if (cp) strcpy(cp,atmbuf); cmp_b[cmddep][3] = cp; if (cp == NULL) return(-1); cp = malloc((int)strlen(atxbuf)+1); /* 4: Expansion buffer */ if (cp) strcpy(cp,atxbuf); cmp_b[cmddep][4] = cp; if (cp == NULL) return(-1); cp = malloc((int)strlen(atybuf)+1); /* 5: Atom buffer copy */ if (cp) strcpy(cp,atybuf); cmp_b[cmddep][5] = cp; if (cp == NULL) return(-1); cp = malloc((int)strlen(filbuf)+1); /* 6: File name buffer */ if (cp) strcpy(cp,filbuf); cmp_b[cmddep][6] = cp; if (cp == NULL) return(-1);#endif /* DCMDBUF */ cmini(dpx); /* Initize the command parser */ return(0);}intcmpop() { /* Restore the command environment */ debug(F101,"&cmpop","",cmddep); if (cmddep < 0) return(-1); /* Don't pop too much! */#ifdef DCMDBUF cmflgs = cmp[cmddep].i[0]; /* First do the global ints */ cmfsav = cmp[cmddep].i[1]; atxn = cmp[cmddep].i[2]; ungw = cmp[cmddep].i[3]; bp = cmp[cmddep].c[0]; /* Then the global pointers */ pp = cmp[cmddep].c[1]; np = cmp[cmddep].c[2];#else cmflgs = cmp_i[cmddep][0]; /* First do the global ints */ cmfsav = cmp_i[cmddep][1]; atxn = cmp_i[cmddep][2]; ungw = cmp_i[cmddep][3]; bp = cmp_c[cmddep][0]; /* Then the global pointers */ pp = cmp_c[cmddep][1]; np = cmp_c[cmddep][2];#endif /* DCMDBUF */ /* Now the buffers themselves. */ /* Note: strncpy(), not ckstrncpy() -- Here we WANT the NUL padding... */#ifdef DCMDBUF if (cmp[cmddep].b[0]) { strncpy(cmdbuf,cmp[cmddep].b[0],CMDBL); /* 0: Command buffer */ free(cmp[cmddep].b[0]); cmp[cmddep].b[0] = NULL; } if (cmp[cmddep].b[1]) { strncpy(savbuf,cmp[cmddep].b[1],CMDBL); /* 1: Save buffer */ free(cmp[cmddep].b[1]); cmp[cmddep].b[1] = NULL; }#ifdef OLDHELP if (cmp[cmddep].b[2]) { strncpy(hlpbuf,cmp[cmddep].b[2],HLPBL); /* 2: Help buffer */ free(cmp[cmddep].b[2]); cmp[cmddep].b[2] = NULL; }#endif /* OLDHELP */ if (cmp[cmddep].b[3]) { strncpy(atmbuf,cmp[cmddep].b[3],ATMBL); /* 3: Atomic buffer! */ free(cmp[cmddep].b[3]); cmp[cmddep].b[3] = NULL; } if (cmp[cmddep].b[4]) { strncpy(atxbuf,cmp[cmddep].b[4],ATMBL); /* 4: eXpansion buffer */ free(cmp[cmddep].b[4]); cmp[cmddep].b[4] = NULL; } if (cmp[cmddep].b[5]) { strncpy(atybuf,cmp[cmddep].b[5],ATMBL); /* 5: Atom buffer copY */ free(cmp[cmddep].b[5]); cmp[cmddep].b[5] = NULL; } if (cmp[cmddep].b[6]) { strncpy(filbuf,cmp[cmddep].b[6],ATMBL); /* 6: Filename buffer */ free(cmp[cmddep].b[6]); cmp[cmddep].b[6] = NULL; }#else if (cmp_b[cmddep][0]) { strncpy(cmdbuf,cmp_b[cmddep][0],CMDBL); /* 0: Command buffer */ free(cmp_b[cmddep][0]); cmp_b[cmddep][0] = NULL; } if (cmp_b[cmddep][1]) { strncpy(savbuf,cmp_b[cmddep][1],CMDBL); /* 1: Save buffer */ free(cmp_b[cmddep][1]); cmp_b[cmddep][1] = NULL; }#ifdef OLDHELP if (cmp_b[cmddep][2]) { strncpy(hlpbuf,cmp_b[cmddep][2],HLPBL); /* 2: Help buffer */ free(cmp_b[cmddep][2]); cmp_b[cmddep][2] = NULL; }#endif /* OLDHELP */ if (cmp_b[cmddep][3]) { strncpy(atmbuf,cmp_b[cmddep][3],ATMBL); /* 3: Atomic buffer! */ free(cmp_b[cmddep][3]); cmp_b[cmddep][3] = NULL; } if (cmp_b[cmddep][4]) { strncpy(atxbuf,cmp_b[cmddep][4],ATMBL); /* 4: eXpansion buffer */ free(cmp_b[cmddep][4]); cmp_b[cmddep][4] = NULL; } if (cmp_b[cmddep][5]) { strncpy(atybuf,cmp_b[cmddep][5],ATMBL); /* 5: Atom buffer copY */ free(cmp_b[cmddep][5]); cmp_b[cmddep][5] = NULL; } if (cmp_b[cmddep][6]) { strncpy(filbuf,cmp_b[cmddep][6],ATMBL); /* 6: Filename buffer */ free(cmp_b[cmddep][6]); cmp_b[cmddep][6] = NULL; }#endif /* DCMDBUF */ cmddep--; /* Rise, rise */ debug(F101,"&cmpop","",cmddep); return(cmddep);}#endif /* NOSPL */#ifdef COMMENTVOIDstripq(s) char *s; { /* Function to strip '\' quotes */ char *t; while (*s) { if (*s == CMDQ) { for (t = s; *t != '\0'; t++) *t = *(t+1); } s++; }}#endif /* COMMENT *//* Convert tabs to spaces, one for one */VOIDuntab(s) char *s; { while (*s) { if (*s == HT) *s = SP; s++; }}/* C M N U M -- Parse a number in the indicated radix *//* The only radix allowed in unquoted numbers is 10. Parses unquoted numeric strings in base 10. Parses backslash-quoted numbers in the radix indicated by the quote: \nnn = \dnnn = decimal, \onnn = octal, \xnn = Hexadecimal. If these fail, then if a preprocessing function is supplied, that is applied and then a second attempt is made to parse an unquoted decimal string. And if that fails, the preprocessed string is passed to an arithmetic expression evaluator. Returns: -3 if no input present when required, -2 if user typed an illegal number, -1 if reparse needed, 0 otherwise, with argument n set to the number that was parsed*/intcmnum(xhlp,xdef,radix,n,f) char *xhlp, *xdef; int radix, *n; xx_strp f; { int x; char *s, *zp, *zq; char lbrace, rbrace; if (!xhlp) xhlp = ""; if (!xdef) xdef = ""; if (cmfldflgs & 1) { lbrace = '('; rbrace = ')'; } else { lbrace = '{'; rbrace = '}'; } if (radix != 10) { /* Just do base 10 */ printf("cmnum: illegal radix - %d\n",radix); return(-1); } /* Easy to add others but there has never been a need for it. */ x = cmfld(xhlp,xdef,&s,(xx_strp)0); debug(F101,"cmnum: cmfld","",x); if (x < 0) return(x); /* Parse a field */ zp = atmbuf;/* Edit 192 - Allow any number field to be braced. This lets us include spaces in expressions, but perhaps more important lets us have user-defined functions in numeric fields.*/ if (*zp == lbrace) { /* Braced field, strip braces */ x = (int) strlen(atmbuf); if (x > 0) { /* The "if" is to shut up optimizers */ if (*(atmbuf+x-1) == rbrace) { *(atmbuf+x-1) = NUL; /* that complain about a possible */ zp++; /* reference to atbmbuf[-1] even */ } } /* though we know that x > 0. */ } if (chknum(zp)) { /* Check for decimal number */ *n = atoi(zp); /* Got one, we're done. */ debug(F101,"cmnum 1st chknum ok","",*n); return(0); } else if ((x = xxesc(&zp)) > -1) { /* Check for backslash escape */#ifndef OS2 *n = x;#else *n = wideresult;#endif /* OS2 */ debug(F101,"cmnum xxesc ok","",*n); return(*zp ? -2 : 0); } else if (f) { /* If conversion function given */ zq = atxbuf; /* Try that */ atxn = CMDBL; if ((*f)(zp,&zq,&atxn) < 0) /* Convert */ return(-2); zp = atxbuf; } debug(F110,"cmnum zp 1",zp,0); if (!*zp) zp = xdef; /* Result empty, substitute default */ debug(F110,"cmnum zp 2",zp,0); if (chknum(zp)) { /* Check again for decimal number */ *n = atoi(zp); /* Got one, we're done. */ debug(F101,"cmnum 2nd chknum ok","",*n); return(0);#ifndef NOSPL } else if ((x = xxesc(&zp)) > -1) { /* Check for backslash escape */#ifndef OS2 *n = x;#else *n = wideresult;#endif /* OS2 */ debug(F101,"cmnum xxesc 2 ok","",*n); return(*zp ? -2 : 0); } else if (f) { /* Not numeric, maybe an expression */ char * p; p = evala(zp); if (chknum(p)) { *n = atoi(p); debug(F101,"cmnum exp eval ok","",*n); return(0); } else return(-2);#endif /* NOSPL */ } else { /* Not numeric */ return(-2); }}#ifdef CKCHANNELIOextern int z_error;#endif /* CKCHANNELIO *//* C M O F I -- Parse the name of an output file *//* Depends on the external function zchko(); if zchko() not available, use cmfld() to parse output file names. Returns: -9 like -2, except message already printed, -3 if no input present when required, -2 if permission would be denied to create the file, -1 if reparse needed, 0 or 1 if file can be created, with xp pointing to name. 2 if given the name of an existing directory.*/intcmofi(xhlp,xdef,xp,f) char *xhlp, *xdef, **xp; xx_strp f; { int x; char *s, *zq;#ifdef DOCHKVAR int tries;#endif /* DOCHKVAR */#ifdef DTILDE char *dirp;#endif /* DTILDE */ cmfldflgs = 0; if (!xhlp) xhlp = ""; if (!xdef) xdef = ""; if (*xhlp == NUL) xhlp = "Output file"; *xp = ""; x = cmfld(xhlp,xdef,&s,(xx_strp)0); debug(F111,"cmofi cmfld returns",s,x); if (x < 0) return(x); if (*s == '{') { /* Strip enclosing braces */ int n; n = strlen(s); if (s[n-1] == '}') { s[n-1] = NUL; s++; } } debug(F110,"cmofi 1.5",s,0);#ifdef DOCHKVAR tries = 0; { char *p = s; /* This is really ugly. If we skip conversion the first time through, then variable names like \%a will be used as filenames (e.g. creating a file called %A in the root directory). If we DON'T skip conversion the first time through, then single backslashes used as directory separators in filenames will be misinterpreted as variable lead-ins. So we prescan to see if it has any variable references. But this module is not supposed to know anything about variables, functions, etc, so this code does not really belong here, but rather it should be at the same level as zzstring(). *//* Hmmm, this looks a lot like chkvar() except it that includes \nnn number escapes. But why? This makes commands like "mkdir c:\123" impossible. And in fact, "mkdir c:\123" creates a directory called "c:{". What's worse, rmdir(), which *does* call chkvar(), won't let us remove it. So let's at least try making cmofi() symmetrical with cmifi()...*/#ifdef COMMENT char * q; while ( (tries == 0) && (p = strchr(p,CMDQ)) ) { q = *(p+1); /* Char after backslash */ if (!q) /* None, quit */ break; if (isupper(q)) /* If letter, convert to lowercase */ q = tolower(q); if (isdigit(q)) { /* If it's a digit, */ tries = 1; /* assume it's a backslash code */ break; } switch (q) { case CMDQ: /* Double backslash */ tries = 1; /* so call the conversion function */ break; case '%': /* Variable or array reference */ case '&': /* must be followed by letter */ if (isalpha(*(p+2)) || (*(p+2) >= '0' && *(p+2) <= '9')) tries = 1; break; case 'm': case 'v': case '$': /* \m(), \v(), \$() */ if (*(p+2) == '(') if (strchr(p+2,')')) tries = 1; break; case 'f': /* \Fname() */ if (strchr(p+2,'(')) if (strchr(p+2,')')) tries = 1; break; case '{': /* \{...} */ if (strchr(p+2,'}')) tries = 1; break; case 'd': case 'o': /* Decimal or Octal number */ if (isdigit(*(p+2))) tries = 1; break; case 'x': /* Hex number */ if (isdigit(*(p+2)) || ((*(p+2) >= 'a' && *(p+2) <= 'f') || ((*(p+2) >= 'A' && *(p+2) <= 'F')))) tries = 1; default: break; } p++; }#else#ifndef NOSPL if (f) { /* If a conversion function is given */ char *s = p; /* See if there are any variables in */ while (*s) { /* the string and if so, expand them */ if (chkvar(s)) { tries = 1; break; } s++; } }#endif /* NOSPL */#endif /* COMMENT */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -