Skip to content

Commit d00ffb2

Browse files
mrorigoemoon
andauthored
Add command-line rocketfile autoload functionality (#175)
* Add command-line rocketfile autoload functionality - Added command-line argument parsing for .rocket/.xml files - Implemented autoload on startup for Linux and macOS platforms - Added Editor_setLoadedFilename() and Editor_getTrackData() APIs - Cross-platform support with proper error handling - Maintains backward compatibility with existing behavior - Graceful error handling with user-friendly dialogs Usage: ./RocketEditor path/to/file.rocket * Add shared argument parser and Windows support - Create args.c/args.h with cross-platform argument parsing - Support --load/-l flag and bare .rocket/.xml filenames - Update Linux, macOS, and Windows to use shared parser - All platforms now support: RocketEditor --load file.rocket or simply: RocketEditor file.rocket --------- Co-authored-by: Daniel Collin <daniel@collin.com>
1 parent 104a7a5 commit d00ffb2

File tree

7 files changed

+162
-5
lines changed

7 files changed

+162
-5
lines changed

src/Editor.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "rlog.h"
2323
#if defined(_WIN32)
2424
#include <Windows.h>
25-
//#include <winsock2.h>
2625
#else
2726
#include <arpa/inet.h>
2827
#include <netinet/in.h>
@@ -136,6 +135,19 @@ void setMostRecentFile(const text_t* filename) {
136135
Window_populateRecentList((const text_t**)s_recentFiles);
137136
}
138137

138+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
139+
140+
void Editor_setLoadedFilename(const text_t* filename) {
141+
s_loadedFilename = (text_t*)filename;
142+
setMostRecentFile(filename);
143+
}
144+
145+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
146+
147+
struct TrackData* Editor_getTrackData(void) {
148+
return &s_editorData.trackData;
149+
}
150+
139151
//
140152

141153
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

src/Editor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ void Editor_loadRecentFile(int file);
1919
bool Editor_saveBeforeExit(void);
2020
bool Editor_needsSave(void);
2121

22+
void Editor_setLoadedFilename(const text_t* filename);
23+
struct TrackData* Editor_getTrackData(void);
2224
text_t** Editor_getRecentFiles(void);
2325

2426
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

src/args.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "args.h"
2+
#include <string.h>
3+
4+
#if defined(_WIN32)
5+
#include <windows.h>
6+
#define STRCMP wcscmp
7+
#define STRICMP _wcsicmp
8+
#define STRLEN wcslen
9+
#define STR(s) L##s
10+
#else
11+
#include <strings.h>
12+
#define STRCMP strcmp
13+
#define STRICMP strcasecmp
14+
#define STRLEN strlen
15+
#define STR(s) s
16+
#endif
17+
18+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19+
20+
static int hasExtension(const text_t* path, const text_t* ext) {
21+
size_t pathLen = STRLEN(path);
22+
size_t extLen = STRLEN(ext);
23+
if (pathLen < extLen) return 0;
24+
return STRICMP(path + pathLen - extLen, ext) == 0;
25+
}
26+
27+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28+
29+
void Args_parse(Args* args, int argc, const text_t* const* argv) {
30+
args->loadFile = NULL;
31+
32+
for (int i = 1; i < argc; i++) {
33+
// Check for --load or -l flag
34+
if ((STRCMP(argv[i], STR("--load")) == 0 || STRCMP(argv[i], STR("-l")) == 0) && i + 1 < argc) {
35+
args->loadFile = argv[i + 1];
36+
return;
37+
}
38+
// Check for bare filename (ends with .rocket or .xml)
39+
if (hasExtension(argv[i], STR(".rocket")) || hasExtension(argv[i], STR(".xml"))) {
40+
args->loadFile = argv[i];
41+
return;
42+
}
43+
}
44+
}

src/args.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
#include <emgui/Types.h>
4+
5+
// Parsed command line arguments
6+
typedef struct Args {
7+
const text_t* loadFile; // File to load on startup (NULL if none)
8+
} Args;
9+
10+
// Parse command line arguments
11+
// argc/argv should be in the native format for the platform
12+
// On Windows: use CommandLineToArgvW to get wide strings
13+
// On Linux/macOS: use standard argc/argv
14+
void Args_parse(Args* args, int argc, const text_t* const* argv);

src/linux/main.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
#include <emgui/Emgui.h>
44
#include <emgui/GFXBackend.h>
55
#include <stdio.h>
6+
#include <string.h>
7+
#include "args.h"
8+
#include "loadsave.h"
69
#include "Editor.h"
710
#include "Menu.h"
811
#ifdef HAVE_GTK
@@ -415,6 +418,10 @@ void loadRecents() {
415418
}
416419

417420
int main(int argc, char* argv[]) {
421+
// Store original argc/argv before GTK initialization
422+
int original_argc = argc;
423+
char** original_argv = argv;
424+
418425
#ifdef HAVE_GTK
419426
gtk_init(&argc, &argv);
420427
#endif
@@ -449,6 +456,21 @@ int main(int argc, char* argv[]) {
449456
EMGFXBackend_updateViewPort(800, 600);
450457
Editor_setWindowSize(800, 600);
451458

459+
// Check for rocket file argument and load it
460+
{
461+
Args args;
462+
Args_parse(&args, original_argc, (const text_t* const*)original_argv);
463+
464+
if (args.loadFile) {
465+
if (LoadSave_loadRocketXML(args.loadFile, Editor_getTrackData())) {
466+
Editor_setLoadedFilename(args.loadFile);
467+
} else {
468+
Dialog_showError("Failed to load rocket file");
469+
fprintf(stderr, "Failed to load rocket file: %s\n", args.loadFile);
470+
}
471+
}
472+
}
473+
452474
run(window);
453475

454476
saveRecents();

src/macosx/RocketAppDelegate.m

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#import "RocketAppDelegate.h"
2+
#include "../args.h"
3+
#include "../loadsave.h"
24
#include "../Editor.h"
35
#include "../RemoteConnection.h"
46
#include "rlog.h"
@@ -16,7 +18,7 @@ @implementation RocketAppDelegate
1618
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
1719
{
1820
NSUInteger exitcode = NSTerminateNow;
19-
21+
2022
if (!Editor_needsSave())
2123
return exitcode;
2224

@@ -46,7 +48,7 @@ - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sende
4648

4749
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4850

49-
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
51+
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
5052
{
5153
char** recent_list = Editor_getRecentFiles();
5254

@@ -69,13 +71,43 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
6971
}
7072
}
7173

74+
// Check for rocket file argument and load it
75+
NSArray* arguments = [[NSProcessInfo processInfo] arguments];
76+
NSUInteger argCount = [arguments count];
77+
78+
if (argCount > 1) {
79+
// Convert NSArray to C array for Args_parse
80+
const char** argv = malloc(argCount * sizeof(char*));
81+
for (NSUInteger i = 0; i < argCount; i++) {
82+
argv[i] = [[arguments objectAtIndex:i] UTF8String];
83+
}
84+
85+
Args args;
86+
Args_parse(&args, (int)argCount, argv);
87+
88+
if (args.loadFile) {
89+
if (LoadSave_loadRocketXML(args.loadFile, Editor_getTrackData())) {
90+
Editor_setLoadedFilename(args.loadFile);
91+
} else {
92+
NSAlert* alert = [[NSAlert alloc] init];
93+
[alert setMessageText:@"Failed to load rocket file"];
94+
[alert setInformativeText:[NSString stringWithFormat:@"Could not load file: %s", args.loadFile]];
95+
[alert setAlertStyle:NSWarningAlertStyle];
96+
[alert runModal];
97+
[alert release];
98+
}
99+
}
100+
101+
free(argv);
102+
}
103+
72104
Window_buildMenu();
73105
Window_populateRecentList(recent_list);
74106
}
75107

76108
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
77109

78-
- (IBAction) buttonClicked:(id)sender
110+
- (IBAction) buttonClicked:(id)sender
79111
{
80112
Editor_menuEvent((int)((NSButton*)sender).tag);
81113
}

src/windows/RocketWindow.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
// clang-format off
55
#include <windows.h>
66
#include <windowsx.h>
7+
#include <shellapi.h>
78
#include <gl/gl.h>
89
// clang-format on
910
#include <string.h>
11+
#include "../args.h"
1012
#include "../Editor.h"
13+
#include "../loadsave.h"
14+
#include "../Dialog.h"
1115
#include "Menu.h"
1216
#include "afxres.h"
1317
#include "resource.h"
@@ -638,11 +642,38 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmndLine, i
638642
MSG msg;
639643
HACCEL accel;
640644
bool done = false;
645+
int argc = 0;
646+
wchar_t** argv = NULL;
647+
Args args = {0};
648+
649+
(void)instance;
650+
(void)prevInstance;
651+
(void)cmndLine;
652+
(void)show;
641653

642654
memset(&msg, 0, sizeof(MSG));
643655

644-
if (!createWindow(L"RocketEditor" EDITOR_VERSION, 800, 600))
656+
// Parse command line arguments
657+
argv = CommandLineToArgvW(GetCommandLineW(), &argc);
658+
if (argv) {
659+
Args_parse(&args, argc, (const text_t* const*)argv);
660+
}
661+
662+
if (!createWindow(L"RocketEditor" EDITOR_VERSION, 800, 600)) {
663+
if (argv) LocalFree(argv);
645664
return 0;
665+
}
666+
667+
// Load file if specified on command line
668+
if (args.loadFile) {
669+
if (LoadSave_loadRocketXML(args.loadFile, Editor_getTrackData())) {
670+
Editor_setLoadedFilename(args.loadFile);
671+
} else {
672+
Dialog_showError(L"Failed to load rocket file");
673+
}
674+
}
675+
676+
if (argv) LocalFree(argv);
646677

647678
accel = CreateAcceleratorTable(s_accelTable, s_accelCount);
648679

0 commit comments

Comments
 (0)