home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Borland Programmer's Resource
/
Borland_Programmers_Resource_CD_1995.iso
/
utils
/
resc
/
resconv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-18
|
68KB
|
2,295 lines
/*
*
* WinRes - OS/2 to Windows resource conversion utility
*
* RESCONV is a utility program used to convert OS/2 resources to
* Windows resources.
*
*/
#include "resconv.h"
#include "extdef.h"
int is_debug_on = FALSE; // JMH
/*
* The following string is printed when the user fails to supply
* sufficient information when running the program.
*/
static char usage_msg [] = "\
\n\
RESCONV - Resource Conversion Utility program\n\
\n\
Usage:\n\
RESCONV <OS/2 src_file> <Windows dst_file>\n\
";
static uchar search [] = {'~', 0};
static uchar replace [] = {'&', 0};
ushort cLineCurrent = 1; /* the current line number */
/*******************************************************************
* *
* LOWER_CASE_CHAR *
* *
* This procedure is called to convert a character from upper to *
* lower case. *
* *
*******************************************************************/
uchar lower_case_char (uchar ch)
{
/* Is it an upper case ASCII character? */
if (ch >= 'A' && ch <= 'Z')
return ch ^ (uchar) ' ';
/* It doesn't have a case. */
return ch;
}
/*******************************************************************
* *
* UPPER_CASE_CHAR *
* *
* This procedure is called to convert a character from lower to *
* upper case. *
* *
*******************************************************************/
uchar upper_case_char (uchar ch)
{
/* Is it a lower case ASCII character? */
if (ch >= 'a' && ch <= 'z')
return ch ^ (uchar) ' ';
/* It doesn't have a case. */
return ch;
}
/*******************************************************************
* *
* GET_CHAR_CASE *
* *
* This procedure is called to get the case of the character. *
* The procedure returns 0 if the character has no case, 1 if *
* the character is lower case, and 2 if the character is upper *
* case. *
* *
*******************************************************************/
ushort get_char_case (uchar ch)
{
/* Is it a lower case ASCII character? */
if (ch >= 'a' && ch <= 'z')
return char_case_lower;
/* Is it an upper case ASCII character? */
if (ch >= 'A' && ch <= 'Z')
return char_case_upper;
/* It doesn't have a case. */
return char_case_none;
}
/*******************************************************************
* *
* EQUAL_IGNORING_CASE *
* *
* Determines whether two strings of characters are identical, *
* ignoring the case of the characters. *
* *
*******************************************************************/
flag equal_ignoring_case (uchar ptr string1, uchar ptr string2)
{
register uchar a;
register uchar b;
if (string1 == NULL || string2 == NULL)
return FALSE;
/*
* Loop as long as both strings have some data. We quit if we find
* a mismatch in the strings.
*/
forever {
if ((a = *string1++) != (b = *string2++)) {
if (get_char_case (a) == char_case_lower)
a = upper_case_char (a);
if (get_char_case (b) == char_case_lower)
b = upper_case_char (b);
}
if (a != b)
return (FALSE);
if (a == 0)
return (TRUE);
}
}
/*******************************************************************
* *
* STRING_LENGTH *
* *
* Determines the length of a string of characters, not including *
* the final null. *
* *
*******************************************************************/
ushort string_length (uchar ptr string)
{
return (_fstrlen (string));
}
/*******************************************************************
* *
* STRING_COPY *
* *
* Copies the contents of one string of characters into another, *
* returning a pointer to the null terminator of the destination. *
* *
*******************************************************************/
void ptr string_copy (uchar ptr dest, uchar ptr source)
{
while (*source)
*dest++ = *source++;
*dest = 0;
return (dest);
}
/*******************************************************************
* *
* STRING_APPEND *
* *
* Copies the contents of one string of characters into another, *
* returning a pointer to the null terminator of the destination. *
* *
*******************************************************************/
void ptr string_append (uchar ptr dest, uchar ptr source)
{
while (*dest)
dest++;
while (*source)
*dest++ = *source++;
*dest = 0;
return (dest);
}
/*******************************************************************
* *
* STRING_REPLACE *
* *
* Searches the given string for characters in the search string. *
* Any characters found are replaced with the corresponding *
* character in the replace string. *
* *
*******************************************************************/
void string_replace (uchar ptr string, uchar ptr search, uchar ptr replace)
{
ushort len;
ushort length;
uchar ptr sp;
uchar ptr ep;
length = string_length (string);
while (*search) {
len = length;
sp = string;
while (ep = _fstrchr (sp, *search)) {
*ep = *replace;
len -= ep - sp + 1;
sp = &ep [1];
}
search++;
replace++;
}
}
/*******************************************************************
* *
* DOUBLE_AMPERSANDS *
* *
* Searches the given string for ampersands and doubles them, *
* so they will not be interpreted incorrectly as mnemonics *
* *
*******************************************************************/
void double_ampersands (uchar ptr string)
{
ushort length;
uchar ptr sp;
uchar ptr ep;
uchar ptr dp;
length = string_length (string);
ep = string;
for (ep = string; *ep; ep++) {
if (*ep == '&')
if (length+1 >= max_string_size)
report_error (err_string_too_long, 0, "doubling ampersands");
else {
dp = string+length+1;
sp = string+length;
while (sp >= ep)
*dp-- = *sp--;
*ep = '&';
length++;
ep++;
}
}
}
/**************************************************************************
* *
* REPORT_ERROR *
* *
* This procedure reports the indicated error and exits the program. *
* *
**************************************************************************/
void report_error (ushort error, ushort token, uchar ptr string)
{
uchar ptr msg;
/* Case on the error and print the message. */
switch (error) {
case err_full_put_char_buffer:
msg = "The put_char buffer is full.";
break;
case err_full_put_token_buffer:
msg = "The put_token buffer is full.";
break;
case err_no_source_file:
msg = "No source file is open.";
break;
case err_unexpected_comment_char:
msg = "Unexpected comment character.";
break;
case err_unexpected_eof:
msg = "Unexpected EOF.";
break;
case err_string_too_long:
msg = "The string is too long.";
break;
case err_identifier_too_long:
msg = "The identifier is too long.";
break;
case err_value_too_big:
msg = "The value is too large.";
break;
case err_invalid_syntax:
msg = "Invalid syntax.";
break;
case err_invalid_character:
msg = "Invalid character.";
break;
case err_bad_menu_option:
msg = "Invalid menu option. Line Omitted";
break;
case err_bad_load_option:
msg = "Invalid load option.";
break;
case err_bad_dialog_option:
msg = "Invalid dialog option.";
break;
case err_bad_control_class:
msg = "Invalid dialog control class.";
break;
case err_bad_accel_option:
msg = "Invalid accelerator table option.";
break;
case err_convert_resources:
msg = "Bad token found in convert_resources.";
break;
default:
msg = "Unknown error occurred.";
break;
}
if (string)
printf ("%s Token = %d Keyword = %s Line = %d \n",
msg, token, string, cLineCurrent);
else
printf ("%s Token = %d Line = %d\n", msg, token, cLineCurrent);
close_destination_file ();
terminate_input ();
exit(1);
}
/**************************************************************************
* *
* REPORT_WARNING *
* *
* This procedure reports the indicated warning. *
* *
**************************************************************************/
void report_warning (uchar ptr szerror, ushort token, uchar ptr string, long value)
{
/* Case on the error and print the message. */
if (string)
printf ("%s Token = %d Keyword = %s Line = %d \n",
szerror, token, string, cLineCurrent);
else if (value)
printf ("%s Token = %d Keyword = %d Line = %d \n",
szerror, token, value, cLineCurrent);
else
printf ("%s Token = %d Line = %d\n", szerror, token, cLineCurrent);
}
/***********************************************************************
* *
* CONVERT_TO_UPPER *
* *
* This procedure converts the character string to upper case. *
* *
***********************************************************************/
void ptr convert_to_upper (uchar ptr string)
{
uchar ptr sp; /* string pointer */
sp = string;
while (*sp) {
*sp = upper_case_char (*sp);
sp++;
}
return sp;
}
/**************************************************************************
* *
* CONVERT_RESOURCE *
* *
* This procedure is called to convert a resource statement. *
* *
**************************************************************************/
void convert_resource (void)
{
ushort token;
uchar ptr string;
long value;
/* Get the resource type identifier. */
if ((token = get_token ()) == tok_numeric)
value = current_token_value ();
else {
string = _fmalloc (string_length (current_token_string ()) + 1);
string_copy (string, current_token_string ());
}
/* Output the resource name identifier. */
if (get_token () == tok_numeric)
output_value (current_token_value ());
else
output_token (current_token_string ());
/* Output the resource type identifier. */
if (token == tok_numeric)
output_value (value);
else {
output_token (string);
_ffree (string);
}
/* Output the file name. */
if ((token = get_token ()) == tok_string)
output_string (current_token_string ());
else
output_token (current_token_string ());
}
/**************************************************************************
* *
* PROCESS_RCINCLUDE *
* *
* This procedure is called to process an rcinclude statement. *
* *
**************************************************************************/
void process_rcinclude (void)
{
ushort token;
/* Get the filename token and open the source file. */
token = get_token ();
open_source_file (current_token_string ());
}
/**************************************************************************
* *
* PROCESS_DLGINCLUDE *
* *
* This procedure is called to process an dlginclude statement. *
* *
**************************************************************************/
void process_dlginclude (void)
{
ushort token;
/* Get the id token */
token = get_token ();
token = get_token ();
/* someday should add byron's new support */
}
/**************************************************************************
* *
* CONVERT_STRINGTABLE *
* *
* This procedure is called to convert a stringtable statement. *
* *
* Syntax: *
* STRINGTABLE *
* BEGIN *
* stringid, string *
* END *
* *
**************************************************************************/
void convert_stringtable (void)
{
ushort token;
uchar ptr string;
/* Output the STRINGTABLE keyword. */
output_token ("STRINGTABLE");
/* Output the BEGIN keyword. */
output_newline ();
token = get_token ();
output_token ("BEGIN");
/*
* Until we've seen the END keyword or the EOF, output the information
* for each of the strings.
*/
while ((token = get_token ()) != tok_end && token != tok_eof) {
/*
* Output the string identifier.
*/
output_newline ();
output_tab (1);
if (token == tok_numeric)
output_value (current_token_value ());
else
output_token (current_token_string ());
/*
* Output the comma.
*/
output_token (",");
/*
* Output the string.
*/
token = get_token ();
if (token == tok_comma)
token = get_token();
string = current_token_string ();
double_ampersands(string);
string_replace (string, search, replace);
output_string (string);
}
/* Output the END keyword. */
output_newline ();
output_token ("END");
}
/**************************************************************************
* *
* CONVERT_POINTER *
* *
* This procedure is called to convert a pointer statement. *
* *
* Syntax: *
* idvalue CURSOR filename *
* *
**************************************************************************/
void convert_pointer (void)
{
ushort token;
ushort done;
/* Output the CURSOR keyword.
========================== */
output_token ("CURSOR");
/* Output the identifier value.
============================ */
token = get_token ();
if (token == tok_numeric)
output_value (current_token_value ());
else if (current_token_string() != NULL)
output_token (current_token_string ());
/* Output option keywords and then the file name.
============================================== */
done = 0;
while (!done) {
token = get_token ();
switch (token) {
case tok_preload:
output_token("PRELOAD");
break;
case tok_loadoncall:
output_token("LOADONCALL");
break;
case tok_fixed:
output_token("FIXED");
break;
case tok_moveable:
output_token("MOVEABLE");
break;
case tok_discardable:
output_token("DISCARDABLE");
break;
default:
if (current_token_string() != NULL)
output_token (current_token_string ());
done = 1;
break;
}
}
}
#define OPTIONSUBMENU 1
#define OPTIONSEPARATOR 2
/**************************************************************************
* *
* CONVERT_MENU_OPTIONS *
* *
* This procedure is called to convert menu item options. *
* returns OPTIONSUBMENU if it's submenu *
* returns OPTIONSEPARATOR if it's a separator *
* otherwise, returns 0. *
* *
**************************************************************************/
ushort convert_menu_options (uchar ptr buffer)
{
ushort token;
ushort ret = 0;
ushort error = 0;
/* While we have options, read and process them.
============================================= */
while ((token = get_token ()) == tok_comma || token == tok_bitor) {
/* Get the token to process.
========================= */
token = get_token ();
/* If we've encountered an error, don't bother to process.
======================================================= */
if (error)
continue;
/* Otherwise, process this option.
=============================== */
switch (token) {
case tok_mia_disabled:
if (buffer)
string_append(buffer, ", CHECKED");
else
output_token (", CHECKED");
break;
case tok_mia_checked:
if (buffer)
string_append(buffer, ", INACTIVE");
else
output_token (", INACTIVE");
break;
case tok_mis_bitmap:
report_warning("Warning -- MIS_BITMAP not supported. ", token, NULL, 0L);
error = 1;
break;
case tok_mis_breakseparator:
if (buffer)
string_append(buffer, ", MENUBARBREAK");
else
output_token (", MENUBARBREAK");
break;
case tok_mis_break:
if (buffer)
string_append(buffer, ", MENUBREAK");
else
output_token (", MENUBREAK");
break;
case tok_mis_ownerdraw:
if (buffer)
string_append(buffer, ", CHECKED");
else
output_token ("CHECKED");
break;
case tok_mis_separator:
ret = OPTIONSEPARATOR;
break;
case tok_mis_text:
break;
case tok_mis_submenu:
ret = OPTIONSUBMENU;
break;
case tok_mis_buttonseparator:
report_warning("Warning - MIS_BUTTONSEPARATOR not supported.", token, current_token_string(),0);
break;
case tok_mis_syscommand:
report_warning("Warning - MIS_SYSCOMMAND not supported.", token, current_token_string(),0);
error = 1;
break;
default:
// report_error (err_bad_menu_option, token, current_token_string ());
report_warning("Invalid menu option. Option omitted.", token, NULL, 0L);
error = 1;
break;
}
}
/* Put the last token back. */
put_token ();
return(ret);
}
/**************************************************************************
* *
* CONVERT_MENU_ITEMS *
* *
* This procedure is called to convert a menuitem statement. *
* *
* Syntax: *
* POPUP text, [option-list] *
* BEGIN *
* item-definitions *
* END *
* or *
* MENUITEM text, result, [option-list] *
* or *
* MENUITEM SEPARATOR *
* *
**************************************************************************/
void convert_menu_items (ushort level)
{
ushort token;
uchar ptr string;
uchar ptr buffer;
uchar ptr bufferTmp;
uchar buf[40];
uchar ptr buffer2;
ushort option;
/* Allocate buffer in case of MIS_SUBMENU.
======================================= */
buffer = _fmalloc (max_string_size);
buffer2 = _fmalloc (max_string_size);
/* Output the BEGIN keyword.
========================= */
output_newline ();
output_tab (level + 1);
token = get_token ();
output_token ("BEGIN");
/* Until we've seen the END keyword or the EOF, output the information
for each of the menu items.
=================================================================== */
while ((token = get_token ()) != tok_end && token != tok_eof) {
output_newline ();
output_tab (level + 1);
/* If this menu item has submenus, output the POPUP keyword.
========================================================= */
if (token == tok_submenu) {
output_token ("POPUP");
// Output the menu item name.
token = get_token ();
if ((string = current_token_string ()) == NULL)
string = ""; // was: string = current_token_string ();
double_ampersands(string);
string_replace (string, search, replace);
output_string (string);
// Get the comma and submenu identifier (which isn't used for
// windows).
token = get_token (); // Get the comma
if (token == tok_comma)
token = get_token (); // If it was the comma, get the id
else
put_token(); // If not a comma, put it back
// Get any terminating commas.
token = get_token();
if (token != tok_comma)
put_token();
// Convert the menu options.
convert_menu_options (NULL);
// Get the BEGIN keyword and convert the menu items.
convert_menu_items (level + 1);
}
/* If a regular item or separator, output the MENUITEM keyword.
============================================================ */
else if (token == tok_menuitem) {
string_copy (buffer, "MENUITEM ");
// See if this is a separator or menu text.
if ((token = get_token ()) == tok_separator) {
string_append (buffer, "SEPARATOR ");
}
else {
if ((string = current_token_string ()) == NULL)
string = "";
double_ampersands(string);
string_replace (string, search, replace);
// Save menu text in case of popup.
string_copy(buffer2, string);
string_append(buffer, "\"");
string_append (buffer, string);
string_append(buffer, "\"");
// Output the comma and menu identifier.
token = get_token ();
string_append (buffer, ", ");
token = get_token ();
if (token == tok_numeric) {
ltoa (current_token_value(), buf, 10);
string_append(buffer, buf);
} else {
if (bufferTmp = current_token_string ()) {
string_append(buffer, bufferTmp);
}
}
// Convert the options list.
option = convert_menu_options (buffer);
// If the options say it's a SUBMENU, make it a POPUP.
if (option == OPTIONSUBMENU) {
string_copy (buffer, "POPUP ");
string_append(buffer, "\"");
string_append(buffer, buffer2);
string_append(buffer, "\"");
output_token(buffer);
convert_menu_items(level+1);
}
// If the options say separator, make it so.
else if (option == OPTIONSEPARATOR)
output_token("MENUITEM SEPARATOR");
// Otherwise, just output the options.
else
output_token(buffer);
}
/* Unrecognized token in the menu description.
=========================================== */
} else {
report_error (err_bad_menu_option, token, current_token_string ());
}
/* Continue looping until we reach the END keyword or end-of-file.
=============================================================== */
}
/* Output the END keyword. */
output_newline ();
output_tab (level + 1);
output_token ("END");
_ffree (buffer);
_ffree (buffer2);
}
/**************************************************************************
* *
* CONVERT_MENU *
* *
* This procedure is called to convert a menu statement. *
* *
* Syntax: *
* menuid MENU [load-option] [mem-option] *
* BEGIN *
* item-definitions *
* END *
* *
**************************************************************************/
void convert_menu (void)
{
ushort token;
/* Output the menu identifier.
=========================== */
token = get_token ();
if (token == tok_numeric)
output_value (current_token_value ());
else if (current_token_string() != NULL)
output_token (current_token_string ());
/* Output the MENU keyword.
======================== */
output_token ("MENU");
/* Output any load and memory options.
=================================== */
while ((token = get_token ()) != tok_begin && token != tok_eof) {
switch (token) {
case tok_discardable:
output_token ("DISCARDABLE");
break;
case tok_fixed:
output_token ("FIXED");
break;
case tok_moveable:
output_token ("MOVEABLE");
break;
case tok_loadoncall:
output_token ("LOADONCALL");
break;
case tok_preload:
output_token ("PRELOAD");
break;
default:
report_error (err_bad_load_option, token, current_token_string ());
break;
}
}
/* Replace the BEGIN or eof token that caused us to exit the loop.
=============================================================== */
put_token ();
/* Convert the menu items.
======================= */
if (token != tok_eof)
convert_menu_items (0);
}
/**************************************************************************
* *
* CONVERT_HELPTABLE *
* *
* This procedure is called to convert a help table. *
* *
**************************************************************************/
void convert_helptable (void)
{
ushort token;
report_warning("Helptables not supported.", 0, NULL, 0);
for (token = get_token();
token != tok_end && token != tok_eof;
token = get_token())
;
}
/**************************************************************************
* *
* CONVERT_HELPSUBTABLE *
* *
* This procedure is called to convert a help table. *
* *
**************************************************************************/
void convert_helpsubtable (void)
{
ushort token;
report_warning("Helpsubtables not supported.", 0, NULL, 0);
for (token = get_token();
token != tok_end && token != tok_eof;
token = get_token())
;
}
/**************************************************************************
* *
* CONVERT_INCLUDE *
* *
* This procedure is called to convert an include statement. *
* *
**************************************************************************/
void convert_include (void)
{
ushort token;
uchar ptr string;
/* Get the filename. */
token = get_token ();
string = current_token_string ();
/*
* If this is the <os2.h> include file, we need to change it to <windows.h>.
* We also need to undefine a define because we need some defines that are
* not included.
*
* If this is not <os2.h>, output the #include and the filename.
*/
output_newline();
if (equal_ignoring_case (string, "<os2.h>")) {
output_token ("#undef RC_INVOKED");
output_newline ();
output_token ("#include");
output_token ("<windows.h>");
}
else {
output_token ("#include");
if (token == tok_string)
output_string (string);
else
output_token (string);
}
}
/**************************************************************************
* *
* CONVERT_ICON *
* *
* This procedure is called to convert an icon statement. *
* *
* Syntax: *
* idvalue ICON filename *
* *
**************************************************************************/
void convert_icon (void)
{
ushort token;
ushort done;
/* Output the ICON keyword. */
output_token ("ICON");
/* Output the identifier value. */
token = get_token ();
if (token == tok_numeric)
output_value (current_token_value ());
else if (token == tok_constant)
output_token (current_token_string ());
else if (current_token_string() != NULL)
output_string (current_token_string());
/* Output option keywords and then the file name.
============================================== */
done = 0;
while (!done) {
token = get_token ();
switch (token) {
case tok_preload:
output_token("PRELOAD");
break;
case tok_loadoncall:
output_token("LOADONCALL");
break;
case tok_fixed:
output_token("FIXED");
break;
case tok_moveable:
output_token("MOVEABLE");
break;
case tok_discardable:
output_token("DISCARDABLE");
break;
default:
if (current_token_string() != NULL)
output_token (current_token_string ());
done = 1;
break;
}
}
}
/**************************************************************************
* *
* CONVERT_DIALOG_OPTIONS *
* *
* This procedure is called to convert a dialog elements options. *
* *
**************************************************************************/
void convert_dialog_options (flag output)
{
ushort token;
/*
* Until we find the 'stopper' keywords or the EOF, output the option
* information.
*/
for (token = get_token();
token != tok_begin && token != tok_end && token != tok_eof &&
token != tok_ltext && token != tok_rtext && token != tok_ctext &&
token != tok_radiobutton && token != tok_autoradiobutton &&
token != tok_checkbox && token != tok_autocheckbox &&
token != tok_pushbutton && token != tok_defpushbutton &&
token != tok_listbox && token != tok_groupbox && token != tok_entryfield
&& token != tok_icon;
token = get_token()){
/*
* If we have output something, output a '|' before the next keyword.
*/
/*
* Output the option.
*/
switch (token) {
case tok_bs_autocheckbox:
if (output)
output_token ("|");
output_token ("BS_AUTOCHECKBOX");
output = TRUE;
break;
case tok_bs_autoradiobutton:
if (output)
output_token ("|");
output_token ("BS_AUTORADIOBUTTON");
output = TRUE;
break;
case tok_bs_checkbox:
if (output)
output_token ("|");
output_token ("BS_CHECKBOX");
output = TRUE;
break;
case tok_bs_default:
if (output)
output_token ("|");
output_token ("BS_DEFPUSHBUTTON");
output = TRUE;
break;
case tok_bs_help:
break;
case tok_bs_nopointerfocus:
break;
case tok_bs_pushbutton:
if (output)
output_token ("|");
output_token ("BS_PUSHBUTTON");
output = TRUE;
break;
case tok_bs_radiobutton:
if (output)
output_token ("|");
output_token ("BS_RADIOBUTTON");
output = TRUE;
break;
case tok_cbs_dropdown:
if (output)
output_token ("|");
output_token ("CBS_DROPDOWN");
output = TRUE;
break;
case tok_cbs_dropdownlist:
if (output)
output_token ("|");
output_token ("CBS_DROPDOWNLIST");
output = TRUE;
break;
case tok_cbs_simple:
if (output)
output_token ("|");
output_token ("CBS_SIMPLE");
output = TRUE;
break;
case tok_dt_bottom:
if (output)
output_token ("|");
output_token ("DT_TOP");
output = TRUE;
break;
case tok_dt_center:
if (output)
output_token ("|");
output_token ("DT_CENTER");
output = TRUE;
break;
case tok_dt_left:
if (output)
output_token ("|");
output_token ("DT_LEFT");
output = TRUE;
break;
case tok_dt_mnemonic:
break;
case tok_dt_right:
if (output)
output_token ("|");
output_token ("DT_RIGHT");
output = TRUE;
break;
case tok_dt_top:
if (output)
output_token ("|");
output_token ("DT_TOP");
output = TRUE;
break;
case tok_dt_vcenter:
if (output)
output_token ("|");
output_token ("DT_CENTER");
output = TRUE;
break;
case tok_dt_wordbreak:
if (output)
output_token ("|");
output_token ("DT_WORDBREAK");
output = TRUE;
break;
case tok_dt_halftone:
if (output)
output_token ("|");
output_token ("DT_HALFTONE");
output = TRUE;
break;
case tok_es_autoscroll:
if (output)
output_token ("|");
output_token ("ES_AUTOHSCROLL");
output = TRUE;
break;
case tok_es_center:
if (output)
output_token ("|");
output_token ("ES_CENTER");
output = TRUE;
break;
case tok_es_left:
if (output)
output_token ("|");
output_token ("ES_LEFT");
output = TRUE;
break;
case tok_es_margin:
break;
case tok_es_right:
if (output)
output_token ("|");
output_token ("ES_RIGHT");
output = TRUE;
break;
case tok_mls_vscroll:
if (output)
output_token ("|");
output_token ("ES_AUTOVSCROLL");
output = TRUE;
break;
case tok_mls_wordwrap:
break;
case tok_mls_border:
if (output)
output_token ("|");
output_token ("WS_BORDER");
output = TRUE;
break;
case tok_fcf_sysmenu:
if (output)
output_token ("|");
output_token ("WS_SYSMENU");
output = TRUE;
break;
case tok_fcf_titlebar:
if (output)
output_token ("|");
output_token ("WS_CAPTION");
output = TRUE;
break;
case tok_fs_border:
if (output)
output_token ("|");
output_token ("DS_MODALFRAME");
output = TRUE;
break;
case tok_fs_dlgborder:
case tok_fcf_dlgborder:
if (output)
output_token ("|");
output_token ("DS_MODALFRAME");
output = TRUE;
break;
case tok_fs_mousealign:
break;
case tok_fcf_icon:
case tok_fs_icon:
report_warning("Icon style on dialogs not supported.", token, current_token_string(), 0);
break;
case tok_fcf_minbutton:
report_warning("Minimize style on dialogs not supported.", token, current_token_string(), 0);
break;
case tok_fs_nobytealign:
case tok_fcf_nobytealign:
break;
case tok_ls_horzscroll:
if (output)
output_token ("|");
output_token ("WS_HSCROLL");
output = TRUE;
break;
case tok_ls_multiplesel:
if (output)
output_token ("|");
output_token ("LBS_MULTIPLESEL");
output = TRUE;
break;
case tok_ls_ownerdraw:
if (output)
output_token ("|");
output_token ("LBS_OWNERDRAWFIXED");
output = TRUE;
break;
case tok_sbs_horz:
if (output)
output_token ("|");
output_token ("SBS_HORZ");
output = TRUE;
break;
case tok_sbs_vert:
if (output)
output_token ("|");
output_token ("SBS_VERT");
output = TRUE;
break;
case tok_ss_icon:
case tok_ss_fgndframe:
case tok_ss_groupbox:
case tok_ss_halftoneframe:
/*
* This information was already output with the static
* style.
*/
break;
case tok_ss_text:
break;
case tok_ws_clipsiblings:
if (output)
output_token ("|");
output_token ("WS_CLIPSIBLINGS");
output = TRUE;
break;
case tok_ws_group:
if (output)
output_token ("|");
output_token ("WS_GROUP");
output = TRUE;
break;
case tok_ws_savebits:
if (output)
output_token ("|");
output_token ("CS_SAVEBITS");
output = TRUE;
break;
case tok_ws_tabstop:
if (output)
output_token ("|");
output_token ("WS_TABSTOP");
output = TRUE;
break;
case tok_ws_visible:
if (output)
output_token ("|");
output_token ("WS_VISIBLE");
output = TRUE;
break;
case tok_numeric:
report_warning ("Warning - Unknown window style.", token, NULL, current_token_value ());
output_value(current_token_value());
break;
case tok_string:
report_warning ("Warning - Unknown window style.", token, current_token_string (), 0);
output_string(current_token_string());
break;
case tok_comma:
put_token();
break; //JMH
default:
report_error (err_bad_dialog_option, token, current_token_string ());
break;
}
/*
* Skip over the '|' or ',' characters. If it isn't one of these
* two characters, exit.
*/
if ((token = get_token ()) != tok_bitor && token != tok_comma) {
put_token ();
return;
}
}
/* Put back the last token. */
put_token ();
}
/**************************************************************************
* *
* CONVERT_DLGTEMPLATE *
* *
* This procedure is called to convert a dlgtemplate statement. *
* *
* Syntax: *
* nameid DIALOG [load-option] [mem-option] x, y, width, height *
* [option-statements] *
* BEGIN *
* control-statements *
* END *
* *
**************************************************************************/
void convert_dlgtemplate (void)
{
ushort token;
uchar ptr string;
uchar ptr title;
long dlg_width, dlg_height;
long x, y, width, height;
ushort type;
ushort ctltype;
ushort fOutputOr;
/* Output the name identifier. */
token = get_token ();
output_token (current_token_string ());
/* Output the DIALOG keyword. */
output_token ("DIALOG");
/*
* Until we see the BEGIN keyword of the EOF, output the load and
* memory options.
*/
while ((token = get_token ()) != tok_begin && token != tok_eof) {
switch (token) {
case tok_discardable:
output_token ("DISCARDABLE");
break;
case tok_fixed:
output_token ("FIXED");
break;
case tok_moveable:
output_token ("MOVEABLE");
break;
case tok_loadoncall:
output_token ("LOADONCALL");
break;
case tok_preload:
output_token ("PRELOAD");
break;
default:
report_error (err_bad_load_option, token, current_token_string ());
break;
}
}
/* Skip over the DIALOG/FRAME keyword and make a copy of the title. */
type = get_token ();
token = get_token ();
title = _fmalloc (string_length (current_token_string ()) + 1);
string_copy (title, current_token_string ());
/* Skip over the comma, second dialog identifier, and another comma. */
token = get_token ();
token = get_token ();
token = get_token ();
/* Output the x, y, width, and height values. */
output_newline ();
output_tab (2);
token = get_token ();
x = current_token_value ();
output_value (x);
token = get_token ();
output_token (",");
token = get_token ();
y = current_token_value ();
output_value (y);
token = get_token ();
output_token (",");
token = get_token ();
dlg_width = current_token_value ();
output_value ((long) ((double) dlg_width * .8));
token = get_token ();
output_token (",");
token = get_token ();
dlg_height = current_token_value ();
output_value (dlg_height);
token = get_token ();
/* Output the dialog title. */
output_newline ();
output_tab (2);
output_token ("CAPTION");
output_string (title);
_ffree (title);
/* Output the dialog style information. */
output_newline ();
output_tab (2);
output_token ("STYLE");
convert_dialog_options (FALSE);
if (type == tok_frame)
output_token (" | WS_CHILD");
/* Output the BEGIN keyword. */
output_newline ();
output_tab (1);
token = get_token ();
output_token ("BEGIN");
/*
* While there are still control statements in the dialog, convert them.
* Syntax:
* CONTROL text, id, class, style, x, y, width, height
*/
for (token = get_token();
token != tok_end && token != tok_eof;
token = get_token()){
/*
* Output the CONTROL keyword.
*/
output_newline ();
output_tab (2);
output_token ("CONTROL");
ctltype = token;
/*
* Output the text and a comma.
*/
/* listboxes don't have text */
if (ctltype == tok_listbox)
output_string("");
else {
token = get_token ();
string = current_token_string ();
/* check for ICON case, where text can be a constant */
if (token == tok_constant)
output_token(string);
else {
double_ampersands(string);
string_replace (string, search, replace);
output_string (string);
}
/* get the following comma */
token = get_token ();
if (token != tok_comma)
put_token();
}
output_token (",");
/*
* Output the control identifier and a comma.
*/
token = get_token ();
if (token == tok_numeric)
output_value (current_token_value ());
else if (token == tok_did_ok)
output_token("IDOK");
else if (token == tok_did_cancel)
output_token("IDCANCEL");
else
output_token (current_token_string ());
token = get_token ();
output_token (",");
/*
* The next four fields are x, y, width, and height. We need to save
* these off because they are output after the class and style options.
*/
token = get_token ();
x = current_token_value ();
token = get_token ();
token = get_token ();
y = current_token_value ();
token = get_token ();
token = get_token ();
width = current_token_value ();
token = get_token ();
token = get_token ();
height = current_token_value ();
/* if next thing is a comma, get it */
token = get_token ();
if (token != tok_comma)
put_token();
/*
* If using CONTROL syntax, the next option will be the control class.
* If using alternate syntax, fake code into believing there is a style.
*/
if (ctltype == tok_control){
type = token = get_token ();
}
else
type = token = ctltype;
fOutputOr = FALSE;
if (token == wc_static) {
/*
* Get the comma and the type of static item.
*/
token = get_token ();
token = get_token ();
switch (token) {
case tok_ss_fgndframe:
output_token ("STATIC, SS_GRAYFRAME ");
fOutputOr = TRUE;
break;
case tok_ss_groupbox:
output_token ("BUTTON, BS_GROUPBOX");
fOutputOr = TRUE;
break;
case tok_ss_halftoneframe:
output_token ("STATIC, SS_GRAYFRAME");
fOutputOr = TRUE;
break;
case tok_ss_text:
output_token ("STATIC,");
break;
case tok_ss_icon:
output_token ("STATIC, SS_ICON");
fOutputOr = TRUE;
break;
default:
report_error (err_bad_control_class, token, current_token_string ());
break;
}
/*
* Put the static type back to make parsing consistent in
* convert_dialog_options. However, since we've already output
* the information here, convert_dialog_options will just ignore
* the ss_xxx tokens.
*/
put_token ();
output_newline ();
output_tab (3);
}
else {
switch(token) {
case tok_icon:
output_token ("STATIC, SS_ICON");
fOutputOr = TRUE;
break;
case tok_ltext:
output_token ("STATIC, DT_LEFT");
fOutputOr = TRUE;
break;
case tok_rtext:
output_token ("STATIC, DT_RIGHT");
fOutputOr = TRUE;
break;
case tok_ctext:
output_token ("STATIC, DT_CENTER");
fOutputOr = TRUE;
break;
case tok_radiobutton:
output_token ("BUTTON, BS_RADIOBUTTON");
fOutputOr = TRUE;
break;
case tok_autoradiobutton:
output_token ("BUTTON, BS_AUTORADIOBUTTON");
fOutputOr = TRUE;
break;
case tok_checkbox:
output_token ("BUTTON, BS_CHECKBOX");
fOutputOr = TRUE;
break;
case tok_autocheckbox:
output_token ("BUTTON, BS_AUTOCHECKBOX");
fOutputOr = TRUE;
break;
case tok_pushbutton:
output_token ("BUTTON, BS_PUSHBUTTON");
fOutputOr = TRUE;
break;
case tok_defpushbutton:
output_token ("BUTTON, BS_DEFPUSHBUTTON");
fOutputOr = TRUE;
break;
case tok_groupbox:
output_token ("BUTTON, BS_GROUPBOX");
fOutputOr = TRUE;
break;
case wc_button:
output_token ("BUTTON,");
break;
case wc_combobox:
output_token ("COMBOBOX,");
break;
case wc_mle:
output_token ("EDIT, ES_MULTILINE");
fOutputOr = TRUE;
height += 2;
break;
case tok_entryfield:
type = wc_entryfield;
case wc_entryfield:
output_token ("EDIT, WS_BORDER");
fOutputOr = TRUE;
height += 2;
break;
case tok_listbox:
type = wc_listbox;
case wc_listbox:
output_token ("LISTBOX, LBS_NOTIFY | WS_BORDER | WS_VSCROLL");
fOutputOr = TRUE;
break;
case wc_scrollbar:
output_token ("SCROLLBAR,");
break;
case tok_string:
report_warning ("Warning - Unknown control class.", token, current_token_string (), 0);
output_string (current_token_string());
output_token (",");
type = wc_static;
break;
default:
report_error (err_bad_control_class, token, current_token_string ());
break;
}
/*
* Get the comma and output a newline.
*/
token = get_token ();
if (token != tok_comma)
put_token();
output_newline ();
output_tab (3);
}
/*
* Output the style options.
*/
convert_dialog_options (fOutputOr);
output_token (",");
output_newline ();
output_tab (3);
/*
* Now we can output the x, y, width, and height information.
*/
output_value ((long) ((double) x * .8));
output_token (",");
if (type == wc_listbox)
output_value (dlg_height - y - height + 2);
else
output_value (dlg_height - y - height);
output_token (",");
output_value ((long) ((double) width * .8));
output_token (",");
if (type == wc_entryfield)
output_value (height + 2);
else
output_value (height);
}
/* Output the END keyword. */
output_newline ();
output_tab (1);
token = get_token ();
output_token ("END");
}
/**************************************************************************
* *
* CONVERT_BITMAP *
* *
* This procedure is called to convert a bitmap statement. *
* *
* Syntax: *
* idvalue BITMAP filename *
* *
**************************************************************************/
void convert_bitmap (void)
{
ushort token;
ushort done;
/* Output the identifier value.
============================ */
token = get_token ();
if (token == tok_numeric)
output_value (current_token_value ());
else if (current_token_string() != NULL)
output_token (current_token_string ());
/* Output the PM12BITMAP keyword.
============================== */
output_token ("BITMAP");
/* Output option keywords and then the file name.
============================================== */
done = 0;
while (!done) {
token = get_token ();
switch (token) {
case tok_preload:
output_token("PRELOAD");
break;
case tok_loadoncall:
output_token("LOADONCALL");
break;
case tok_fixed:
output_token("FIXED");
break;
case tok_moveable:
output_token("MOVEABLE");
break;
case tok_discardable:
output_token("DISCARDABLE");
break;
default:
if (current_token_string() != NULL)
output_token (current_token_string ());
done = 1;
break;
}
}
}
/**************************************************************************
* *
* CONVERT_ACCELTABLE *
* *
* This procedure is called to convert an acceltable statement. *
* *
* Syntax: *
* acctablename ACCELERATORS *
* BEGIN *
* event, idvalue, [type] [NOINVERT] [ALT] [SHIFT] [CONTROL] *
* *
* *
**************************************************************************/
void convert_acceltable (void)
{
ushort token; /* token type */
uchar ptr string;
ushort fControl = FALSE;
/* Get the table identifier. */
get_token ();
output_token (current_token_string ());
/* Output the ACCELERATOR and BEGIN keywords. */
output_token ("ACCELERATORS");
output_newline ();
output_token ("BEGIN");
/*
* Windows doesn't have any load options, so scan through any that might
* be associated with the OS/2 definition.
*/
while ((token = get_token ()) != tok_begin && token != tok_eof);
/*
* Until we've seen the END keyword or the EOF, output the information
* for each of the accelerators.
*/
while ((token = get_token ()) != tok_end && token != tok_eof) {
/*
* Output the event.
*/
output_newline ();
output_tab (1);
if (token == tok_numeric)
output_value (current_token_value ());
else {
string = current_token_string ();
if (token == tok_string) {
if (*string == '^'){
string_copy(string, string+1);
fControl = TRUE;
}
else
fControl = FALSE;
convert_to_upper (string);
output_string (string);
}
else if (equal_ignoring_case (string, "VK_BACKSPACE"))
output_token ("VK_BACK");
else
output_token (string);
}
/*
* Output the comma.
*/
token = get_token ();
output_token (",");
/*
* Output the idvalue.
*/
token = get_token ();
if (token == tok_numeric)
output_value (current_token_value ());
else
output_token (current_token_string ());
if ((token = get_token ()) == tok_plus) {
output_token ("+");
token = get_token ();
output_value (current_token_value ());
token = get_token ();
}
/*
* We want to make everything a virtual key, so output VERTKEY.
*/
output_token (",");
output_token ("VIRTKEY");
/*
* While there are still commas, interpret the modifiers.
*/
while (token == tok_comma) {
/*
* Output the modifier.
*/
token = get_token ();
switch (token) {
case tok_alt:
output_token (",");
output_token ("ALT");
break;
case tok_char:
output_token (",");
output_token ("ASCII");
break;
case tok_control:
output_token (",");
output_token ("CONTROL");
break;
case tok_shift:
output_token (",");
output_token ("SHIFT");
break;
case tok_virtualkey:
/*
* Everything is already a virtual key, so don't ouput
* anything.
*/
break;
case tok_syscommand:
report_warning("Warning - SYSCOMMAND accels not supported.", token, current_token_string(), 0);
break;
default:
report_error (err_bad_accel_option, token, current_token_string ());
break;
}
token = get_token ();
}
if (fControl) {
output_token (",");
output_token ("CONTROL");
fControl = FALSE;
}
put_token ();
}
/* Output the END keyword. */
output_newline ();
output_token ("END");
}
/**************************************************************************
* *
* CONVERT_RESOURCES *
* *
* This procedure is called to parse the OS/2 resource file and convert *
* it into a Windows resource file. *
* *
**************************************************************************/
void convert_resources (void)
{
ushort token; /* input token */
/* While there are still input tokens, process them. */
while ((token = get_token ()) != tok_eof) {
switch (token) {
case tok_acceltable:
output_newline ();
convert_acceltable ();
output_newline ();
break;
case tok_bitmap:
convert_bitmap ();
output_newline ();
break;
case tok_dlgtemplate:
output_newline ();
convert_dlgtemplate ();
output_newline ();
break;
case tok_helptable:
convert_helptable();
break;
case tok_helpsubtable:
convert_helpsubtable();
break;
case tok_icon:
convert_icon ();
output_newline ();
break;
case tok_include:
convert_include ();
output_newline ();
break;
case tok_menu:
output_newline ();
convert_menu ();
output_newline ();
break;
case tok_pointer:
convert_pointer ();
output_newline ();
break;
case tok_rcinclude:
process_rcinclude ();
output_newline ();
break;
case tok_resource:
convert_resource ();
output_newline ();
break;
case tok_stringtable:
output_newline ();
convert_stringtable ();
output_newline ();
break;
case tok_dlginclude:
process_dlginclude();
break;
default:
report_error (err_convert_resources, token, current_token_string ());
break;
}
}
}
/**************************************************************************
* *
* PROCESS_PARAMS *
* *
* This procedure is called to parse the parameter string and do *
* the right thing. *
* *
**************************************************************************/
flag process_params (int argc, char *argv [])
{
uchar ptr src_fname; /* source filename */
uchar ptr dst_fname; /* destination filename */
/* Skip over our program name. */
argc--;
argv++;
//JMH Is there a debug flag?
if (*(*argv) == '-')
{
is_debug_on = TRUE;
argc--;
argv++;
}
/* We must have a source file name. */
if (argc < 1) {
printf ("Incorrect usage: A source file name is required.\n");
printf (usage_msg);
return FALSE;
}
src_fname = *argv++;
argc--;
/* We must have a destination file name. */
if (argc < 1) {
printf ("Incorrect usage: A destination file name is required.\n");
printf (usage_msg);
return FALSE;
}
dst_fname = *argv++;
argc--;
/* We should not have any more parameters. */
if (argc != 0) {
printf ("Incorrect usage: Extra parameters found on command line\n");
printf (usage_msg);
return FALSE;
}
/* Open the source and destination files. */
if (cant open_source_file (src_fname) ||
cant open_destination_file (dst_fname))
return FALSE;
/* Success. */
return TRUE;
}
/**************************************************************************
* *
* MAIN *
* *
* This procedure is called by the system when the program is executed. *
* *
**************************************************************************/
void main (int argc, char *argv [])
{
/* Do some initialization. */
//_asm int 03h // put this line for debug break on entry
initialize_input ();
/* Process the startup parameters and convert the resources. */
if (process_params (argc, argv))
convert_resources ();
/* Do some cleanup. */
close_destination_file ();
terminate_input ();
}