/* * * 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 \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 include file, we need to change it to . * We also need to undefine a define because we need some defines that are * not included. * * If this is not , output the #include and the filename. */ output_newline(); if (equal_ignoring_case (string, "")) { output_token ("#undef RC_INVOKED"); output_newline (); output_token ("#include"); output_token (""); } 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 (); }