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 + -
显示快捷键?