📄 input.c
字号:
return 0;}/* * Return the current input file stream, or NULL if none. */FILE *curstream(void){ if (depth <= 0 || depth > MAXDEPTH) return NULL; return cip->i_fp;}/* * Open a string for scanning, num characters to be read. * String is copied into local memory so it can be trashed afterwards. * Returns -1 if cannot open string. * * given: * str string to be opened * num lengh of string to open */intopenstring(char *str, size_t num){ char *cp; /* copied string */ if ((depth >= MAXDEPTH) || (str == NULL)) return -2; cp = (char *) malloc(num + 1); if (cp == NULL) return -1; strncpy(cp, str, num); cp[num] = '\0'; /* firewall */ cip = inputs + depth++; cip->i_state = IS_READ; cip->i_char = '\0'; cip->i_cp = cp; cip->i_str = cp; cip->i_num = num; cip->i_fp = NULL; cip->i_name = NULL; cip->i_ttystr = NULL; cip->i_line = 1; return 0;}/* * Set to read input from the terminal. * Returns -1 if there is no more depth for input. */intopenterminal(void){ if (depth >= MAXDEPTH) return -2; cip = inputs + depth++; cip->i_state = IS_READ; cip->i_char = '\0'; cip->i_str = NULL; cip->i_ttystr = NULL; cip->i_fp = NULL; cip->i_name = NULL; cip->i_line = 1; return 0;}/* * Close the current input source. */voidcloseinput(void){ if (depth <= 0) return; if (cip->i_str) free(cip->i_str); if (cip->i_fp) fclose(cip->i_fp); if (cip->i_name) free(cip->i_name); depth--; cip = depth ? &inputs[depth - 1] : NULL;}/* * Reset the input sources back to the initial state. */voidresetinput(void){ while (depth > 0) closeinput(); noprompt = FALSE;}/* * Set the prompt for terminal input. */voidsetprompt(char *str){ prompt = str; noprompt = FALSE;}/* * Read the next character from the current input source. * End of file closes current input source, and returns EOF character. */intnextchar(void){ int ch; /* current input character */ if (depth == 0) /* input finished */ return EOF; if (cip->i_state == IS_REREAD) { /* rereading current char */ ch = cip->i_char; cip->i_state = IS_READ; if (ch == '\n') cip->i_line++; return ch; } if (cip->i_str) { /* from string */ if (cip->i_num) { ch = chartoint(*cip->i_cp++); cip->i_num--; } else { ch = EOF; } } else if (cip->i_fp) { /* from file */ ch = fgetc(cip->i_fp); } else if (!stdin_tty) { /* from file */ ch = fgetc(stdin); } else { /* from terminal */ ch = ttychar(); } if (depth > 0) cip->i_char = ch; /* save for rereads */ if (ch == '\n') cip->i_line++; return ch;}/* * Read in the next line of input from the current input source. * The line is terminated with a null character, and does not contain * the final newline character. The returned string is only valid * until the next such call, and so must be copied if necessary. * Returns NULL on end of file. */char *nextline(void){ char *cp; int ch; int len; cp = linebuf; if (linesize == 0) { cp = (char *)malloc(TTYSIZE + 1); if (cp == NULL) { math_error("Cannot allocate line buffer"); /*NOTREACHED*/ } linebuf = cp; linesize = TTYSIZE; } len = 0; for (;;) { noprompt = TRUE; ch = nextchar(); noprompt = FALSE; if (ch == EOF) return NULL; if (ch == '\0') continue; if (ch == '\n') break; if (len >= linesize) { cp = (char *)realloc(cp, linesize + TTYSIZE + 1); if (cp == NULL) { math_error("Cannot realloc line buffer"); /*NOTREACHED*/ } linebuf = cp; linesize += TTYSIZE; } cp[len++] = (char)ch; } cp[len] = '\0'; return linebuf;}/* * Read the next character from the terminal. * The routines in the history module are called so that the user * can use a command history and emacs-like editing of the line. */static intttychar(void){ int ch; /* current char */ int len; /* length of current command */ static char charbuf[1024]; /* * If we have more to read from the saved command line, then do that. * When we see a newline character, then clear the pointer so we will * read a new line on the next call. */ if (cip->i_ttystr) { ch = chartoint(*cip->i_ttystr++); if (ch == '\n') cip->i_ttystr = NULL; return ch; } /* * We need another complete line. */ abortlevel = 0; inputwait = TRUE; len = hist_getline(noprompt ? "" : prompt, charbuf, sizeof(charbuf)); if (len == 0) { inputwait = FALSE; return EOF; } inputwait = FALSE; /* * Handle shell escape if present */ if (charbuf[0] == '!') { /* do a shell command */ char *cmd; cmd = charbuf + 1; if (*cmd == '\0' || *cmd == '\n') cmd = shell; if (allow_exec) { if (conf->calc_debug & CALCDBG_SYSTEM) { printf("%s\n", cmd); } system(cmd); } else { fprintf(stderr, "execution disallowed by -m flag\n"); } return '\n'; } hist_saveline(charbuf, len); /* * Return the first character of the line, and set up to * return the rest of it with later calls. */ ch = chartoint(charbuf[0]); if (ch != '\n') cip->i_ttystr = charbuf + 1; return ch;}/* * Return whether or not the input source is the terminal. */BOOLinputisterminal(void){ return ((depth <= 0) || ((cip->i_str == NULL) && (cip->i_fp == NULL)));}/* * Return depth of current input source */intinputlevel(void){ return depth - 1;}/* * Return the name of the current input file. * Returns NULL for terminal or strings. */char *inputname(void){ if (depth <= 0) return NULL; return cip->i_name;}/* * Return the current line number. */longlinenumber(void){ if (depth > 0) return cip->i_line; return 1;}/* * Restore the next character to be read again on the next nextchar call. */voidreread(void){ if ((depth <= 0) || (cip->i_state == IS_REREAD)) return; cip->i_state = IS_REREAD; if (cip->i_char == '\n') cip->i_line--;}/* * Process all startup files found in the $CALCRC path. */voidrunrcfiles(void){ char path[MAX_CALCRC+1+1]; /* name being searched for */ char *cp; char *p; /* execute each file in the list */ while (calcrc != NULL && *calcrc) { cp = calcrc; calcrc = (char *) strchr(calcrc + 1, LISTCHAR); /* load file name into the path */ if (calcrc == NULL) { strncpy(path, cp, MAX_CALCRC+1); } else { strncpy(path, cp, calcrc - cp); path[calcrc - cp] = '\0'; } /* find the start of the path */ p = (path[0] == ':') ? path + 1 : path; if (p[0] == '\0') { continue; } /* process the current file in the list */ if (openfile(p) < 0) { /* Unable to open rcfile */ if (c_flag && !d_flag) fprintf(stderr, "Unable to open rcfile \"%s\"\n", p); continue; } getcommands(FALSE); closeinput(); }}/* * isinoderead - determine if we have read a given dev/inode * * This function returns the index of the readset element that matches * a given device/inode, -1 otherwise. * * * WIN32 NOTE: * * This function does not work under WIN32. The sbuf->st_ino is always * zero because the FAT and NTFS filesystems do not support inodes. * They also don't support links, which is why you need this function * under UNIX. For WIN32, use _fullpath() to determine if you have * already opened a file. * * given: * sbuf stat of the inode in question */static intisinoderead(struct stat *sbuf){ int i; /* deal with the empty case */ if (readset == NULL || maxreadset <= 0) { /* readset is empty */ return -1; } /* scan the entire readset */ for (i=0; i < maxreadset; ++i) {#if defined(_WIN32) || defined(__MSDOS__) tmp = _fullpath(NULL, cip->i_name, _MAX_PATH); if (readset[i].active && tmp != NULL && strcasecmp(readset[i].path, tmp) == 0) { /* found a match */ free(tmp); return i; } if (tmp != NULL) { free(tmp); }#else /* Windoz free systems */ if (readset[i].active && sbuf->st_dev == readset[i].inode.st_dev && sbuf->st_ino == readset[i].inode.st_ino) { /* found a match */ return i; }#endif /* Windoz free systems */ } /* no match found */ return -1;}/* * findfreeread - find the next free readset element * * This function will return the index of the next free readset element. * If needed, this function will allocate new readset elements. * * This function returns the index of the next free element, or -1. */static intfindfreeread(void){ int i; /* deal with an empty readset case */ if (readset == NULL || maxreadset <= 0) { /* malloc a new readset */ readset = (READSET *)malloc((READSET_ALLOC+1)*sizeof(READSET)); if (readset == NULL) { return -1; } maxreadset = READSET_ALLOC; for (i=0; i < READSET_ALLOC; ++i) { readset[i].active = 0; } /* return first entry */ return 0; } /* try to find a free readset entry */ for (i=0; i < maxreadset; ++i) { if (readset[i].active == 0) { /* found a free readset entry */ return i; } } /* all readset entries are in use, allocate more */ readset = (READSET *)realloc(readset, (maxreadset+READSET_ALLOC) * sizeof(READSET)); if (readset == NULL) { return -1; } for (i=0; i < READSET_ALLOC; ++i) { readset[i+maxreadset].active = 0; } maxreadset += READSET_ALLOC; /* return the first newly allocated free entry */ return maxreadset-READSET_ALLOC;}/* * addreadset - add a entry to the readset array if it is not already there * * This function attempts to add a file into the readset. If the readset * has an entry with a matching dev/inode, then that entry is updated with * the new name and path. If no such readset entry is found, a new entry * is added. * * This function returns the index of the readset entry, or -1 if error. * * given: * name name given to read or include * path full pathname of file * sbuf stat of the path */static intaddreadset(char *name, char *path, struct stat *sbuf){ int ret; /* index to return */ size_t name_len; /* length of read set name */ size_t path_len; /* length of path to read set name */ /* find the inode */ ret = isinoderead(sbuf); if (ret < 0) { /* not in readset, find a free node */ ret = findfreeread(); if (ret < 0) { /* cannot find/form a free readset entry */ return -1; } } else { /* found an readset entry, free old readset data */ if (readset[ret].name != NULL) { free(readset[ret].name); } if (readset[ret].path != NULL) { free(readset[ret].path); } } /* load our information into the readset entry */ name_len = strlen(name); readset[ret].name = (char *)malloc(name_len+1); if (readset[ret].name == NULL) { return -1; } strncpy(readset[ret].name, name, name_len+1);#if defined(_WIN32) || defined(__MSDOS__) /* * For WIN32, _fullpath expands the path to a fully qualified * path name, which under WIN32 FAT and NTFS is unique, just * like UNIX inodes. _fullpath also allocated the memory for * this new longer path name. */ { readset[ret].path = _fullpath(NULL, path, _MAX_PATH); if (readset[ret].path == NULL) { return -1; } }#else /* Windoz free systems */ path_len = strlen(path); readset[ret].path = (char *)malloc(path_len+1); if (readset[ret].path == NULL) { return -1; } strncpy(readset[ret].path, path, path_len+1);#endif /* Windoz free systems */ readset[ret].inode = *sbuf; readset[ret].active = 1; /* return index of the newly added entry */ return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -