void gosubret(char *ignored) { int offset, err; if (InAScript()) { err = 0; if (ReturnToDepth <= 0) { printf("Nothing to return to\n"); err = 1; } else { ReturnToDepth--; offset = tfsseek(currentScriptfd(), ReturnToTellTbl[ReturnToDepth],TFS_BEGIN); if (offset <= 0) { err = 1; printf("return error: %s\n",tfserrmsg(offset)); } } if (err) printf("Possible gosub/return imbalance.\n"); } }
/* fatfsGet(): * Retreive a file from the FATFS and place it in the specified destination. * The destination may be either a TFS filename or a hex address * (indicated by a leading "0x"). * * Input: * char *fatfspath * Pointer to FATFS file and path. * char *dest * Pointer to TFS filename or a addr,len string. * The expected "addr,len" syntax is 0xADDR,LEN or 0xADDR,0xLEN. */ static int fatfsGet(char *fatfile, char *dest) { FILEINFO fi; char *p, tfs; uint32_t i; if (DFS_OpenFile(&vi, (uint8_t *)fatfile, DFS_READ, sector, &fi)) { printf("error opening file\n"); return(-1); } if (strncmp(dest,"0x",2) == 0) { tfs = 0; p = (char *)strtoul(dest,0,0); } else { tfs = 1; p = fatfs_tmp_space; } DFS_ReadFile(&fi, sector, (uint8_t *)p, &i, fi.filelen); if (i != fi.filelen) { printf("read %d, expected %d\n",i,fi.filelen); return(-1); } if (tfs) { #if INCLUDE_TFS int tfserr; char *flags, *info; flags = info = (char *)0; if ((flags = strchr(dest,','))) { *flags++ = 0; if ((info = strchr(flags,','))) *info++ = 0; } tfserr = tfsadd(dest,info,flags,(uchar *)p,fi.filelen); if (tfserr != TFS_OKAY) { printf("TFS error: %s\n",tfserrmsg(tfserr)); return(-1); } #else printf("TFS not built in\n"); return(-1); #endif } return(0); }
/* tfsclose(): * If the file was opened for reading only, then just close out the * entry in the tfsSlots table. If the file was opened for creation, * then add it to the tfs list. Note the additional argument is * only needed for tfsclose() of a newly created file. * info = additional text describing the file. * MONLIB NOTICE: this function is accessible through monlib.c. */ int tfsclose(int fd,char *info) { int err; struct tfsdat *tdat; if (!info) info = ""; if (tfsTrace > 0) printf("tfsclose(%d,%s)\n",fd,info); if ((fd < 0) || (fd >= TFS_MAXOPEN)) return(TFSERR_BADARG); tdat = &tfsSlots[fd]; if (tdat->offset == -1) return(TFSERR_BADFD); /* Mark the file as closed by setting the offset to -1. * Note that this is done prior to potentially calling tfsadd() so * that tfsadd() will not think the file is opened and reject the add... */ tdat->offset = -1; /* If the file was opened for creation or append, and the hwp * (high-water-point) is greater than zero, then add it now. * * Note regarding hwp==0... * In cases where a non-existent file is opened for creation, * but then nothing is written to the file, the hwp value will * be zero; hence, no need to call tfsadd(). */ if ((tdat->flagmode & (TFS_CREATE | TFS_APPEND)) && (tdat->hwp > 0)) { char buf[16]; err = tfsadd(tdat->hdr.name, info, tfsflagsbtoa(tdat->flagmode,buf), tdat->base, tdat->hwp); if (err != TFS_OKAY) { printf("%s: %s\n",tdat->hdr.name,tfserrmsg(err)); return(err); } } return(TFS_OKAY); }
int tfsscript(TFILE *fp,int verbose) { char lcpy[CMDLINESIZE], *sv; int tfd, lnsize, lno, verbosity, ignoreerror, cmdstat; tfd = tfsopen(fp->name,TFS_RDONLY,0); if (tfd < 0) return(tfd); lno = 0; /* If ScriptIsRunning is zero, then we know that this is the top-level * script, so we can initialize state here... */ if (ScriptIsRunning == 0) ReturnToDepth = 0; CurrentScriptfdTbl[++ScriptIsRunning] = tfd; while(1) { lno++; lnsize = tfsgetline(tfd,lcpy,CMDLINESIZE); if (lnsize == 0) /* end of file? */ break; if (lnsize < 0) { printf("tfsscript(): %s\n",tfserrmsg(lnsize)); break; } if ((lcpy[0] == '\r') || (lcpy[0] == '\n')) /* empty line? */ continue; lcpy[lnsize-1] = 0; /* Remove the newline */ /* Just in case the goto tag was set outside a script, */ /* clear it now. */ if (ScriptGotoTag) { free(ScriptGotoTag); ScriptGotoTag = (char *)0; } ScriptExitFlag = 0; /* Execute the command line. * If the shell variable "SCRIPTVERBOSE" is set, then enable * verbosity for this command; else use what was passed in * the parameter list of the function. Note that the variable * is tested for each command so that verbosity can be enabled * or disabled within a script. * If the command returns a status that indicates that there was * some parameter error, then exit the script. */ sv = getenv("SCRIPTVERBOSE"); if (sv) verbosity = atoi(sv); else verbosity = verbose; if ((lcpy[0] == '-') || (getenv("SCRIPT_IGNORE_ERROR"))) ignoreerror = 1; else ignoreerror = 0; if (verbosity) printf("[%02d]: %s\n",lno,lcpy); cmdstat = tfsDocommand(lcpy[0] == '-' ? lcpy+1 : lcpy, 0); if (cmdstat != CMD_SUCCESS) { setenv("CMDSTAT","FAIL"); if (ignoreerror == 0) { printf("Terminating script '%s' at line %d\n", TFS_NAME(fp),lno); ScriptExitFlag = EXIT_SCRIPT; break; } } else { setenv("CMDSTAT","PASS"); } /* Check for exit flag. If set, then in addition to terminating the * script, clear the return depth here so that the "missing return" * warning is not printed. This is done because there is likely * to be a subroutine with an exit in it and this should not * cause a warning. */ if (ScriptExitFlag) { ReturnToDepth = 0; break; } /* If ScriptGotoTag is set, then attempt to reposition the line * pointer to the line that contains the tag. */ if (ScriptGotoTag) { int tlen; tlen = strlen(ScriptGotoTag); lno = 0; tfsseek(tfd,0,TFS_BEGIN); while(1) { lnsize = tfsgetline(tfd,lcpy,CMDLINESIZE); if (lnsize == 0) { printf("Tag '%s' not found\n",ScriptGotoTag+2); free(ScriptGotoTag); ScriptGotoTag = (char *)0; tfsclose(tfd,0); return(TFS_OKAY); } lno++; if (!strncmp(lcpy,ScriptGotoTag,tlen) && (isspace(lcpy[tlen]) || (lcpy[tlen] == ':'))) { free(ScriptGotoTag); ScriptGotoTag = (char *)0; break; } } } /* After each line, poll ethernet interface. */ pollethernet(); } tfsclose(tfd,0); if (ScriptExitFlag & REMOVE_SCRIPT) tfsunlink(fp->name); if (ScriptIsRunning > 0) { ScriptIsRunning--; if ((ScriptIsRunning == 0) && (ReturnToDepth != 0)) { printf("Error: script is done, but return-to-depth != 0\n"); printf("(possible gosub/return imbalance)\n"); } } else { printf("Script run-depth error\n"); } /* If the EXECUTE_AFTER_EXIT flag is set (by exit -e), then automatically * start up the file specified in ExecuteAfterExit[]... */ if (ScriptExitFlag & EXECUTE_AFTER_EXIT) { char *argv[2]; argv[0] = ExecuteAfterExit; argv[1] = 0; ScriptExitFlag = 0; tfsrun(argv,0); } /* Upon completion of a script, clear the ScriptExitFlag variable so * that it is not accidentally applied to another script that may have * called this script. */ if ((ScriptExitFlag & EXIT_ALL_SCRIPTS) != EXIT_ALL_SCRIPTS) ScriptExitFlag = 0; return(TFS_OKAY); }