setupinf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,908 行 · 第 1/5 页
C
1,908 行
typedef struct dialog_info { // structure used when parsing a dialog
array_info array;
int num_push_buttons;
int num_variables;
int num_radio_buttons;
int max_width;
int wrap_width;
a_dialog_header *curr_dialog;
int row_num;
int col_num;
} DIALOG_INFO;
// Characters prohibited from beginning lines
#define NUM_INVALID_FIRST 56
static unsigned short InvalidFirst[ NUM_INVALID_FIRST ] =
{
0x8141, 0x8142, 0x8143, 0x8144, 0x8146, 0x8147, 0x8148, 0x8149,
0x814a, 0x814b, 0x8152, 0x8153, 0x8154, 0x8155, 0x8158, 0x815b,
0x815c, 0x815d, 0x8166, 0x8168, 0x816a, 0x816c, 0x816e, 0x8170,
0x8172, 0x8174, 0x8176, 0x8178, 0x817a, 0x818b, 0x818c, 0x818d,
0x818e, 0x8193, 0x829f, 0x82a1, 0x82a3, 0x82a5, 0x82a7, 0x82c1,
0x82e1, 0x82e3, 0x82e5, 0x82ec, 0x8340, 0x8342, 0x8344, 0x8346,
0x8348, 0x8362, 0x8383, 0x8385, 0x8387, 0x838e, 0x8395, 0x8396
};
// Characters prohibited from terminating lines
#define NUM_INVALID_LAST 19
static unsigned short InvalidLast[ NUM_INVALID_LAST ] =
{
0x8165, 0x8167, 0x8169, 0x816b, 0x816d, 0x816f, 0x8171, 0x8173,
0x8175, 0x8177, 0x8179, 0x818f, 0x8190, 0x8191, 0x8192, 0x8197,
0x8198, 0x81a7, 0x81f2
};
static bool valid_first_char( char *p )
/*************************************/
{
int i;
unsigned short kanji_char;
if( GUICharLen( *p ) == 2 ) {
// Kanji
kanji_char = ( *p << 8 ) + *( p + 1 );
if( kanji_char < InvalidFirst[ 0 ]
|| kanji_char > InvalidFirst[ NUM_INVALID_FIRST - 1 ] ) {
// list is sorted
return( TRUE );
}
for( i = 0; i < NUM_INVALID_FIRST; ++i ) {
if( kanji_char == InvalidFirst[ i ] ) {
return( FALSE ); // invalid
} else if( kanji_char < InvalidFirst[ i ] ) {
return( TRUE );
}
}
return( TRUE );
} else {
return( FALSE );
}
}
static bool valid_last_char( char *p )
/************************************/
{
int i;
unsigned short kanji_char;
if( GUICharLen( *p ) == 2 ) {
// Kanji
kanji_char = ( *p << 8 ) + *( p + 1 );
if( kanji_char < InvalidLast[ 0 ]
|| kanji_char > InvalidLast[ NUM_INVALID_LAST - 1 ] ) {
// list is sorted
return( TRUE );
}
for( i = 0; i < NUM_INVALID_LAST; ++i ) {
if( kanji_char == InvalidLast[ i ] ) {
return( FALSE ); // invalid
} else if( kanji_char < InvalidLast[ i ] ) {
return( TRUE );
}
}
return( TRUE );
} else {
return( FALSE );
}
}
static char *find_break( char *text, DIALOG_INFO *dlg, int *chwidth )
/*******************************************************************/
{
char *e;
char *n;
char *br;
char *s;
int len;
gui_ord width;
int winwidth;
// Line endings are word breaks already
s = text;
while( *s && (*s != '\r') && (*s != '\n') ) s++;
len = s - text;
winwidth = dlg->wrap_width * CharWidth;
// Use string length as cutoff to avoid overflow on width
if( len < 2 * dlg->wrap_width ) {
width = GUIGetExtentX( MainWnd, text, len );
if( width < winwidth ) {
*chwidth = (width / CharWidth) + 1;
dlg->max_width = max( dlg->max_width, *chwidth );
return( text + len );
}
}
dlg->max_width = max( dlg->max_width, dlg->wrap_width );
*chwidth = dlg->max_width;
br = text;
for( e=text;; ) {
if( *e == '\0' )
return( text );
if( *e == '\\' && *( e + 1 ) == 'n' )
return( e );
n = e + GUICharLen( *e );
width = GUIGetExtentX( MainWnd, text, n - text );
if( width >= winwidth )
break;
// is this a good place to break?
if( *e == ' ' || *e == '\t' ) { // English
br = n;
} else if( valid_last_char( e ) && valid_first_char( n ) ) {
br = n;
}
e = n;
}
if( br == text )
return( e );
return( br );
}
static bool dialog_static( char *next, DIALOG_INFO *dlg )
/*******************************************************/
{
char *line;
int len;
char *text;
bool rc = TRUE;
char dummy_var[ DUMMY_VAR_SIZE ];
vhandle var_handle;
line = next; next = NextToken( line, '"' );
line = next; next = NextToken( line, '"' );
GUIStrDup( line, &text );
line = next; next = NextToken( line, ',' );
line = next; next = NextToken( line, ',' );
if( line == NULL || *line == '\0' || EvalCondition( line ) ) {
line = next; next = NextToken( line, ',' );
if( line != NULL ) {
// condition for visibility (dynamic)
GUIStrDup( line,
&dlg->curr_dialog->pVisibilityConds[ dlg->curr_dialog->num_controls ] );
}
MakeDummyVar( dummy_var );
// dummy_var allows control to have an id - used by dynamic visibility feature
var_handle = AddVariable( dummy_var );
if( text != NULL ) {
text = AddInstallName( text, TRUE );
len = strlen( text );
set_dlg_dynamstring( dlg->curr_dialog->controls, dlg->array.num-1,
text, var_handle, dlg->col_num, dlg->row_num, dlg->col_num + len );
dlg->max_width = max( dlg->max_width, dlg->col_num + len );
} else {
set_dlg_dynamstring( dlg->curr_dialog->controls, dlg->array.num-1,
"", var_handle, dlg->col_num, dlg->row_num, dlg->col_num + 0 );
}
} else {
rc = FALSE;
}
GUIMemFree( text );
return( rc );
}
static char * textwindow_wrap( char *text, DIALOG_INFO *dlg, bool convert_newline )
/*********************************************************************************/
// Makes newline chars into a string into \r\n combination.
// Frees passed in string and allocates new one.
{
char *big_buffer = NULL;
char *orig_index = NULL;
char *new_index = NULL;
char *break_candidate = NULL;
int chwidth;
bool new_line = TRUE;
if( text == NULL ) {
return( NULL );
}
big_buffer = GUIMemAlloc( strlen( text ) * 2 + 1 );
if( big_buffer == NULL ) {
return( NULL );
}
orig_index = text;
break_candidate = find_break( orig_index, dlg, &chwidth );
for( new_index = big_buffer; *orig_index != '\0'; orig_index++, new_index++ ) {
if( new_line ) {
while( *orig_index == '\t' || *orig_index == ' ' ) {
orig_index++;
}
}
if( ( convert_newline
&& *orig_index == '\\' && *(orig_index + 1) == 'n' )
|| ( !convert_newline && *orig_index == '\r' && *(orig_index + 1) == '\n' ) ) {
*new_index = '\r';
new_index++;
orig_index++;
*new_index = '\n';
break_candidate = find_break( orig_index + 1, dlg, &chwidth );
} else if( break_candidate != NULL
&& orig_index == break_candidate ) {
*new_index = '\r';
new_index++;
*new_index = '\n';
new_index++;
*new_index = *break_candidate;
break_candidate = find_break( orig_index + 1, dlg, &chwidth );
new_line = TRUE;
continue;
} else if( *orig_index == '\t' ) {
*new_index = ' ';
} else {
*new_index = *orig_index;
}
new_line = FALSE;
}
*new_index = '\0';
GUIMemFree( text );
GUIStrDup( big_buffer, &text );
GUIMemFree( big_buffer );
return( text );
}
static bool dialog_textwindow( char *next, DIALOG_INFO *dlg )
/***********************************************************/
{
char *line;
char *text;
char *file_name;
unsigned int rows;
bool rc = TRUE;
void *io;
struct stat buf;
char dummy_var[ DUMMY_VAR_SIZE ];
vhandle var_handle;
text = NULL;
line = next; next = NextToken( line, ',' );
rows = atoi( line );
if( rows > 0 ) {
rows -= 1;
}
line = next; next = NextToken( line, '"' );
line = next; next = NextToken( line, '"' );
if( line == NULL ) {
rc = FALSE;
} else {
if( *line == '@' ) {
GUIStrDup( line + 1, &file_name );
io = FileOpen( file_name, O_RDONLY + O_BINARY );
if( io != NULL ) {
FileStat( file_name, &buf );
text = GUIMemAlloc( buf.st_size + 1 ); // 1 for terminating null
if( text != NULL ) {
FileRead( io, text, buf.st_size );
text[ buf.st_size ] = '\0';
FileClose( io );
}
}
GUIMemFree( file_name );
text = textwindow_wrap( text, dlg, FALSE ); //VERY VERY SLOW!!!! Don't use large files!!!
// bottleneck is the find_break function
} else {
GUIStrDup( line, &text );
text = textwindow_wrap( text, dlg, TRUE );
}
line = next; next = NextToken( line, ',' );
line = next; next = NextToken( line, ',' );
if( ( line == NULL || *line == '\0' || EvalCondition( line ) ) && text != NULL ) {
line = next; next = NextToken( line, ',' );
if( line != NULL ) {
// condition for visibility (dynamic)
GUIStrDup( line,
&dlg->curr_dialog->pVisibilityConds[ dlg->curr_dialog->num_controls ] );
}
MakeDummyVar( dummy_var );
// dummy_var allows control to have an id - used by dynamic visibility feature
var_handle = AddVariable( dummy_var );
set_dlg_textwindow( dlg->curr_dialog->controls, dlg->array.num-1,
text, var_handle, C0, dlg->row_num, dlg->max_width + 2, rows,
GUI_VSCROLL );
dlg->curr_dialog->rows += rows;
dlg->row_num += rows;
#if defined( __DOS__ )
dlg->curr_dialog->rows += 2;
dlg->row_num += 2;
#endif
} else {
rc = FALSE;
}
GUIMemFree( text );
}
return( rc );
}
static bool dialog_dynamic( char *next, DIALOG_INFO *dlg )
/********************************************************/
{
int len;
char *line;
vhandle var_handle;
char *vbl_name;
char *text;
bool rc = TRUE;
line = next; next = NextToken( line, ',' );
GUIStrDup( line, &vbl_name );
line = next; next = NextToken( line, '"' );
line = next; next = NextToken( line, '"' );
var_handle = AddVariable( vbl_name );
GUIStrDup( line, &text );
line = next; next = NextToken( line, ',' );
line = next; next = NextToken( line, ',' );
if( line == NULL || *line == '\0' || EvalCondition( line ) ) {
if( text != NULL ) {
SetVariableByHandle( var_handle, text );
}
dlg->curr_dialog->pVariables[dlg->num_variables] = var_handle;
dlg->num_variables += 1;
len = strlen( text );
line = next; next = NextToken( line, ',' );
if( line != NULL ) {
// condition for visibility (dynamic)
GUIStrDup( line,
&dlg->curr_dialog->pVisibilityConds[ dlg->curr_dialog->num_controls ] );
}
dlg->max_width = max( dlg->max_width, max( len, 60 ) );
set_dlg_dynamstring( dlg->curr_dialog->controls, dlg->array.num-1,
text, VarGetId( var_handle ), C0, dlg->row_num, C0 + dlg->max_width );
} else {
rc = FALSE;
}
GUIMemFree( vbl_name );
GUIMemFree( text );
return( rc );
}
static bool dialog_pushbutton( char *next, DIALOG_INFO *dlg )
/***********************************************************/
{
char *line;
char *line_start;
int id;
bool def_ret;
bool rc = TRUE;
line_start = next; next = NextToken( line_start, ',' );
line = next; next = NextToken( line, ',' );
if( line == NULL || *line == '\0' || EvalCondition( line ) ) {
dlg->num_push_buttons += 1;
def_ret = FALSE;
if( *line_start == '.' ) {
++line_start;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?