00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <unistd.h>
00024
00025 #include "analy_register.h"
00026 #include "asm.h"
00027 #include "htapp.h"
00028 #include "htatom.h"
00029 #include "htcfg.h"
00030 #include "htclipboard.h"
00031 #include "htcurses.h"
00032 #include "htexcept.h"
00033 #include "hthist.h"
00034 #include "htiobox.h"
00035 #include "htkeyb.h"
00036 #include "htidle.h"
00037 #include "htmenu.h"
00038 #include "htpal.h"
00039 #include "htinfo.h"
00040 #include "htreg.h"
00041 #include "htsys.h"
00042 #include "info/infoview.h"
00043 #include "log.h"
00044 #include "stddata.h"
00045
00046 char *htcopyrights[]=
00047 {
00048 ht_name" "ht_version" ("HT_SYS_NAME") "__TIME__" on "__DATE__,
00049 ht_copyright1,
00050 ht_copyright2,
00051 NULL
00052 };
00053
00054 static void add_file_history_entry(char *n)
00055 {
00056 ht_clist *hist=(ht_clist*)find_atom(HISTATOM_FILE);
00057 if (hist) insert_history_entry(hist, n, 0);
00058 }
00059
00060 typedef bool (*initfunc)();
00061 typedef void (*donefunc)();
00062
00063 struct initdonefunc {
00064 initfunc i;
00065 donefunc d;
00066 char *name;
00067 };
00068
00069 #define INITDONE(name) { init_##name, done_##name, #name }
00070
00071 initdonefunc initdone[] = {
00072 INITDONE(system),
00073 INITDONE(atom),
00074 INITDONE(string),
00075 INITDONE(data),
00076 INITDONE(pal),
00077 INITDONE(registry),
00078 INITDONE(keyb),
00079 INITDONE(idle),
00080 INITDONE(menu),
00081 INITDONE(hist),
00082 INITDONE(clipboard),
00083 INITDONE(obj),
00084 INITDONE(analyser),
00085 INITDONE(asm),
00086 INITDONE(stddata),
00087 INITDONE(cfg),
00088 INITDONE(app)
00089 };
00090
00091 int htstate;
00092
00093 static bool init()
00094 {
00095 for (htstate=0; htstate<(int)(sizeof initdone / sizeof initdone[0]); htstate++) {
00096 if (!initdone[htstate].i()) return false;
00097 }
00098 return true;
00099 }
00100
00101 static void done()
00102 {
00103 for (htstate--; htstate>=0; htstate--) {
00104 initdone[htstate].d();
00105 }
00106 }
00107
00108 static void load_file(char *fn, UINT mode)
00109 {
00110 char cfn[HT_NAME_MAX];
00111 char cwd[HT_NAME_MAX];
00112
00113 cwd[0] = 0;
00114 getcwd(cwd, sizeof cwd);
00115
00116 if (sys_common_canonicalize(cfn, fn, cwd, sys_is_path_delim)==0) {
00117 add_file_history_entry(cfn);
00118 ((ht_app*)app)->create_window_file(cfn, mode, true);
00119 }
00120 }
00121
00122
00123 #ifdef SPLINE_TEST
00124
00125 #include "htspline.h"
00126 #endif
00127
00128 static void show_help()
00129 {
00130 #ifdef SPLINE_TEST
00131 bounds b;
00132 b.x = 0; b.y = 0; b.w = 80; b.h = 23;
00133 ht_window *s=new ht_window();
00134 s->init(&b, "spline", FS_KILLER | FS_TITLE | FS_NUMBER | FS_MOVE, 0);
00135 b.w = 78;
00136 b.h = 21;
00137
00138
00139
00140 ht_spline_view *sv = new ht_spline_view();
00141 sv->init(&b, "test");
00142 s->insert(sv);
00143 ((ht_app*)app)->insert_window(s, AWT_LOG, 0, false, NULL);
00144 #else
00145 ((ht_app*)app)->create_window_help(MAGIC_HT_HELP, "Top");
00146 #endif
00147 }
00148
00149 static void show_version()
00150 {
00151 char **copyrights=htcopyrights;
00152 while (*copyrights) {
00153 printf("%s\n", *copyrights);
00154 copyrights++;
00155 }
00156 exit(0);
00157 }
00158
00159 static void params(int argc, char *argv[], bool started)
00160 {
00161 int escaped_params_start = 0;
00162
00163 int load_mode = FOM_BIN;
00164 bool showhelp = false;
00165
00166 #define PARAM_ERROR(a...) {if (started) LOG_EX(LOG_ERROR, a);}
00167 #define EXPECT_PARAMEND(b) if ((j+1)!=len) { PARAM_ERROR("syntax error in options"); b;}
00168 #define EXPECT_PARAMS(p, b) if (i+p+1 > argc) { PARAM_ERROR("syntax error in options"); b;}
00169 #define NOTHING ((void)(0))
00170 for (int i=1; i<argc; i++) {
00171 if (argv[i][0]=='-') {
00172 int len = strlen(argv[i]);
00173 if (len==1) PARAM_ERROR("unknown option: %s", argv[i]);
00174 if (argv[i][1]=='-') {
00175 if (len==2) {
00176
00177 escaped_params_start = i+1;
00178 break;
00179 }
00180 if (strcmp(argv[i], "--auto") == 0) {
00181 EXPECT_PARAMS(1, NOTHING) else {
00182 if (started) load_file(argv[i+1], FOM_AUTO);
00183 i++;
00184 }
00185 } else
00186 if (strcmp(argv[i], "--bin") == 0) {
00187 EXPECT_PARAMS(1, NOTHING) else {
00188 if (started) load_file(argv[i+1], FOM_BIN);
00189 i++;
00190 }
00191 } else
00192 if (strcmp(argv[i], "--help") == 0) {
00193 showhelp = true;
00194 } else
00195 if (strcmp(argv[i], "--project") == 0) {
00196 EXPECT_PARAMS(1, NOTHING) else {
00197 if (started) ((ht_app*)app)->project_opencreate(argv[i+1]);
00198 i++;
00199 }
00200 } else
00201 if (strcmp(argv[i], "--text") == 0) {
00202 EXPECT_PARAMS(1, NOTHING) else {
00203 if (started) load_file(argv[i+1], FOM_TEXT);
00204 i++;
00205 }
00206 } else
00207 if (strcmp(argv[i], "--version") == 0) {
00208 show_version();
00209 } else
00210 {
00211 PARAM_ERROR("unknown option: %s", argv[i]);
00212 }
00213 } else {
00214 for (int j=1; j<len; j++) {
00215 switch (argv[i][j]) {
00216 case 'A':
00217 load_mode = FOM_AUTO;
00218 break;
00219 case 'B':
00220 load_mode = FOM_BIN;
00221 break;
00222 case 'T':
00223 load_mode = FOM_TEXT;
00224 break;
00225 case 'a':
00226 EXPECT_PARAMEND(break);
00227 EXPECT_PARAMS(1, break);
00228 if (started) load_file(argv[i+1], FOM_AUTO);
00229 i++;
00230 break;
00231 case 'b':
00232 EXPECT_PARAMEND(break);
00233 EXPECT_PARAMS(1, break);
00234 if (started) load_file(argv[i+1], FOM_BIN);
00235 i++;
00236 break;
00237 case 'h':
00238 showhelp = true;
00239 break;
00240 case 'p':
00241 EXPECT_PARAMEND(break);
00242 EXPECT_PARAMS(1, break);
00243 if (started) ((ht_app*)app)->project_opencreate(argv[i+1]);
00244 i++;
00245 break;
00246 case 't':
00247 EXPECT_PARAMEND(break);
00248 EXPECT_PARAMS(1, break);
00249 if (started) load_file(argv[i+1], FOM_TEXT);
00250 i++;
00251 break;
00252 case 'v':
00253 show_version();
00254 break;
00255 default:
00256 PARAM_ERROR("unknown option: -%c", argv[i][j]);
00257 break;
00258 }
00259 }
00260 }
00261 } else {
00262 if (started) {
00263 load_file(argv[i], load_mode);
00264 }
00265 }
00266 }
00267 if (escaped_params_start && started) {
00268 char **s = &argv[escaped_params_start];
00269 while (*s) {
00270 load_file(*s, load_mode);
00271 s++;
00272 }
00273 }
00274 if (showhelp && started) show_help();
00275 }
00276
00277 #if defined(WIN32) || defined(__WIN32__)
00278 #define LEAN_AND_MEAN
00279 #include <windows.h>
00280 #endif
00281
00282 int main(int argc, char *argv[])
00283 {
00284 #if defined(WIN32) || defined(__WIN32__)
00285 HMODULE h = GetModuleHandle(NULL);
00286 GetModuleFileName(h, appname, sizeof appname-1);
00287 #else
00288 strncpy(appname, argv[0], sizeof appname-1);
00289 #endif
00290
00291 params(argc, argv, 0);
00292
00293 if (!init()) {
00294 int init_failed = htstate;
00295 done();
00296 printf("init(): fatal error in init_%s\n", initdone[init_failed].name);
00297 return 1;
00298 }
00299
00300 ((ht_app*)app)->sendmsg(msg_draw);
00301
00302 char **copyrights=htcopyrights;
00303 while (*copyrights) {
00304 LOG(*copyrights);
00305 copyrights++;
00306 }
00307 LOG("appname = %s", appname);
00308
00309 int systemconfig_version = 0;
00310 int systemconfig_magic = 0;
00311
00312 loadstore_result load;
00313 int error_info;
00314 if (!load_systemconfig(&load, &error_info)) {
00315 switch (load) {
00316 case LS_OK:
00317 break;
00318 case LS_ERROR_NOT_FOUND:
00319 LOG_EX(LOG_WARN, "couldn't load configuration file...");
00320 break;
00321 case LS_ERROR_READ:
00322 LOG_EX(LOG_ERROR, "couldn't read configuration file...");
00323 infobox("couldn't read configuration file...");
00324 break;
00325 case LS_ERROR_MAGIC:
00326 case LS_ERROR_FORMAT:
00327 LOG_EX(LOG_ERROR, "%s %s %s...", "current configuration file ("SYSTEM_CONFIG_FILE_NAME") has", "invalid", "magic");
00328 systemconfig_magic = true;
00329 break;
00330 case LS_ERROR_VERSION:
00331 LOG_EX(LOG_ERROR, "%s %s %s...", "current configuration file ("SYSTEM_CONFIG_FILE_NAME") has", "wrong", "version");
00332 if (error_info < ht_systemconfig_fileversion) {
00333 systemconfig_version = -1;
00334 } else {
00335 systemconfig_version = 1;
00336 }
00337 break;
00338 case LS_ERROR_CORRUPTED:
00339
00340 if (screen) delete screen;
00341 printf("\n\n\nfatal error loading configuration file (%s)", systemconfig_file);
00342 if (error_info) {
00343 printf(":\nerror near line %d\n", error_info);
00344 } else {
00345 printf(".\n");
00346 }
00347 printf("please try to delete it.\n");
00348 return 1;
00349 default: {assert(0);}
00350 }
00351 }
00352
00353 params(argc, argv, 1);
00354
00355 try {
00356 ((ht_app*)app)->run(false);
00357 } catch (ht_io_exception *x) {
00358 done();
00359 fprintf(stderr, "FATAL: %s: %s\n", "unhandled exception", x->what());
00360 return 1;
00361 } catch (std::exception *x) {
00362 done();
00363 fprintf(stderr, "FATAL: %s: %s\n", "unhandled exception", x->what());
00364 return 1;
00365 } catch (...) {
00366 done();
00367 fprintf(stderr, "FATAL: unknown %s !?\n", "unhandled exception");
00368 return 1;
00369 }
00370
00371 loadstore_result save=LS_OK;
00372 bool save_config = true;
00373
00374 if (systemconfig_magic) {
00375 if (confirmbox_modal("%s %s %s...\noverwrite it ?", "current configuration file ("SYSTEM_CONFIG_FILE_NAME") has", "wrong", "magic")!=button_ok) {
00376 save_config = false;
00377 }
00378 }
00379
00380 if (systemconfig_version < 0) {
00381 if (confirmbox_modal("%s %s %s...\noverwrite it ?", "current configuration file ("SYSTEM_CONFIG_FILE_NAME") has", "older", "version")!=button_ok) {
00382 save_config = false;
00383 }
00384 } else if (systemconfig_version > 0) {
00385 if (confirmbox_modal("%s %s %s...\noverwrite it ?", "current configuration file ("SYSTEM_CONFIG_FILE_NAME") has", "NEWER", "version")!=button_ok) {
00386 save_config = false;
00387 }
00388 }
00389
00390 if (save_config) {
00391 LOG("saving config...");
00392 save = save_systemconfig();
00393 }
00394 LOG("exit.");
00395 done();
00396 if (save!=LS_OK) {
00397 printf("save_systemconfig(): error\n");
00398 return 1;
00399 }
00400 return 0;
00401 }
00402