00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "binToC.h"
00017 #include "pystub.h"
00018
00019
00020 static const int col_width = 11;
00021
00022
00023
00024
00025
00026
00027 BinToC::
00028 BinToC() :
00029 WithOutputFile(true, true, false)
00030 {
00031 clear_runlines();
00032 add_runline("input output.c");
00033 add_runline("input -o output.c");
00034 add_runline("input >output.c");
00035
00036 set_program_description
00037 ("bin2c is a simple utility program to read a disk file, presumably "
00038 "one with binary contents, and output a table that can be "
00039 "compiled via a C compiler to generate the same data. It's handy "
00040 "for portably importing binary data into a library or executable.");
00041
00042 add_option
00043 ("n", "name", 0,
00044 "Specify the name of the table that is generated.",
00045 &BinToC::dispatch_string, NULL, &_table_name);
00046
00047 add_option
00048 ("static", "", 0,
00049 "Flag the table with the keyword 'static'.",
00050 &BinToC::dispatch_none, &_static_table);
00051
00052 add_option
00053 ("string", "", 0,
00054 "Define the table suitablly to pass to a string constructor.",
00055 &BinToC::dispatch_none, &_for_string);
00056
00057 add_option
00058 ("o", "filename", 0,
00059 "Specify the filename to which the resulting C code will be written. "
00060 "If this option is omitted, the last parameter name is taken to be the "
00061 "name of the output file, or standard output is used if there are no "
00062 "other parameters.",
00063 &BinToC::dispatch_filename, &_got_output_filename, &_output_filename);
00064
00065 _table_name = "data";
00066 }
00067
00068
00069
00070
00071
00072
00073 void BinToC::
00074 run() {
00075 ifstream in;
00076 if (!_input_filename.open_read(in)) {
00077 nout << "Unable to read " << _input_filename << ".\n";
00078 exit(1);
00079 }
00080
00081 ostream &out = get_output();
00082 string static_keyword;
00083 if (_static_table) {
00084 static_keyword = "static ";
00085 }
00086
00087 string table_type = "const unsigned char ";
00088 string length_type = "const int ";
00089 if (_for_string) {
00090
00091
00092
00093 length_type = "const size_t ";
00094 }
00095
00096 out << "\n"
00097 << "/*\n"
00098 << " * This table was generated by the command:\n"
00099 << " *\n"
00100 << " * " << get_exec_command() << "\n"
00101 << " */\n\n"
00102 << static_keyword << table_type << _table_name << "[] = {";
00103 out << hex << setfill('0');
00104 int count = 0;
00105 int col = 0;
00106 unsigned int ch;
00107 ch = in.get();
00108 while (!in.fail() && !in.eof()) {
00109 if (col == 0) {
00110 out << "\n ";
00111 } else if (col == col_width) {
00112 out << ",\n ";
00113 col = 0;
00114 } else {
00115 out << ", ";
00116 }
00117 out << "0x" << setw(2) << ch;
00118 col++;
00119 count++;
00120 ch = in.get();
00121 }
00122 out << "\n};\n\n"
00123 << static_keyword << length_type << _table_name << "_len = "
00124 << dec << count << ";\n\n";
00125 }
00126
00127
00128
00129
00130
00131
00132 bool BinToC::
00133 handle_args(ProgramBase::Args &args) {
00134 if (args.size() == 2 && !_got_output_filename) {
00135
00136 _got_output_filename = true;
00137 _output_filename = args[1];
00138 args.pop_back();
00139 }
00140
00141 if (args.size() != 1) {
00142 nout << "You must specify exactly one input file to read on the command line.\n";
00143 return false;
00144 }
00145
00146 _input_filename = Filename::binary_filename(args[0]);
00147 return true;
00148 }
00149
00150
00151 int main(int argc, char *argv[]) {
00152
00153 pystub();
00154
00155 BinToC prog;
00156 prog.parse_command_line(argc, argv);
00157 prog.run();
00158 return 0;
00159 }