Blog

April042021

unix2atari8.c

Ein kleines Programm, um UNIX-Text in Atari-8-Bit-Text umzuwandeln. Hauptsächlich geht es um den Zeilenumbruch. Mehr tut das Programm momentan nicht.

unix2atari8.c:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"str_replace.c"

int main(int argc, char* argv[]) {
    // printf("argc = %d\n", argc);
    unsigned char replace[]={155, 0};
    
    // replace[0]=(unsigned char)155; replace[1]=(unsigned char)0;
    
    if (argc<2) {
        printf("usage: %s unix_text_files\n", argv[0]);
        return 0;
    }
    
    if ((strcmp(argv[1], "--help") && strcmp(argv[1], "-h"))==0) {
        printf("\nreplaces UNIX linebreaks with Atari's CHR$(155)\n");
        printf("Outputs are named CONV0001.TXT, CONV0002.TXT and so on\n");
        printf("which works well with most Atari-DOSses and Emulators\n");
        printf("Files will be overwritten WITHOUT ANY WARNING!\n\n");
        return 0;
    }
    
    for(int i=1; i<argc; i++) {
        // printf("arg[%d]=\"%s\"\n", i, argv[i]);
        FILE *fp;
        
        fp=fopen(argv[i], "r");
        
        if (fp==NULL) {
            printf("File \"%s\" not found\n", argv[i]);
        } else {
            char *unix_text, *atari8_text;
            size_t size;
            char filename[20];
            fseek(fp, 0, SEEK_END); // seek to end of file
            size = ftell(fp); // get current file pointer
            fseek(fp, 0, SEEK_SET); // seek back to beginning of file
            // proceed with allocating memory and reading the file
            unix_text=(char*)malloc(size+1);
            fread(unix_text, 1, size, fp);
            fclose(fp);
            sprintf(filename, "CONV%04d.TXT", i);
            atari8_text=str_replace(unix_text, "\n", replace);
            if (atari8_text==NULL) {
                printf("Nothing to convert in file \"%s\"\n", argv[i]);
            } else {
                printf("Writing converted file \"%s\" to \"%s\"\n", argv[i], filename);
                fp=fopen(filename, "wb");
                fwrite(atari8_text, 1, size, fp);
                fclose(fp);
                free(atari8_text);
            }
            free(unix_text);
        }
    }
    
    return 0;
}

Das Programm bedient sich eines Code-Schnipsels, den ich im Netz gefunden habe:

str_replace.c
// You must free the result if result is non-NULL.
char* str_replace(char* orig, char* rep, char* with) {
    char* result; // the return string
    char* ins;    // the next insert point
    char* tmp;    // varies
    int len_rep;  // length of rep (the string to remove)
    int len_with; // length of with (the string to replace rep with)
    int len_front; // distance between rep and end of last rep
    int count;    // number of replacements

    // sanity checks and initialization
    if (!orig || !rep)
        return NULL;
    len_rep = strlen(rep);
    if (len_rep == 0)
        return NULL; // empty rep causes infinite loop during count
    if (!with)
        with = "";
    len_with = strlen(with);

    // count the number of replacements needed
    ins = orig;
    for (count = 0; tmp = strstr(ins, rep); ++count) {
        ins = tmp + len_rep;
    }

    tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);

    if (!result)
        return NULL;

    // first time through the loop, all the variable are set correctly
    // from here on,
    //    tmp points to the end of the result string
    //    ins points to the next occurrence of rep in orig
    //    orig points to the remainder of orig after "end of rep"
    while (count--) {
        ins = strstr(orig, rep);
        len_front = ins - orig;
        tmp = strncpy(tmp, orig, len_front) + len_front;
        tmp = strcpy(tmp, with) + len_with;
        orig += len_front + len_rep; // move to next "end of rep"
    }
    strcpy(tmp, orig);
    return result;
}

Kompiliert wird das ganze unter Linux mit cc unix2atari8.c -o unix2atari8.

Tags: