📄 config.c
字号:
/******************* start of original comments ********************//* * This file contains the utilities to read in a ".tdecfg" file. * * Most of this stuff is duplicated from the cfgfile.c functions. In * Linux, this utility searches the CWD first then it searches the * HOME directory for the ".tdecfg" file. * * Many thanks to <intruder@link.hacktic.nl> for the idea and sample code * for this function. * ********************* start of Jason's comments ********************* * * DJGPP also requires the configuration file ("tde.cfg"), so to provide * the same functionality across versions, DOS gets it as well. * I also added a custom help file (".tdehlp" and "tde.hlp"). * * Load the file from the HOME or executable directory first, and then * from the current directory. This allows global and local settings. * The help file is loaded from the current directory, or the HOME / * executable directory. * ********************* end of Jason's comments ********************* * * New editor name: TDE, the Thomson-Davis Editor. * Author: Frank Davis * Date: June 5, 1991, version 1.0 * Date: July 29, 1991, version 1.1 * Date: October 5, 1991, version 1.2 * Date: January 20, 1992, version 1.3 * Date: February 17, 1992, version 1.4 * Date: April 1, 1992, version 1.5 * Date: June 5, 1992, version 2.0 * Date: October 31, 1992, version 2.1 * Date: April 1, 1993, version 2.2 * Date: June 5, 1993, version 3.0 * Date: August 29, 1993, version 3.1 * Date: November 13, 1993, version 3.2 * Date: June 5, 1994, version 4.0 * Date: December 5, 1998, version 5.0 (jmh) * * This code is released into the public domain, Frank Davis. * You may distribute it freely. */#include "tdestr.h" /* tde types */#include "common.h"#include "define.h"#include "tdefunc.h"#include "config.h" char *line_in = NULL; /* input line buffer */static int line_in_len = 0; /* length of above */ int line_no; /* global variable for line count */ int process_macro; /* multi-line macro definition */static int stroke_count; /* global variable for macro strokes */static long macro_key; MACRO *mac;static TREE *branch; TREE *cfg_key_tree;static int existing_macro;static int key_num; /* current menu key (jmh 020831) */static int need_a_redraw; /* if we redefined colors, then redraw screen */static int need_mode_line; /* if we redefined modes, then redraw line */static int need_rulers; /* if we redefined rulers, then redraw ruler */static int need_line_numbers; /* redefining line numbers? */static int need_cwd; /* redefining the cwd display? */ int background; /* default background color (jmh 990420) */ char *cmd_config = NULL; /* config file from command line (jmh 010605) */ MENU_STR *user_menu; /* User menu or Language sub-menu (jmh 031129)*/extern MENU_LIST popout_default[];extern MENU_LIST *popout_last;#if defined( __WIN32__ )extern HANDLE conin;#endifstatic void new_key_name( char *, char * );static const char *new_scancode_map( char *, char * );static int new_help_screen( FILE*, int );static const char *process_menu( char *, char * );static const char *new_menu_item( MENU_STR *, char *, char * );static void free_menu( MENU_STR * );/* * Name: tdecfgfile * Date: June 5, 1994 * Notes: read in a configuration file at any time. * read in a configuration file when we first fire up TDE in * a linux (unix) and djgpp environment. * August 20, 1997, Jason Hood - read in a help file as well. * jmh 980721: replaces load_strokes. * jmh 981127: only bring up the directory list if the macro name contains * a wildcard pattern. * jmh 990430: blank out help screen if the file contains fewer lines; * read in a viewer help screen. * jmh 010604: moved help to readfile(); * prompt for a config file; * update the mono "colors" if using MDA. * jmh 031130: update the menu. */int tdecfgfile( TDE_WIN *window ){int rc = OK;int prompt_line;char fname[PATH_MAX]; /* new name for file */const char *prompt;int i, j; prompt_line = (window != NULL) ? window->bottom_line : g_display.end_line; need_a_redraw = FALSE; need_mode_line = FALSE; need_rulers = FALSE; need_line_numbers = mode.line_numbers; need_cwd = mode.display_cwd; key_num = 0; background = 1; user_menu = &menu[user_idx].menu; if (window == NULL) { cfg_key_tree = &key_tree; /* * CONFIGFILE is defined in tdestr.h */ join_strings( fname, g_status.argv[0], CONFIGFILE ); rc = readfile( fname, prompt_line ); /* * jmh 990213: See if the current directory and executable directory * are the same. If so, don't read the config file twice. */ get_current_directory( fname ); if (strcmp( fname, g_status.argv[0] ) != 0) rc = readfile( CONFIGFILE, prompt_line ); /* * jmh 010605: Read the config file specified on the command line. * Assume it's different to those above. */ if (cmd_config != NULL) { rc = readfile( cmd_config, prompt_line ); cmd_config = NULL; } } else { if (g_status.command == LoadMacro) { /* * search path or file name for macro file */ prompt = main21; strcpy( fname, "*.tdm" ); cfg_key_tree = (window->syntax) ? &window->file_info->syntax->key_tree : &key_tree; } else { /* * search path or file name for config file */ prompt = main21a; strcpy( fname, CONFIGFILE ); cfg_key_tree = &key_tree; } if (get_name( prompt, prompt_line, fname, &h_file ) > 0) { if (is_pattern( fname )) rc = list_and_pick( fname, window ); /* * if everything is everything, load in the file selected by user. */ if (rc == OK) rc = readfile( fname, prompt_line ); } else rc = ERROR; } if (rc == OK) { if (need_a_redraw) { g_display.color = colour[(g_display.adapter != MDA)]; if (g_display.adapter != MDA) set_overscan_color( Color( Overscan ) ); } if (window != NULL) { if (need_a_redraw) redraw_screen( window ); if (need_mode_line && !need_a_redraw) show_modes( ); if (need_rulers) show_all_rulers( ); if (need_line_numbers != mode.line_numbers) toggle_line_numbers( NULL ); if (need_cwd != mode.display_cwd) toggle_cwd( NULL ); } else { make_ruler( ); mode.line_numbers = need_line_numbers; mode.display_cwd = need_cwd; } } if (user_idx == -1) process_menu( NULL, "User" ); if (user_menu && user_menu->minor_cnt == 0) new_user_menu( NULL, (char*)config32, FALSE ); /* <Empty> */ /* * remove empty menus (apart from User) */ for (i = menu_cnt - 1; i >= 0; --i) { if (menu[i].menu.minor_cnt == 0 && i != user_idx) { if (*menu[i].major_name != '\0') my_free( menu[i].major_name ); memcpy( menu + i, menu + i+1, (menu_cnt - (i+1)) * sizeof(*menu) ); if (user_idx > i) --user_idx; --menu_cnt; } } for (i = menu_cnt - 1; i >= 0; --i) { for (j = menu[i].menu.minor_cnt - 2; j >= 1; --j) { if (menu[i].menu.minor[j].pop_out && menu[i].menu.minor[j].pop_out->minor_cnt == 0) { MENU_LIST *ml, *po; po = NULL; for (ml = popout_menu; ml != NULL; ml = ml->next) { if (&ml->popout == menu[i].menu.minor[j].pop_out) { if (po == NULL) popout_menu = ml->next; else po->next = ml->next; my_free( ml ); my_free( menu[i].menu.minor[i].minor_name ); memcpy( menu[i].menu.minor + j, menu[i].menu.minor + j+1, (menu[i].menu.minor_cnt - (j+1)) * sizeof(*menu) ); --menu[i].menu.minor_cnt; break; } po = ml; } } } } /* * initialise the pull-down menus (jmh) */ init_menu( window == NULL ); return( rc );}/* * Name: readfile * Date: May 31, 1998 * Notes: helper function for tdecfgfile * * jmh 010604: read the help file based on the config file - replace trailing * "cfg" with "hlp" (eg: tde.cfg -> tde.hlp; .tdecfg -> .tdehlp; * tde.tdm -> no help file); "cfg" is case sensitive in UNIX; * if the first line of the help file is the separator, don't blank * out the editor help screen; similarly, if there is no separator, * don't blank out the viewer help screen. This allows for global * editor and viewer screens, but only one local screen; * no error is returned if the help file could not be opened, but * the warning is still given; * don't load the help if the config could not be opened; * it's okay to have a help file without a config file, but the * config name must still be given. */int readfile( char *fname, int prompt_line ){FILE *config;char hname[PATH_MAX];int i;int rc = OK; if (file_exists( fname ) != ERROR) { if ((config = fopen( fname, "r" )) == NULL) { rc = ERROR; combine_strings( line_out, main7a, fname, main7b ); error( WARNING, prompt_line, line_out ); } else { line_no = 1; process_macro = FALSE; while (read_line( config ) != EOF && !g_status.control_break) { parse_line( line_in, prompt_line ); ++line_no; } if (process_macro) { /* * Unexpected end of file. Tidy up the macro definition. */ check_macro( mac ); error( WARNING, prompt_line, config26 ); } fclose( config ); } } /* * See if there's a help file. */ if (rc == OK) { strcpy( hname, fname ); i = strlen( hname ); if (i >= 3 &&#if defined( __UNIX__ ) strcmp( hname+i-3, "cfg" ) == 0)#else stricmp( hname+i-3, "cfg" ) == 0)#endif strcpy( hname+i-3, "hlp" ); if (file_exists( hname ) != ERROR) { if ((config = fopen( hname, "r" )) == NULL) { combine_strings( line_out, main7a, hname, main7b ); error( WARNING, prompt_line, line_out ); } else { if (new_help_screen( config, 0 )) new_help_screen( config, 1 ); fclose( config ); } } } return( rc );}/* * Name: read_line * Purpose: read a line from a file * Date: October 31, 2002 * Passed: file: the file to read * Returns: the length of the line, or EOF. * Notes: reads a line into the global line_in buffer, replacing the line * ending with a NUL. (also replaces remove_cr() used in UNIX.) */int read_line( FILE *file ){int len = 0;int ch = EOF; for (;;) { if (len == line_in_len) { char *temp = realloc( line_in, line_in_len + 80 ); if (temp == NULL) { if (len == 0) return( EOF ); else { --len; break; } } line_in = temp; line_in_len += 80; } ch = fgetc( file );#if defined( __UNIX__ ) if (ch == '\r') { if ((ch = fgetc( file )) != '\n') { ungetc( ch, file ); ch = '\r'; } }#endif if (ch == '\n' || ch == EOF) break; line_in[len++] = ch; } line_in[len] = '\0'; return( (ch == EOF && len == 0) ? EOF : len );}/* * Name: parse_line * Purpose: real work horse of the configuration utility, figure out what * we need to do with each line of the config file. * Date: June 5, 1994 * Passed: line: line that contains the text to parse * jmh 980720: take into account multi-line macro definitions * jmh 980730: I really don't like a lot of if-else-if conditionals, so I * restructured with goto bad_config. * jmh 990404: Added the explicit setting of insert/overwrite cursor sizes: * "CursorStyle Large Medium" will use a solid block for insert * and a half-block for overwrite. * jmh 990428: Recognize the viewer character functions. * jmh 020818: Treat function keys as prefixes and key name; * other modifications based on the new key mapping. */void parse_line( char *line, int prompt_line ){char key[1042]; /* buffer to hold any token that we parse */char *residue; /* pointer to next item in line, if it exists */int key_no; /* index into key array */long two_key; /* two-combination keys */int color; /* color field */int mode_index; /* index in mode array */int func_no; /* function number we want to assign to a key */int color_no; /* attribute we want to assign to a color field */int mode_no; /* mode number we want to assign to a mode */int found; /* boolean, did we find a valid key, color, or mode? */int i;const char *errmsg = NULL; if (process_macro) { parse_macro( line, prompt_line ); return; } /* * find the first token and put it in key. residue points to next token. */ residue = parse_token( line, key ); if (*key == '\0') return; /* * jmh 980730: there must be something else on the line (except for macros, * which are taken care of above). */ if (residue == NULL) { errmsg = config1; /* setting without value */ goto bad_config;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -