Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ LOCALES = ca de el en en_AU en_GB es es_419 fr fur hu it ja nl pl pt ro ru sv tr
SYMBOLS := TRUE
DEBUGGER := TRUE
# -gno-column-info is a workaround for Debugger issue (#15159)
COMPILER_FLAGS = -gno-column-info -std=c++17 -Werror
COMPILER_FLAGS = -gno-column-info -std=c++20 -Werror

## Include the Makefile-Engine
DEVEL_DIRECTORY := \
Expand Down
30 changes: 3 additions & 27 deletions src/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,36 +200,12 @@ App::QuitRequested()
void
App::ReadyToRun()
{
if(CountWindows() == 0 && fSuppressInitialWindow == false) {
if(fSuppressInitialWindow == false && CountWindows() == 0) {
PostMessage(WINDOW_NEW);
}
}


void
App::ArgvReceived(int32 argc, char** argv)
{
BMessage* message = CurrentMessage();
BString cwd = message->GetString("cwd", "~");
std::unique_ptr<BWindowStack> windowStack;
for(int32 i = 1; i < argc; ++i) {
std::string arg = argv[i];
// FIXME: this should be handled in main.cpp probably
if(arg == "-w" || arg == "--wait" || arg == "-h" || arg == "--help")
continue;
int32 line, column;
std::string filename = ParseFileArgument(argv[i], &line, &column);
if(filename.find('/') != 0) {
BPath absolute(cwd.String(), filename.c_str(), true);
filename = absolute.Path();
}
entry_ref ref;
BEntry(filename.c_str()).GetRef(&ref);
_ActivateOrCreateWindow(message, ref, line, column, windowStack);
}
}


void
App::RefsReceived(BMessage* message)
{
Expand All @@ -248,8 +224,8 @@ App::RefsReceived(BMessage* message)
trackerMessage.AddRef("refs", &ref);
continue;
}
const int32 line = message->GetInt32("be:line", -1);
const int32 column = message->GetInt32("be:column", -1);
const int32 line = message->GetInt32("be:line", i, -1);
const int32 column = message->GetInt32("be:column", i, -1);
_ActivateOrCreateWindow(message, ref, line, column, windowStack);
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/App.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Styler;
enum {
SUPPRESS_INITIAL_WINDOW = 'Siwn',
WINDOW_NEW_WITH_QUIT_REPLY = 'NWwn',
ACTIVATE_WINDOW = 'actw'
ACTIVATE_WINDOW = 'actw'
};


Expand All @@ -43,7 +43,6 @@ class App : public BApplication {
void AboutRequested();
bool QuitRequested();
void ReadyToRun();
void ArgvReceived(int32 argc, char** argv);
void RefsReceived(BMessage* message);
void MessageReceived(BMessage* message);

Expand Down
133 changes: 85 additions & 48 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,112 @@

#include "App.h"

#include <string>

#include <Roster.h>

#include <array>
#include <iostream>
#include <getopt.h>

#include "Utils.h"


void
_PrintUsage(std::ostream& outStream)
{
outStream
<< "Usage: Koder [options] file...\n"
<< "Options:\n"
<< " -h, --help\t\tPrints this message.\n"
<< " -w, --wait\t\tWait for the window to quit before returning.\n"
<< "\t\t\tOpening in window stacks is not supported in this mode.\n"
<< "\t\t\tCurrently accepts only one filename.\n";
}


int
main(int argc, char** argv)
{
std::string arg1 = argc > 1 ? argv[1] : "";
if(argc > 1 && (arg1 == "-h" || arg1 == "--help")) {
fprintf(stderr, "Usage: Koder [options] file...\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, " -h, --help\t\tPrints this message.\n");
fprintf(stderr, " -w, --wait\t\tWait for the window to quit before "
"returning.\n"
"\t\t\tOpening in window stacks is not supported in this mode.\n"
"\t\t\tCurrently accepts only one filename.\n");
int optionIndex = 0;
auto long_options = std::to_array<option>({
{"help", no_argument, 0, 'h'},
{"wait", no_argument, 0, 'w'},
{0, 0, 0, 0}});

bool waitForExit = false;
int c;
while((c = getopt_long(argc, argv, "hw", long_options.data(), &optionIndex)) != -1) {
switch(c) {
case 'w':
waitForExit = true;
break;
case 'h':
_PrintUsage(std::cout);
return 0;
default:
_PrintUsage(std::cerr);
return 1;
}
}

// use the getopt optind global to tell us where the switch processing ended
if(waitForExit == true && argc - optind > 1) {
std::cerr << "Error: Only one filename allowed when using --wait.\n";
return 1;
}

if(argc > 1 && (arg1 == "-w" || arg1 == "--wait")) {
if(argc > 3) {
fprintf(stderr, "Koder accepts only one filename when launching "
"in --wait mode.\n");
BMessage windowMessage
(waitForExit == true ? (system_message_code) WINDOW_NEW_WITH_QUIT_REPLY : B_REFS_RECEIVED);

while(optind < argc) {
int32 line, column;
BPath filePath(ParseFileArgument(argv[optind++], &line, &column).c_str(), nullptr, true);
if(filePath.InitCheck() != B_OK) {
std::cerr << "Error: Invalid file path specified.\n";
return 1;
}
BRoster roster;
team_id team = roster.TeamFor(gAppMime);
if(team == B_ERROR) {
BMessage* suppressMessage = new BMessage(SUPPRESS_INITIAL_WINDOW);
status_t status = roster.Launch(gAppMime, suppressMessage, &team);
delete suppressMessage;
if(status != B_OK && status != B_ALREADY_RUNNING) {
fprintf(stderr, "An issue occured while trying to launch Koder.\n");
return 1;
}

entry_ref ref;
BEntry entry(filePath.Path(), true);
if(entry.InitCheck() != B_OK || (entry.Exists() == true && entry.IsFile() == false)) {
std::cerr << "Error: Specified path is not a regular file.\n";
return 1;
}
if(entry.GetRef(&ref) != B_OK) {
std::cerr << "Error: Unable to get entry_ref for path.\n";
return 1;
}
BMessage windowMessage(WINDOW_NEW_WITH_QUIT_REPLY);
// parse filename if any
// TODO: support -- for piping
if(argc > 2) {
int32 line, column;
std::string filename = ParseFileArgument(argv[2], &line, &column);
if(filename.find('/') != 0) {
BPath absolute(".", filename.c_str(), true);
filename = absolute.Path();
}
entry_ref ref;
BEntry(filename.c_str()).GetRef(&ref);
windowMessage.AddRef("refs", &ref);
if(line != -1) {
windowMessage.AddInt32("be:line", line);
}
if(column != -1) {
windowMessage.AddInt32("be:column", column);
}
// always add column and line so that the count is the same as the number of refs
windowMessage.AddRef("refs", &ref);
windowMessage.AddInt32("be:column", column);
windowMessage.AddInt32("be:line", line);
}

BRoster roster;
team_id team = roster.TeamFor(gAppMime);
if(waitForExit == true && team < B_OK) {
BMessage suppressMessage(SUPPRESS_INITIAL_WINDOW);
status_t status = roster.Launch(gAppMime, &suppressMessage, &team);
if(status != B_OK && status != B_ALREADY_RUNNING) {
std::cerr << "Error: Unable to launch Koder.\n";
return 1;
}
BMessenger messenger(gAppMime, team);
}

BMessenger messenger(gAppMime, team);
// make sure we're targetting a different team with a BApplication and not this one
if(messenger.IsValid() == true && messenger.IsTargetLocal() == false) {
BMessage reply;
messenger.SendMessage(&windowMessage, &reply);
return 0;
} else {
App* app = new App();
app->Init();
// pass any converted command line args since the app doesn't have ArgvReceived
if(windowMessage.IsEmpty() == false) {
app->RefsReceived(&windowMessage);
}
app->Run();
delete app;

return 0;
}

return 0;
}