Panda3D
|
00001 // Filename: build_patch.cxx 00002 // Created by: 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "pandabase.h" 00016 #ifndef HAVE_GETOPT 00017 #include "gnu_getopt.h" 00018 #else 00019 #include <getopt.h> 00020 #endif 00021 #include "patchfile.h" 00022 #include "filename.h" 00023 00024 void 00025 usage() { 00026 cerr << "Usage: build_patch [opts] <old_file> <new_file>" << endl; 00027 } 00028 00029 void 00030 help() { 00031 usage(); 00032 cerr << "\n" 00033 "This program generates a patch file that describes the differences\n" 00034 "between any two source files. The patch file can later be used to\n" 00035 "construct <new_file>, given <old_file>. Arbitrary file types, including\n" 00036 "binary files, are supported.\n\n" 00037 00038 "The patching algorithm can get very slow for very large files. As an\n" 00039 "optimization, if the input files are both Panda Multifiles, the patcher\n" 00040 "will by default patch them on a per-subfile basis, which has the potential\n" 00041 "to be much faster. The -c option will forbid this and force the patcher\n" 00042 "to work on the full file.\n\n" 00043 00044 "Options:\n\n" 00045 00046 " -o output_name\n" 00047 " Specify the filename of the patch file to generate.\n\n" 00048 00049 " -c\n" 00050 " Always generate patches against the complete file, even if the\n" 00051 " input files appear to be multifiles.\n\n" 00052 00053 " -f footprint_length\n" 00054 " Specify the footprint length for the patching algorithm.\n\n"; 00055 } 00056 00057 int 00058 main(int argc, char *argv[]) { 00059 Filename patch_file; 00060 bool complete_file = false; 00061 int footprint_length = 0; 00062 00063 // extern char *optarg; 00064 extern int optind; 00065 static const char *optflags = "o:cf:h"; 00066 int flag = getopt(argc, argv, optflags); 00067 Filename rel_path; 00068 while (flag != EOF) { 00069 switch (flag) { 00070 case 'o': 00071 patch_file = optarg; 00072 break; 00073 00074 case 'c': 00075 complete_file = true; 00076 break; 00077 00078 case 'f': 00079 footprint_length = atoi(optarg); 00080 break; 00081 00082 case 'h': 00083 help(); 00084 return 1; 00085 case '?': 00086 usage(); 00087 return 1; 00088 default: 00089 cerr << "Unhandled switch: " << flag << endl; 00090 break; 00091 } 00092 flag = getopt(argc, argv, optflags); 00093 } 00094 argc -= (optind - 1); 00095 argv += (optind - 1); 00096 00097 if (argc < 3) { 00098 usage(); 00099 return 1; 00100 } 00101 00102 Filename src_file = Filename::from_os_specific(argv[1]); 00103 src_file.set_binary(); 00104 00105 Filename dest_file = Filename::from_os_specific(argv[2]); 00106 dest_file.set_binary(); 00107 00108 if (patch_file.empty()) { 00109 patch_file = dest_file.get_fullpath() + ".pch"; 00110 } 00111 Patchfile pfile; 00112 00113 pfile.set_allow_multifile(!complete_file); 00114 if (footprint_length != 0) { 00115 cerr << "Footprint length is " << footprint_length << "\n"; 00116 pfile.set_footprint_length(footprint_length); 00117 } 00118 00119 cerr << "Building patch file to convert " << src_file << " to " 00120 << dest_file << endl; 00121 if (pfile.build(src_file, dest_file, patch_file) == false) { 00122 cerr << "build patch failed" << endl; 00123 return 1; 00124 } 00125 00126 return 0; 00127 }