📄 ckuus5.c
字号:
tlevel = 0; if (tfnam[tlevel] = malloc(strlen(line)+1)) strcpy(tfnam[tlevel],line);#ifndef NOSPL cmdlvl++; ifcmd[cmdlvl] = 0; iftest[cmdlvl] = 0; count[cmdlvl] = 0; debug(F101,"open ok","",cmdlvl); cmdstk[cmdlvl].src = CMD_TF; cmdstk[cmdlvl].lvl = tlevel;#endif /* NOSPL */ debug(F110,"init file",line,0); } if (homdir && (tlevel < 0)) { strcpy(lp,kermrc); if ((tfile[0] = fopen(line,"r")) != NULL) { tlevel = 0; if (tfnam[tlevel] = malloc(strlen(line)+1)) strcpy(tfnam[tlevel],line);#ifndef NOSPL cmdlvl++; cmdstk[cmdlvl].src = CMD_TF; cmdstk[cmdlvl].lvl = tlevel; ifcmd[cmdlvl] = 0; iftest[cmdlvl] = 0; count[cmdlvl] = 0;#endif /* NOSPL */ } }#endif /* OS2 */#ifdef AMIGA reqpop(); /* Restore requestors */#endif /* AMIGA */}#ifndef NOSPL/* G E T N C M Get next command from current macro definition. Moved to a separate routine in edit 181 to allow multiline GET to work when issued in a macro. Command is copied into string pointed to by argument s, max length n. Returns: 0 if a string was copied, -1 if there was no string to copy.*/intgetncm(s,n) char *s; int n; { int y, kp = 0, pp = 0; char *s2; s2 = s; *s = NUL; /* Copy next cmd to command buffer. */ debug(F111,"getncm",s,n); for (y = 0; macp[maclvl] && *macp[maclvl] && y < n; y++, s++, macp[maclvl]++) { *s = *macp[maclvl]; /* Get next character */ debug(F000,"char","",*s);/* Allow braces around macro definition to prevent commas from being turned to end-of-lines and also treat any commas within parens as text so that multiple-argument functions won't cause the command to break prematurely.*/ if (*s == '{') kp++; /* Count braces */ if (*s == '}') kp--; if (*s == '(') pp++; /* Count parentheses. */ if (*s == ')') pp--; if (*s == ',' && pp <= 0 && kp <= 0) { macp[maclvl]++; debug(F110,"next cmd",s,0); kp = pp = 0; break; } } /* Reached end. */ if (*s2 == NUL) { /* If nothing was copied, */ debug(F100,"getncm eom","",0); popclvl(); /* pop command level. */ return(-1); } else { /* otherwise, tack CR onto end */ *s++ = CR; *s = '\0'; if (mecho && pflag) printf("%s\n",s2); debug(F101,"getncm returns ptr to",s2,0); } return(0);}#endif /* NOSPL *//* G E T N C T Get next command from current TAKE file. Moved to a separate routine in edit 181 to allow multiline GET to work when issued in a macro. Command is copied into string pointed to by argument s, max length n. Returns: 0 if a string was copied, -1 on EOF, -2 on malloc failure -3 if line not properly terminated*/intgetnct(s,n) char *s; int n; { int i, j; char c, *s2, *lp, *lp2; s2 = s; /* Remember original pointer */ debug(F101,"getnct","",n); if (!(lp2 = (char *) malloc(n+1))) { /* Get a temporary buffer */ debug(F101,"getnct malloc failure","",0); return(-2); } lp = lp2; /* Make a working pointer */ /* (lp2 must not change!) */ while (1) { /* Loop to read lines from file */ if (fgets(lp2,n,tfile[tlevel]) == NULL) { /* EOF */ free(lp2); /* Free temporary storage */ *s = NUL; /* Make destination be empty */ return(-1); /* Return failure code */ } debug(F110,"Line from TAKE file",lp2,0); /* Got a line */ if (techo && pflag) /* If TAKE ECHO ON, */ printf("%s",lp2); /* echo it. */ lp = lp2; /* Make a working pointer *//* Trim trailing whitespace */ j = strlen(lp2) - 1; /* Position of line terminator */ if (j < 0) j = 0; c = lp2[j]; /* Value of line terminator */ if (c < LF || c > CR) { /* It's not a terminator */ debug(F111,"getnct bad line",lp2,c); if (feof(tfile[tlevel]) && j > 0 && j < n) { printf("Warning: Last line of TAKE file lacks terminator\n"); c = lp2[++j] = '\n'; } else return(-3); } for (i = j - 1; i > -1; i--) /* Back up over spaces and tabs */ if (lp2[i] != SP && lp2[i] != HT && lp2[i] != NUL) break; lp2[i+1] = c; /* Move after last nonblank char */ lp2[i+2] = NUL; /* Terminate the string */ while (*s++ = *lp++) { /* Copy result to target buffer */ if (--n < 2) { printf("?Command too long, maximum length: %d.\n",CMDBL); free(lp2); return(dostop()); }/* Check for trailing comment, " ;" or " #" */ if ((s > s2 + 1) && (*(s-1) == ';' || *(s-1) == '#') && (*(s-2) == SP || *(s-2) == HT)) { debug(F100,"Trailing comment","",0); s -= 2; /* Got one, back up buffer pointer */ n += 2; /* and adjust free space count. */ while ((s >= s2) /* Trim whitespace again. */ && (*s == SP || *s == HT)) s--, n++; s++; /* Point after last character */ *s++ = c; /* Put back line terminator */ *s++ = NUL; /* and string terminator */ n -= 3; /* Adjust free count */ debug(F110,"Comment trimmed & terminated",s2,0); break; } }/* Check whether this line is continued */ debug(F000,"Last char in line","",*(s-3)); if (*(s - 3) != CMDQ && *(s - 3) != '-') /* Line continued? */ break; /* No, done. */ s -= 3; /* No, back up pointer */ debug(F100,"Got continue char","",0); /* and continue */ } untab(s2); /* Done, convert tabs to spaces */ free(lp2); /* Free temporary storage */ return(0); /* Return success */}/* P A R S E R -- Top-level interactive command parser. */ /* Call with: m = 0 for normal behavior: keep parsing and executing commands until an action command is parsed, then return with a Kermit start-state as the value of this function. m = 1 to parse only one command, can also be used to call parser() recursively. m = 2 to read but do not execute one command. In all cases, parser() returns: 0 if no Kermit protocol action required > 0 with a Kermit protocol start-state. < 0 upon error.*/intparser(m) int m; { int tfcode, xx, yy, zz; /* Workers */#ifndef NOSPL int inlevel; /* Level we were called at */#endif /* NOSPL */ char *cbp; /* Command buffer pointer */#ifdef MAC extern char *lfiles; /* Fake extern cast */#endif /* MAC */#ifdef AMIGA reqres(); /* restore AmigaDOS requestors */#endif /* AMIGA */ what = W_COMMAND; /* Now we're parsing commands. */#ifndef NOSPL if (cmdlvl == 0) /* If at top (interactive) level, */#else if (tlevel < 0)#endif /* NOSPL */ concb((char)escape); /* put console in cbreak mode. */#ifndef NOSPL ifcmd[0] = 0; /* Command-level related variables */ iftest[0] = 0; /* initialize variables at top level */ count[0] = 0; /* of stack... */ inlevel = cmdlvl; /* Current macro level */ debug(F101,"&parser entry maclvl","",maclvl); debug(F101,"&parser entry inlevel","",inlevel); debug(F101,"&parser entry tlevel","",tlevel); debug(F101,"&parser entry cmdlvl","",cmdlvl); debug(F101,"&parser entry m","",m);#endif /* NOSPL *//* sstate becomes nonzero when a command has been parsed that requires some action from the protocol module. Any non-protocol actions, such as local directory listing or terminal emulation, are invoked directly from below.*/#ifdef COMMENT if (local && pflag) /* Just returned from connect? */ printf("\n");#endif /* COMMENT */ sstate = 0; /* Start with no start state. */#ifndef NOFRILLS rmailf = rprintf = 0; /* MAIL and PRINT modifiers for SEND */ *optbuf = NUL; /* MAIL and PRINT options */#endif /* NOFRILLS */ while (sstate == 0) { /* Parse cmds until action requested */ debug(F100,"top of parse loop","",0); /* Take requested action if there was an error in the previous command */#ifndef MAC conint(trap,stptrap); /* In case we were just fg'd */ bgchk(); /* Check background status */#endif /* MAC */ debug(F101,"tlevel","",tlevel);#ifndef NOSPL /* In case we just reached top level */ debug(F101,"cmdlvl","",cmdlvl); if (cmdlvl == 0) concb((char)escape);#else if (tlevel < 0) concb((char)escape);#endif /* NOSPL */#ifndef NOSPL if (success == 0) { if (cmdstk[cmdlvl].src == CMD_TF && terror) { printf("Command error: take file terminated.\n"); popclvl(); if (cmdlvl == 0) return(0); } if (cmdstk[cmdlvl].src == CMD_MD && merror) { printf("Command error: macro terminated.\n"); popclvl(); if (m && (cmdlvl < inlevel)) return((int) sstate); } } nulcmd = (m == 2);#else if (success == 0 && tlevel > -1 && terror) { printf("Command error: take file terminated.\n"); popclvl(); cmini(ckxech); /* Clear the cmd buffer. */ if (tlevel < 0) /* Just popped out of cmd files? */ return(0); /* End of init file or whatever. */ }#endif /* NOSPL */#ifdef MAC /* Check for TAKE initiated by menu. */ if ((tlevel == -1) && lfiles) startlfile();#endif /* MAC */ /* If in TAKE file, check for EOF */#ifndef NOSPL#ifdef MAC if#else while#endif /* MAC */ ((cmdstk[cmdlvl].src == CMD_TF) /* If end of take file */ && (tlevel > -1) && feof(tfile[tlevel])) { popclvl(); /* pop command level */ cmini(ckxech); /* and clear the cmd buffer. */ if (cmdlvl == 0) /* Just popped out of all cmd files? */ return(0); /* End of init file or whatever. */ }#ifdef MAC miniparser(1); if (sstate == 'a') { /* if cmd-. cancel */ debug(F100, "parser: cancel take due to sstate", "", sstate); sstate = '\0'; dostop(); return(0); /* End of init file or whatever. */ }#endif /* MAC */#else /* NOSPL */ if ((tlevel > -1) && feof(tfile[tlevel])) { /* If end of take */ popclvl(); /* Pop up one level. */ cmini(ckxech); /* and clear the cmd buffer. */ if (tlevel < 0) /* Just popped out of cmd files? */ return(0); /* End of init file or whatever. */ }#endif /* NOSPL */#ifndef NOSPL if (cmdstk[cmdlvl].src == CMD_MD) { /* Executing a macro? */ debug(F100,"parser macro","",0); maclvl = cmdstk[cmdlvl].lvl; /* Get current level */ debug(F101,"parser maclvl","",maclvl); cbp = cmdbuf; /* Copy next cmd to command buffer. */ *cbp = NUL; if (*savbuf) { /* In case then-part of 'if' command */ strcpy(cbp,savbuf); /* was saved, restore it. */ *savbuf = '\0'; } else { /* Else get next cmd from macro def */ if (getncm(cbp,CMDBL) < 0) { if (m && (cmdlvl < inlevel)) return((int) sstate); else /* if (!m) */ continue; } } debug(F110,"cmdbuf from macro",cmdbuf,0); } else if (cmdstk[cmdlvl].src == CMD_TF)#else if (tlevel > -1) #endif /* NOSPL */ {#ifndef NOSPL if (*savbuf) { /* In case THEN-part of IF command */ strcpy(cmdbuf,savbuf); /* was saved, restore it. */ *savbuf = '\0'; } else#endif /* NOSPL */ /* Get next line from TAKE file */ if ((tfcode = getnct(cmdbuf,CMDBL)) < 0) { if (tfcode < -1) { /* Error */ printf("?Error in TAKE command file: %s\n", (tfcode == -2) ? "Memory allocation failure" : "Line too long or contains NUL characters" ); popclvl(); } continue; /* -1 means EOF */ } /* If interactive, get next command from user. */ } else { /* User types it in. */ if (pflag) prompt(xxstring); cmini(ckxech); } /* Now know where next command is coming from. Parse and execute it. */ repars = 1; /* 1 = command needs parsing */ displa = 0; /* Assume no file transfer display */ while (repars) { /* Parse this cmd until entered. */ debug(F101,"parser top of while loop","",0); cmres(); /* Reset buffer pointers. */ xx = cmkey2(cmdtab,ncmd,"Command","",toktab,xxstring); debug(F101,"top-level cmkey2","",xx); if (xx == -5) { yy = chktok(toktab); debug(F101,"top-level cmkey token","",yy); ungword(); switch (yy) {#ifndef NOPUSH case '!': xx = XXSHE; break; /* Shell escape */#endif /* NOPUSH */ case '#': xx = XXCOM; break; /* Comment */ case ';': xx = XXCOM; break; /* Comment */#ifndef NOSPL case ':': xx = XXLBL; break; /* GOTO label */#endif /* NOSPL */#ifndef NOPUSH case '@': xx = XXSHE; break; /* Shell (DCL) escape */#endif /* NOPUSH */ default: printf("\n?Invalid - %s\n",cmdbuf); xx = -2; } }#ifndef NOSPL /* Special handling for IF..ELSE */ if (ifcmd[cmdlvl]) /* Count stmts after IF */ ifcmd[cmdlvl]++; if (ifcmd[cmdlvl] > 2 && xx != XXELS && xx != XXCOM) ifcmd[cmdlvl] = 0; /* Execute the command and take action based on return code. */ if (nulcmd) { /* Ignoring this command? */ xx = XXCOM; /* Make this command a comment. */ }#endif /* NOSPL */ zz = docmd(xx); /* Parse rest of command & execute. */ debug(F101,"docmd returns","",zz);#ifdef MAC if (tlevel > -1) { if (sstate == 'a') { /* if cmd-. cancel */ debug(F110, "parser: cancel take, sstate:", "a", 0); sstate = '\0'; dostop(); return(0); /* End of init file or whatever. */ } }#endif /* MAC */ switch (zz) { case -4: /* EOF (e.g. on redirected stdin) */ doexit(GOOD_EXIT,xitsta); /* ...exit successfully */ case -1: /* Reparse needed */ repars = 1; /* Just set reparse flag and */ continue; case -6: /* Invalid command given w/no args */ case -2: /* Invalid command given w/args */#ifdef COMMENT#ifndef NOSPL /* This is going to be really ugly... */ yy = mlook(mactab,atmbuf,nmac); /* Look in macro table */ if (yy > -1) { /* If it's there */ if (zz == -2) { /* insert "do" */ char *mp; mp = malloc((int)strlen(cmdbuf) + 5); if (!mp) { printf("?malloc error 1\n"); return(-2); } sprintf(mp,"do %s ",cmdbuf); strcpy(cmdbuf,mp); free(mp); } else sprintf(cmdbuf,"do %s %c",atmbuf, CR); if (ifcmd[cmdlvl] == 2) /* This one doesn't count! */ ifcmd[cmdlvl]--; debug(F111,"stuff cmdbuf",cmdbuf,zz); repars = 1; /* go for reparse */ continue; } else { char *p; int n; p = cmdbuf; lp = line; n = LINBUFSIZ; if (cmflgs == 0) printf("\n"); if (xxstring(p,&lp,&n) > -1) printf("?Invalid: %s\n",line); else printf("?Invalid: %s\n",cmdbuf); } /* (fall thru...) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -