lib_calc.c
来自「Calc Software Package for Number Calc」· C语言 代码 · 共 890 行 · 第 1/2 页
C
890 行
strncpy(home, ent->pw_dir, pw_dir_len+1); }#endif /* Windoz free systems */ /* determine the $PAGER value */ c = (no_env ? NULL : getenv(PAGER)); pager = (c ? strdup(c) : NULL); if (pager == NULL || *pager == '\0') pager = DEFAULTCALCPAGER; /* determine the $SHELL value */ c = (no_env ? NULL : getenv(SHELL)); shell = (c ? strdup(c) : NULL); if (shell == NULL || *shell == '\0') shell = DEFAULTSHELL;}/* * libcalc_call_me_last - users of libcalc.a can call this function when done * * Anything that uses libcalc.a can call this function after they are * completely finished with libcalc.a processing. The only effect of * this function is to free storage that might otherwise go unused. * * NOTE: If, for any reason, you need to do more libcalc.a processing, * then you will need to call libcalc_call_me_first() again. */voidlibcalc_call_me_last(void){ int i; /* * firewall */ if (init_done == 0) { return; } /* * free the configuration */ config_free(conf); /* * free Blum generator state */ random_libcalc_cleanup(); /* * restore all changed descriptor states */ for (i=0; i < fd_setup_len; ++i) { if (fd_setup[i] >= 0) { if (conf->calc_debug & CALCDBG_TTY) printf("libcalc_call_me_last: fd %d " "not in original state, " "restoring it", fd_setup[i]); orig_tty(fd_setup[i]); } } /* * all done */ init_done = 0; return;}/* * run_state_name - return a constant string given a run_state */char *run_state_name(run state){ switch (state) { case RUN_ZERO: return "ZERO"; case RUN_BEGIN: return "BEGIN"; case RUN_RCFILES: return "RCFILES"; case RUN_PRE_CMD_ARGS: return "PRE_CMD_ARGS"; case RUN_CMD_ARGS: return "CMD_ARGS"; case RUN_PRE_TOP_LEVEL: return "PRE_TOP_LEVEL"; case RUN_TOP_LEVEL: return "TOP_LEVEL"; case RUN_EXIT: return "EXIT"; case RUN_EXIT_WITH_ERROR: return "EXIT_WITH_ERROR"; } return "RUN_invalid";}/* * calc_strdup - calc interface to provide or simulate strdup() */char *calc_strdup(CONST char *s1){#if defined(HAVE_STRDUP) return strdup(s1);#else /* HAVE_STRDUP */ char *ret; /* return string */ size_t s1_len; /* length of string to duplicate */ /* * firewall */ if (s1 == NULL) { return NULL; } /* * allocate duplicate storage */ s1_len = strlen(s1); ret = (char *)malloc(s1_len+1); /* * if we have storage, duplicate the string */ if (ret != NULL) { strncpy(ret, s1, s1_len+1); } /* * return the new string, or NULL if malloc failed */ return ret;#endif /* HAVE_STRDUP */}/* * find_tty_state - establish a new tty state * * Given: * fd file descriptor to establish a new tty state for * * Returns: * indx The index into fd_setup[], fd_orig[] and fd_cur[] to use or -1 */static intfind_tty_state(int fd){ int *new_fd_setup; /* new fd_setup array */ ttystruct *new_fd_orig; /* new fd_orig array */ ttystruct *new_fd_cur; /* new fd_cur array */ int i; /* * firewall: must be > 0 */ if (fd < 0) { /* bad descriptor */ return -1; } /* * case: need to initially malloc some state */ if (fd_setup_len <= 0 || fd_setup == NULL || fd_orig == NULL) { /* setup for a single descriptor */ fd_setup = (int *)malloc(sizeof(fd_setup[0])); if (fd_setup == NULL) { return -1; } fd_setup[0] = -1; fd_orig = (ttystruct *)malloc(sizeof(fd_orig[0])); if (fd_orig == NULL) { return -1; } fd_cur = (ttystruct *)malloc(sizeof(fd_orig[0])); if (fd_cur == NULL) { return -1; } fd_setup_len = 1; } /* * look for an existing tty state for the descriptor */ for (i=0; i < fd_setup_len; ++i) { /* case: found existing tty state, return index */ if (fd_setup[i] == fd) { return i; } } /* * no tty state exists for the descriptor, look for empty slot */ for (i=0; i < fd_setup_len; ++i) { /* case: found an empty slot, so return it */ if (fd_setup[i] < 0) { return i; } } /* * no empty slots exist, realloc another slot */ new_fd_setup = (int *)realloc(fd_setup, sizeof(fd_setup[0]) * (fd_setup_len+1)); if (new_fd_setup == NULL) { return -1; } new_fd_setup[fd_setup_len] = -1; new_fd_orig = (ttystruct *)realloc(fd_setup, sizeof(fd_orig[0]) * (fd_setup_len+1)); if (new_fd_orig == NULL) { return -1; } new_fd_cur = (ttystruct *)realloc(fd_cur, sizeof(fd_cur[0]) * (fd_setup_len+1)); if (new_fd_cur == NULL) { return -1; } fd_setup = new_fd_setup; fd_orig = new_fd_orig; fd_cur = new_fd_cur; ++fd_setup_len; /* return the new slot */ return fd_setup_len-1;}/* * calc_tty - setup a file descriptor for calc's interactive use * * Calc wants, in effect, cbreak on and echo off. * * Given: * fd the descriptor for calc's interactive use * * Returns: * TRUE state change was successful * FALSE unable to change state of descriptor for interactive use */BOOLcalc_tty(int fd){ int slot; /* the saved descriptor slot or -1 */ /* * grab the saved slot for this descriptor */ slot = find_tty_state(fd); if (slot < 0) { if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: Cannot get saved descriptor slot\n"); return FALSE; }#if defined(USE_SGTTY) /* * USE_SGTTY tty state method */ /* save original state if needed */ if (fd_setup[slot] < 0 && ioctl(fd, TIOCGETP, fd_orig+slot) < 0) { if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: Cannot TIOCGETP fd %d\n", fd); return FALSE; } /* setup for new state */ fd_cur[slot] = fd_orig[slot]; fd_cur[slot].sg_flags &= ~ECHO; fd_cur[slot].sg_flags |= CBREAK; /* enable new state */ if (ioctl(fd, TIOCSETP, fd_cur+slot) < 0) { if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: Cannot TIOCSETP fd %d\n", fd); return FALSE; } if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: stty -ECHO +CBREAK: fd %d\n", fd);#elif defined(USE_TERMIO) /* * USE_TERMIO tty state method */ if (fd_setup[slot] < 0 && ioctl(fd, TCGETA, fd_orig+slot) < 0) { if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: Cannot TCGETA fd %d\n", fd); return FALSE; } /* setup for new state */ fd_cur[slot] = fd_orig[slot]; fd_cur[slot].c_lflag &= ~(ECHO | ECHOE | ECHOK); fd_cur[slot].c_iflag |= ISTRIP; fd_cur[slot].c_lflag &= ~ICANON; fd_cur[slot].c_cc[VMIN] = 1; fd_cur[slot].c_cc[VTIME] = 0; /* enable new state */ if (ioctl(fd, TCSETAW, fd_cur+slot) < 0) { if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: Cannot TCSETAW fd %d\n", fd); return FALSE; } if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: stty -ECHO -ECHOE -ECHOK -ICANON +ISTRIP " "VMIN=1 VTIME=0: fd %d\n", fd);#elif defined (USE_TERMIOS) /* * USE_TERMIOS tty state method */ if (fd_setup[slot] < 0 && tcgetattr(fd, fd_orig+slot) < 0) { if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: Cannot tcgetattr fd %d\n", fd); return FALSE; } /* setup for new state */ fd_cur[slot] = fd_orig[slot]; fd_cur[slot].c_lflag &= ~(ECHO | ECHOE | ECHOK); fd_cur[slot].c_iflag |= ISTRIP; fd_cur[slot].c_lflag &= ~ICANON; fd_cur[slot].c_cc[VMIN] = 1; fd_cur[slot].c_cc[VTIME] = 0; /* enable new state */ if (tcsetattr(fd, TCSANOW, fd_cur+slot) < 0) { if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: Cannot tcsetattr fd %d\n", fd); return FALSE; } if (conf->calc_debug & CALCDBG_TTY) printf("calc_tty: stty -ECHO -ECHOE -ECHOK -ICANON +ISTRIP " "VMIN=1 VTIME=0: fd %d\n", fd);#else /* Using none of the above */ fd_cur[slot] = fd_orig[slot];#endif /* * note that the tty slot is on use */ fd_setup[slot] = fd; return TRUE;}/* * orig_tty - restore the original state of a file descriptor * * This routine will restore the state of a descriptor to its calc * startup value if it was set for interactive use by calc_tty(). * * Given: * fd the descriptor to restore * * Returns: * TRUE restore was successful * FALSE unable to restore descriptor to original state */BOOLorig_tty(int fd){ int slot; /* the saved descriptor slot or -1 */ /* * find the saved slot for this descriptor */ slot = find_tty_state(fd); if (slot < 0) { if (conf->calc_debug & CALCDBG_TTY) printf("orig_tty: Cannot get saved descriptor slot\n"); return FALSE; } /* * do nothing if no state was saved for this descriptor */ if (fd_setup[slot] < 0) { if (conf->calc_debug & CALCDBG_TTY) printf("orig_tty: no state saved for fd %d\n", fd); return FALSE; }#if defined(USE_SGTTY) /* * USE_SGTTY tty state method */ (void) ioctl(fd, TIOCSETP, fd_orig+slot); if (conf->calc_debug & CALCDBG_TTY) printf("orig_tty: TIOCSETP restored fd %d\n", fd);#elif defined(USE_TERMIO) /* * USE_TERMIO tty state method */ (void) ioctl(fd, TCSETAW, fd_orig+slot); if (conf->calc_debug & CALCDBG_TTY) printf("orig_tty: TCSETAW restored fd %d\n", fd);#elif defined (USE_TERMIOS) /* * assume USE_SGTTY tty state method */ (void) tcsetattr(fd, TCSANOW, fd_orig+slot); if (conf->calc_debug & CALCDBG_TTY) printf("orig_tty: TCSANOW restored fd %d\n", fd);#else /* nothing assigned */ if (conf->calc_debug & CALCDBG_TTY) printf ("orig_tty: nothing restored to fd %d\n", fd);#endif /* * note new current state */ fd_cur[slot] = fd_orig[slot]; /* * Since current state is the original state, we can free up * this slot. This also prevents functions such as the * libcalc_call_me_last() function from re-restoring it. */ fd_setup[slot] = -1; return TRUE;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?