From 79bca732c8511aaaa6a8b68d1eb9b300a87f475b Mon Sep 17 00:00:00 2001 From: Dietrich Epp Date: Wed, 24 Mar 2021 04:19:47 -0400 Subject: [PATCH] Convert resource files GitOrigin-RevId: ee47a60e097c818def27f799dfd97c1396be2a68 --- Makefile | 12 ++++++++++-- README.md | 8 ++++++-- convert.h | 3 +++ copy.c | 19 +++++++++++++++++++ defs.h | 9 +++++++++ sync.c | 37 +++++++++++++++++++++++-------------- 6 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 copy.c diff --git a/Makefile b/Makefile index d7c20b4..f2c6c97 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ COptions-68K = {COptions} {Sym-68K} SrcFiles = ∂ convert.c ∂ + copy.c ∂ file.c ∂ mac_from_unix.c ∂ mac_to_unix.c ∂ @@ -19,6 +20,7 @@ SrcFiles = ∂ ObjFiles-PPC = ∂ convert.c.x ∂ + copy.c.x ∂ file.c.x ∂ mac_from_unix.c.x ∂ mac_to_unix.c.x ∂ @@ -27,6 +29,7 @@ ObjFiles-PPC = ∂ ObjFiles-68K = ∂ convert.c.o ∂ + copy.c.o ∂ file.c.o ∂ mac_from_unix.c.o ∂ mac_to_unix.c.o ∂ @@ -91,7 +94,7 @@ Dependencies ƒ $OutOfDate {SrcFiles} #*** Dependencies: Cut here *** -# These dependencies were produced at 3:18:36 AM on Wed, Mar 24, 2021 by MakeDepend +# These dependencies were produced at 4:16:36 AM on Wed, Mar 24, 2021 by MakeDepend :convert.c.x :convert.c.o ƒ ∂ :convert.c ∂ @@ -99,9 +102,14 @@ Dependencies ƒ $OutOfDate :defs.h ∂ :mac_from_unix_data.h +:copy.c.x :copy.c.o ƒ ∂ + :copy.c ∂ + :convert.h + :file.c.x :file.c.o ƒ ∂ :file.c ∂ - :defs.h + :defs.h ∂ + :convert.h :mac_from_unix.c.x :mac_from_unix.c.o ƒ ∂ :mac_from_unix.c ∂ diff --git a/README.md b/README.md index 7123ce7..0025fcb 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,11 @@ SyncFiles is a tool for MPW (Macintosh Programmer’s Workshop) which synchroniz - Only synchronizes files which match hard-coded patterns. -- Converts files to UTF-8 and LF line endings for Unix systems; converts to Mac OS Roman and CR line endings for Macintosh systems. +- Converts text files to UTF-8 and LF line endings for Unix systems; converts to Mac OS Roman and CR line endings for Macintosh systems. -- Creates Macintosh files with MPW Shell creator code and text file type. +- For resource files, converts by copying the Macintosh resource fork to the data fork. + +- Sets the file type and creator code, creating MPW Shell text files and ResEdit resource files. ## File Patterns @@ -22,6 +24,8 @@ Copies files named Makefile, and files with the following extensions: - C++: `.cc` `.cp` `.cpp` `.cxx` `.hh` `.hpp` `.hxx` +- Resource: `.rsrc` + ## Usage Operates in push or pull mode. The tool runs from inside the classic Macintosh environment, so the “push” mode copies from Macintosh to Unix, and the “pull” mode copies from Unix to Macintosh. It is assumed that the Macintosh directory is on a normal disk volume. diff --git a/convert.h b/convert.h index 23bf093..82fafec 100644 --- a/convert.h +++ b/convert.h @@ -44,3 +44,6 @@ int mac_to_unix(short srcRef, short destRef, void *srcBuf, void *destBuf); // Convert UTF-8 with LF line endings to Macintosh encoding with CR. The source // and destinations are file handles. The buffers have size kBufferTotalSize. int mac_from_unix(short srcRef, short destRef, void *srcBuf, void *destBuf); + +// Raw data copy. +int copy_data(short srcRef, short destRef, void *buf); diff --git a/copy.c b/copy.c new file mode 100644 index 0000000..6d1f03f --- /dev/null +++ b/copy.c @@ -0,0 +1,19 @@ +#include "convert.h" + +int copy_data(short srcRef, short destRef, void *buf) { + long count; + int r, r2; + + do { + count = kBufferBaseSize; + r = convert_read(srcRef, &count, buf); + if (r == kConvertError) { + return 1; + } + r2 = convert_write(destRef, count, buf); + if (r2 != kConvertOK) { + return 1; + } + } while (r != kConvertEOF); + return 0; +} diff --git a/defs.h b/defs.h index 20ec063..8ba8779 100644 --- a/defs.h +++ b/defs.h @@ -76,6 +76,13 @@ typedef enum { kActionDelete, // Delete dest file. } file_action; +// A general type of file. Affects the type code and conversions applied. +typedef enum { + kTypeUnknown, + kTypeText, // Text file: convert CR/LF and encoding. + kTypeResource, // Resource file: copy resource fork to data fork. +} file_type; + // Information about a file present in the source or destination directory (or // both). struct file_info { @@ -85,6 +92,8 @@ struct file_info { struct file_meta meta[2]; // The action to apply to this file. file_action action; + // The type of file. Used to select type codes and converters. + file_type type; }; // Synchronize a file according to the action in the action field. The temporary diff --git a/sync.c b/sync.c index a3ee57d..a3ff36d 100644 --- a/sync.c +++ b/sync.c @@ -112,16 +112,15 @@ static int dir_from_path(short *vRefNum, long *dirID, const char *dirpath) { return 0; } -// Return true if a file with the given name should be included. The name is a -// Pascal string. -static int filter_name(const unsigned char *name) { +// Get the file type for a file with the given name. +static file_type file_type_from_name(const unsigned char *name) { int len, i, stem; const unsigned char *ext; char temp[32]; unsigned char c0, c1, c2; if (EqualString(name, "\pmakefile", false, true)) { - return 1; + return kTypeText; } stem = 0; len = name[0]; @@ -137,7 +136,7 @@ static int filter_name(const unsigned char *name) { // .c .h .r c0 = ext[0]; if (c0 == 'c' || c0 == 'h' || c0 == 'r') { - return 1; + return kTypeText; } break; case 2: @@ -146,7 +145,7 @@ static int filter_name(const unsigned char *name) { c1 = ext[1]; if (c0 == 'c' && (c1 == 'c' || c1 == 'p') || c0 == 'h' && c1 == 'h') { - return 1; + return kTypeText; } break; case 3: @@ -156,7 +155,13 @@ static int filter_name(const unsigned char *name) { c2 = ext[2]; if ((c0 == 'c' || c0 == 'h') && (c1 == 'p' && c2 == 'p' || c1 == 'x' && c2 == 'x')) { - return 1; + return kTypeText; + } + break; + case 4: + if (ext[0] == 'r' && ext[1] == 's' && ext[2] == 'r' && + ext[3] == 'c') { + return kTypeResource; } break; } @@ -165,7 +170,7 @@ static int filter_name(const unsigned char *name) { p2cstr(temp, name); fprintf(stderr, "## Ignored: %s\n", temp); } - return 0; + return kTypeUnknown; } // List files in a directory, filter them, and add the files matching the filter @@ -176,6 +181,7 @@ static int list_dir(short vRefNum, long dirID, int which) { struct file_info *file; OSErr err; int i; + file_type type; for (i = 1; i < 100; i++) { memset(&ci, 0, sizeof(ci)); @@ -191,12 +197,15 @@ static int list_dir(short vRefNum, long dirID, int which) { print_errcode(err, "could not list directory"); continue; } - if ((ci.hFileInfo.ioFlAttrib & kioFlAttribDirMask) == 0 && - filter_name(ppath)) { - ppath[ppath[0] + 1] = '\0'; - file = get_file(ppath); - file->meta[which].exists = true; - file->meta[which].modTime = ci.hFileInfo.ioFlMdDat; + if ((ci.hFileInfo.ioFlAttrib & kioFlAttribDirMask) == 0) { + type = file_type_from_name(ppath); + if (type != kTypeUnknown) { + ppath[ppath[0] + 1] = '\0'; + file = get_file(ppath); + file->meta[which].exists = true; + file->meta[which].modTime = ci.hFileInfo.ioFlMdDat; + file->type = type; + } } }