Post Reply 
(Free42) txt2raw - raw2txt
05-22-2022, 12:27 PM
Post: #1
(Free42) txt2raw - raw2txt
There was a recent wish for a command line utility to translate between txt and raw files of Free42 programs.

So I cloned https://github.com/thomasokken/free42.git and wrote two simple programs:

txt2raw.cc
This program uses core_paste to read the program from a txt-file and core_export_programs to write it to a raw-file.
Code:
#include <sstream>
#include <fstream>

#include "core_main.h"
#include "core_globals.h"

int main(int argc, char *argv[]) {
    std::ostringstream sstream;
    std::ifstream fs(argv[1]);
    sstream << fs.rdbuf();
    const std::string str(sstream.str());
    const char* prgm = str.c_str();

    core_init(0, 0, NULL, 0);
    flags.f.prgm_mode = true;
    core_paste(prgm);
    const int indexes[] = { 0 };
    core_export_programs(1, indexes, argv[2]);

    return 0;
}

raw2txt.cc
This program uses core_import_programs to read the program from a raw-file and core_copy to write it to a txt-file.
Code:
#include <string.h>
#include <iostream>
#include <fstream>

#include "core_main.h"
#include "core_globals.h"

int main(int argc, char *argv[]) {
    core_init(0, 0, NULL, 0);
    core_import_programs(0, argv[1]);
    flags.f.prgm_mode = true;
    const char *prgm = core_copy();

    std::ofstream txt;
    txt.open(argv[2]);
    txt << prgm;
    txt.close();

    return 0;
}

To compile them put them into the gtk directory.

You need a small patch of the Makefile:
Code:
ifeq ($(EXE), txt2raw)
OBJS += txt2raw.o
endif

ifeq ($(EXE), raw2txt)
OBJS += raw2txt.o
endif

And then you have to comment out or remove the main function of gtk/shell_main.cc:
Code:
// int main(int argc, char *argv[]) {
//     for (int i = 1; i < argc; i++) {
//         if (strcmp(argv[i], "-skin") == 0)
//             skin_arg = ++i < argc ? argv[i] : NULL;
//         else if (strcmp(argv[i], "-compactmenu") == 0)
//             use_compactmenu = 1;
//         else {
//             fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
//             exit(1);
//         }
//     }

//     GtkApplication *app;
//     int status;
//     app = gtk_application_new("com.thomasokken.free42", G_APPLICATION_FLAGS_NONE);
//     g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
//     status = g_application_run(G_APPLICATION(app), 0, NULL);
//     g_object_unref(app);
//     return status;
// }

Now you can compile the binaries with:

make EXE=txt2raw

or

make EXE=raw2txt

Example Usage

./txt2raw tmsht.txt tmsht.raw

./raw2txt tmsht.raw tmsht.txt

You will notice annoying error messages related to Gtk and GdkPixbuf which can be ignored.
To do this, simply redirect STDERR to /dev/null by appending: 2> /dev/null

This works on a MacBook and I would guess on Linux too.
But I have no idea about the other platforms.

It is a bit of hack, but I couldn't figure out an easy way to disentangle the core from the shell.
Therefore, the GUI libraries have to be linked, which leads to the error messages.
Possibly an initialisation of the GUI is missing.
But since the programs were running, I didn't bother to find out.

Nevertheless, I hope that these programs will be useful for others as well.
Find all posts by this user
Quote this message in a reply
05-23-2022, 01:34 PM
Post: #2
RE: (Free42) txt2raw - raw2txt
Oh wow, this is super handy, thanks!! I'll give this a try when I have another go at a program later in the week.
Visit this user's website Find all posts by this user
Quote this message in a reply
05-23-2022, 03:15 PM
Post: #3
RE: (Free42) txt2raw - raw2txt
This 3rd program may look a bit silly first, but it can be used to pretty print your program.

txt2txt.cc
Code:
#include <string.h>
#include <iostream>
#include <fstream>
#include <sstream>

#include "core_main.h"
#include "core_globals.h"

int main(int argc, char *argv[]) {
    std::ostringstream sstream;
    std::ifstream fs(argv[1]);
    sstream << fs.rdbuf();
    const std::string str(sstream.str());
    const char* prgm = str.c_str();

    core_init(0, 0, NULL, 0);
    flags.f.prgm_mode = true;
    core_paste(prgm);
    prgm = core_copy();

    std::ofstream txt;
    txt.open(argv[1]);
    txt << prgm;
    txt.close();

    return 0;
}

Don't forget to add this to the Makefile:
Code:
ifeq ($(EXE), txt2txt)
OBJS += txt2txt.o
endif

And then as before compile it with:

make EXE=txt2txt

Example

Let's start with your original file:

tmsht.txt
Code:
00 { 52-Byte Prgm }
01▸LBL "TMSHT"
02 INPUT "DAY END"
03 INPUT "DAY START"
04 RCL "DAY END"
05 RCL "DAY START"
06 HMS-
07 →HR
08 Σ+
09 END

Now run:

./txt2txt tmsht.txt

We end up with:
Code:
00 { 48-Byte Prgm }
01▸LBL "TMSHT"
02 INPUT "DAY END"
03 INPUT "DAY STA"
04 RCL "DAY END"
05 RCL "DAY STA"
06 HMS-
07 →HR
08 Σ+
09 END

We notice that "DAY START" has been shortened to 7 characters: "DAY STA".

Warning: Make a backup of the file (e.g. add it to Git) before running this program.
Text that can not be parsed correctly will be removed.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)