mirror of
https://github.com/ksherlock/mpw-tools.git
synced 2025-03-12 19:40:28 +00:00
MPW Tools (split from MPW)
This commit is contained in:
commit
e6f0a12ef0
346
Duplicate.c
Normal file
346
Duplicate.c
Normal file
@ -0,0 +1,346 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <Files.h>
|
||||
|
||||
/*
|
||||
Duplicate # duplicate files and directories
|
||||
Duplicate [-y | -n | -c] [-p] [-d | -r] name... target > progress
|
||||
-y # overwrite target files (avoids dialog)
|
||||
-n # don't overwrite target files (avoids dialog)
|
||||
-c # cancel if conflict occurs (avoids dialog)
|
||||
-p # write progress information to diagnostics
|
||||
-d # duplicate data fork only
|
||||
-r # duplicate resource fork only
|
||||
-rs # resolve leaf aliases in the source path(s)
|
||||
-rt # resolve leaf aliases in the target path
|
||||
-f # preserve Finder icon locations
|
||||
|
||||
*/
|
||||
// todo -- support src1 src2 ... dest/
|
||||
|
||||
|
||||
char *c2p(const char *cp)
|
||||
{
|
||||
int length;
|
||||
char *p;
|
||||
|
||||
if (!cp) return NULL;
|
||||
length = strlen(cp);
|
||||
if (length > 255)
|
||||
{
|
||||
fprintf(stderr, "Error: Pathname is too long.\n");
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = malloc(length + 2); // + 2 for \0 and length.
|
||||
if (!p)
|
||||
{
|
||||
fprintf(stderr, "Error: unable to allocate memory.\n");
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p[0] = length;
|
||||
memcpy(p + 1, cp, length + 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void help(void)
|
||||
{
|
||||
fprintf(stdout, "Usage: Duplicate [-y | -n | -c] [-p] [-d |-r] source destination\n");
|
||||
}
|
||||
|
||||
int getopt(int *opts, int argc, char **argv)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
char *str = argv[i];
|
||||
char c = str[0];
|
||||
|
||||
if (c != '-') return i;
|
||||
++str;
|
||||
|
||||
// -- to terminate
|
||||
if (str[0] == '-' && str[1] == 0)
|
||||
return i + 1;
|
||||
|
||||
// skip -rt, -rs
|
||||
if (str[0] == 'r' && str[1] == 's' && str[2] == 0)
|
||||
continue;
|
||||
|
||||
if (str[0] == 'r' && str[1] == 't' && str[2] == 0)
|
||||
continue;
|
||||
|
||||
for (; *str; ++str)
|
||||
{
|
||||
c = *str;
|
||||
switch(c)
|
||||
{
|
||||
case 'r':
|
||||
case 'd':
|
||||
opts['r' - 'a'] = 0;
|
||||
opts['d' - 'a'] = 0;
|
||||
opts[c - 'a'] = 1;
|
||||
break;
|
||||
case 'y':
|
||||
case 'n':
|
||||
case 'c':
|
||||
opts['y' - 'a'] = 0;
|
||||
opts['n' - 'a'] = 0;
|
||||
opts['c' - 'a'] = 0;
|
||||
opts[c - 'a'] = 1;
|
||||
break;
|
||||
case 'p':
|
||||
opts[c - 'a'] = 1;
|
||||
break;
|
||||
case 'h':
|
||||
help();
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Duplicate - Invalid flag: \"%c\"\n", c);
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int copyFork(const char *src, const char *dest, unsigned fork)
|
||||
{
|
||||
static char buffer[4096];
|
||||
|
||||
int rfd, wfd;
|
||||
|
||||
int rv;
|
||||
|
||||
fork = fork ? O_RSRC : 0;
|
||||
|
||||
rfd = open(src, O_RDONLY | O_BINARY | fork);
|
||||
if (rfd < 0)
|
||||
{
|
||||
fprintf(stderr, "Error opening %s: %s\n", src, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// no 3rd parameter to open.
|
||||
wfd = open(dest, O_WRONLY | O_BINARY | O_CREAT |O_TRUNC| fork);
|
||||
if (wfd < 0)
|
||||
{
|
||||
fprintf(stderr, "Error opening %s: %s\n", dest, strerror(errno));
|
||||
close(rfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = -1;
|
||||
for (;;)
|
||||
{
|
||||
ssize_t rsize;
|
||||
ssize_t wsize;
|
||||
|
||||
rsize = read(rfd, buffer, sizeof(buffer));
|
||||
if (rsize == 0)
|
||||
{
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
if (rsize < 0)
|
||||
{
|
||||
if (errno == EINTR) continue;
|
||||
fprintf(stderr, "Error reading %s: %s\n", src, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
wsize = write(wfd, buffer, rsize);
|
||||
if (wsize != rsize)
|
||||
{
|
||||
fprintf(stderr, "Error writing %s: %s\n", dest, strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(rfd);
|
||||
close(wfd);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int copyFinderInfo(const char *src, const char *dest)
|
||||
{
|
||||
FInfo finderInfo;
|
||||
OSErr status;
|
||||
|
||||
char *psrc;
|
||||
char *pdest;
|
||||
|
||||
psrc = c2p(src);
|
||||
pdest = c2p(dest);
|
||||
if (!psrc || !pdest) return -1;
|
||||
|
||||
// getfinfo/setfinfo seem to have bugs.
|
||||
|
||||
memset(&finderInfo, 0, sizeof(finderInfo));
|
||||
|
||||
status = GetFInfo((unsigned char *)psrc, 0, &finderInfo);
|
||||
if (status == 0)
|
||||
{
|
||||
status = SetFInfo((unsigned char *)pdest, 0, &finderInfo);
|
||||
}
|
||||
free(psrc);
|
||||
free(pdest);
|
||||
|
||||
if (status) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int createFile(const char *src, const char *dest)
|
||||
{
|
||||
FInfo finderInfo;
|
||||
OSErr status;
|
||||
|
||||
char *psrc;
|
||||
char *pdest;
|
||||
|
||||
psrc = c2p(src);
|
||||
pdest = c2p(dest);
|
||||
if (!psrc || !pdest) return -1;
|
||||
|
||||
memset(&finderInfo, 0, sizeof(finderInfo));
|
||||
|
||||
status = GetFInfo((unsigned char *)psrc, 0, &finderInfo);
|
||||
|
||||
status = Create((unsigned char *)pdest, 0, finderInfo.fdCreator, finderInfo.fdType);
|
||||
free(psrc);
|
||||
free(pdest);
|
||||
|
||||
if (status) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -1 - error.
|
||||
// 0 - no file
|
||||
// 1 - regular file
|
||||
// 2 - directory.
|
||||
int mode(const char *path)
|
||||
{
|
||||
char *pname;
|
||||
CInfoPBRec rec;
|
||||
OSErr status;
|
||||
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
|
||||
pname = c2p(path);
|
||||
if (!pname) return -1;
|
||||
|
||||
rec.hFileInfo.ioNamePtr = (unsigned char *)pname;
|
||||
status = PBGetCatInfo(&rec, false);
|
||||
free(pname);
|
||||
|
||||
if (status) return 0;
|
||||
if (rec.hFileInfo.ioFlAttrib & kioFlAttribDirMask)
|
||||
return 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opts[26];
|
||||
int optind;
|
||||
int ok;
|
||||
char *src;
|
||||
char *dest;
|
||||
int m;
|
||||
|
||||
memset(opts, 0, sizeof(opts));
|
||||
|
||||
opts['n' - 'a'] = 1;
|
||||
optind = getopt(opts, argc, argv);
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
help();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
src = argv[0];
|
||||
dest = argv[1];
|
||||
|
||||
// 1. check if src exists
|
||||
// 2. check if dest exists
|
||||
|
||||
// 3. copy data fork unless -r
|
||||
// 4. copy resource fork unless -d
|
||||
// 5. copy finder info.
|
||||
|
||||
ok = 0;
|
||||
// -n - do not overwrite
|
||||
// -c - cancel if conflict
|
||||
|
||||
m = mode(dest);
|
||||
if (m == 2)
|
||||
{
|
||||
fprintf(stderr, "Error: directory destination is not yet supported.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (m == 0 && opts['r' - 'a'])
|
||||
{
|
||||
// workaround to create the file if
|
||||
// only copying the resource fork.
|
||||
|
||||
// TODO -- call Create(name, 0, creator, filetype)
|
||||
|
||||
if (opts['p' - 'a'])
|
||||
printf("Creating file %s\n", dest);
|
||||
ok = createFile(src, dest);
|
||||
if (ok < 0)
|
||||
{
|
||||
fprintf(stderr, "Error creating %s\n", dest);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (m == 1)
|
||||
{
|
||||
// todo -- should this check at the file level or at the fork level?
|
||||
// seems to check at the file level.
|
||||
|
||||
// file exists.
|
||||
if (opts['c' - 'a'] || opts['n' - 'a'])
|
||||
{
|
||||
if (opts['p' - 'a'])
|
||||
{
|
||||
printf("File exists - nothing done.\n");
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (opts['r' - 'a'] == 0)
|
||||
{
|
||||
if (opts['p' - 'a'])
|
||||
printf("Copying Data Fork.\n");
|
||||
ok = copyFork(src, dest, 0);
|
||||
}
|
||||
|
||||
if (opts['d' - 'a'] == 0)
|
||||
{
|
||||
if (opts['p' - 'a'])
|
||||
printf("Copying Resource Fork.\n");
|
||||
ok = copyFork(src, dest, 1);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
28
GetEnv.c
Normal file
28
GetEnv.c
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
*
|
||||
* GetEnv variable
|
||||
* read an mpw variable.
|
||||
* eg: CLibraries=`mpw GetEnv CLibraries`
|
||||
* (makefile) CLibraries = $(shell mpw GetEnv CLibraries)
|
||||
* flags to do name = value?
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *value;
|
||||
char *name;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
name = argv[1];
|
||||
value = getenv(name);
|
||||
// value == null if not defined.
|
||||
if (value) puts(value);
|
||||
return 0;
|
||||
}
|
1
Help.c
Normal file
1
Help.c
Normal file
@ -0,0 +1 @@
|
||||
/*
* MPW Help utility.
*
* help topic
* does a cat of $ShellDirectory:Help:topic
*/
/*
* MPW 3.2
*
* C Help.c -o Help.c.o -r {SymOptions}
*
* Link {SymOptions} -w -c 'MPS ' -t MPST Help.c.o ∂
* -sn STDIO=Main ∂
* -sn INTENV=Main ∂
* -sn %A5Init=Main ∂
* "{Libraries}"Stubs.o ∂
* "{CLibraries}"StdCLib.o ∂
* "{Libraries}"Interface.o ∂
* "{Libraries}"Runtime.o ∂
* "{Libraries}"ToolLibs.o ∂
* -o Help
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *base(char *str)
{
char *rv = str;
char *tmp = str;
if (!str) return str;
for (tmp = str; *tmp; ++tmp)
{
char c = *tmp;
if (c == ':' || c == '/') rv = tmp + 1;
}
return rv;
}
void help(char *root, char *topic)
{
int l;
char *path;
FILE *fp;
// todo -- check if they're being stupid or malicious and
// handle / or : chars.
topic = base(topic);
if (!topic || !*topic)
{
return;
}
l = strlen(root) + strlen("Help:") + strlen(topic) + 1;
path = malloc(1);
if (!path)
{
fprintf(stderr, "### Help - Memory allocation failure.\n");
return;
}
sprintf(path, "%sHelp:%s", root, topic);
fp = fopen(path, "r");
free(path);
if (!fp)
{
fprintf(stderr, "### Help - \"%s\" was not found.\n", topic);
return;
}
for(;;)
{
char buffer[512];
int count;
count = fread(buffer, 1, sizeof(buffer), fp);
if (count == 0) break;
fwrite(buffer, 1, count, stdout);
}
fwrite("\r", 1, 1, stdout);
fclose(fp);
}
int main(int argc, char **argv)
{
char *root;
root = getenv("ShellDirectory");
if (!root || !*root)
{
fprintf(stderr, "### Help - $ShellDirectory is not defined.\n");
return 1;
}
if (argc == 1)
{
help(root, "MPW");
}
else
{
int i;
for (i = 1; i < argc; ++i)
{
help(root, argv[i]);
}
}
return 0;
}
|
151
SetFile.c
Normal file
151
SetFile.c
Normal file
@ -0,0 +1,151 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <Finder.h>
|
||||
#include <Files.h>
|
||||
|
||||
#include "SetFile-flags.h"
|
||||
|
||||
|
||||
|
||||
int tox(char c)
|
||||
{
|
||||
c |= 0x20;
|
||||
if (c >='0' && c <= '9') return c - '0';
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hex(const char *in, char *out, int length)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < length; ++i)
|
||||
{
|
||||
int tmp = 0;
|
||||
char c;
|
||||
|
||||
c = *in++;
|
||||
if (!isxdigit(c)) return -1;
|
||||
tmp |= tox(c) << 4;
|
||||
|
||||
c = *in++;
|
||||
if (!isxdigit(c)) return -1;
|
||||
tmp |= tox(c);
|
||||
|
||||
*out++ = tmp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// convert the file/creators...
|
||||
// format:
|
||||
// 0x \xdigit{8}
|
||||
// $ \xdigit{8}
|
||||
// 4-cc code
|
||||
int checkcode(const char *in, char *out)
|
||||
{
|
||||
int length;
|
||||
|
||||
length = strlen(in);
|
||||
|
||||
if (length == 4)
|
||||
{
|
||||
// 4 cc code.
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i)
|
||||
out[i] = in[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (length == 9 && in[0] == '$')
|
||||
return hex(in + 1, out, 4);
|
||||
|
||||
if (length ==10 && in[0] == '0' && in[1] == 'x')
|
||||
return hex(in + 2, out, 4);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
FInfo newFI;
|
||||
int optind;
|
||||
int ok;
|
||||
int i;
|
||||
|
||||
|
||||
optind = FlagsParse(argc, argv);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
FlagsHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
memset(&newFI, 0, sizeof(newFI));
|
||||
|
||||
if (!flags._t && !flags._c) return 0;
|
||||
|
||||
if (flags._t)
|
||||
{
|
||||
ok = checkcode(flags._t, (char *)&newFI.fdType);
|
||||
if (ok < 0)
|
||||
{
|
||||
fprintf(stderr, "SetFile: invalid file type: `%s`\n", flags._t);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags._c)
|
||||
{
|
||||
ok = checkcode(flags._c, (char *)&newFI.fdCreator);
|
||||
if (ok < 0)
|
||||
{
|
||||
fprintf(stderr, "SetFile: invalid creator type: `%s`\n", flags._c);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; ++i)
|
||||
{
|
||||
FInfo fi;
|
||||
char buffer[256];
|
||||
char *cp;
|
||||
int l;
|
||||
|
||||
cp = argv[i];
|
||||
l = strlen(cp);
|
||||
if (l > 255)
|
||||
{
|
||||
fprintf(stderr, "SetFile: %s: file name too long.\n", cp);
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer[0] = l;
|
||||
memcpy(buffer + 1, cp, l);
|
||||
|
||||
memset(&fi, 0, sizeof(fi));
|
||||
|
||||
ok = GetFInfo((unsigned char *)buffer, 0, &fi);
|
||||
|
||||
if (flags._t) fi.fdType = newFI.fdType;
|
||||
if (flags._c) fi.fdCreator = newFI.fdCreator;
|
||||
|
||||
ok = SetFInfo((unsigned char *)buffer, 0, &fi);
|
||||
if (ok != 0)
|
||||
{
|
||||
fprintf(stderr, "SetFile: %s: unable to set finder info: %d\n", cp, ok);
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
314
flags.rb
Normal file
314
flags.rb
Normal file
@ -0,0 +1,314 @@
|
||||
#!/usr/bin/env ruby -w
|
||||
|
||||
# process the flags.yaml file
|
||||
# and generate a flags.h and flags.c file.
|
||||
#
|
||||
|
||||
#
|
||||
# todo -- support for long-options (--longoption, --longoption=value, etc)
|
||||
#
|
||||
#
|
||||
|
||||
require 'erb'
|
||||
require 'yaml'
|
||||
|
||||
header_preamble = <<EOF
|
||||
|
||||
#ifndef __flags_h__
|
||||
#define __flags_h__
|
||||
|
||||
typedef struct Flags {
|
||||
EOF
|
||||
|
||||
header_postamble = <<EOF
|
||||
} Flags;
|
||||
|
||||
|
||||
extern struct Flags flags;
|
||||
|
||||
int FlagsParse(int argc, char **argv);
|
||||
|
||||
void FlagsHelp(void);
|
||||
|
||||
#endif
|
||||
|
||||
EOF
|
||||
|
||||
|
||||
class Option
|
||||
@@map = {
|
||||
# some of these are a bad idea but whatever...
|
||||
'>' => 'gt',
|
||||
'<' => 'lt',
|
||||
',' => 'comma',
|
||||
'.' => 'period',
|
||||
'/' => 'forward_slash',
|
||||
'\\' => 'back_slash',
|
||||
'?' => 'question',
|
||||
'|' => 'pipe',
|
||||
'~' => 'tilde',
|
||||
'`' => 'grave',
|
||||
'!' => 'bang',
|
||||
'@' => 'at',
|
||||
'#' => 'hash',
|
||||
'$' => 'dollar',
|
||||
'%' => 'percent',
|
||||
'^' => 'caret',
|
||||
'&' => 'ampersand',
|
||||
'*' => 'star',
|
||||
'(' => 'left_paren',
|
||||
')' => 'right_paren',
|
||||
'-' => 'minus',
|
||||
'+' => 'plus',
|
||||
'=' => 'equal',
|
||||
'[' => 'left_bracket',
|
||||
']' => 'right_bracket',
|
||||
'{' => 'left_brace',
|
||||
'}' => 'right_brace',
|
||||
':' => 'colon',
|
||||
';' => 'semi_colon',
|
||||
'\'' => 'apostrophe',
|
||||
'"' => 'quote'
|
||||
}
|
||||
|
||||
def initialize(hash)
|
||||
|
||||
@char = hash['char'].to_s
|
||||
@argument = hash['argument'] || false
|
||||
|
||||
@flag_name = hash['flag_name']
|
||||
@flag_name = @flag_name.to_s if @flag_name
|
||||
|
||||
@xor = hash['xor'] || []
|
||||
@xor = case @xor
|
||||
when Array
|
||||
@xor
|
||||
when Integer, String
|
||||
[ @xor ]
|
||||
else
|
||||
raise "Invalid xor type: #{@xor}"
|
||||
end
|
||||
|
||||
@xor.map! { |x| x.to_s }
|
||||
end
|
||||
|
||||
attr_reader :char, :xor, :argument
|
||||
|
||||
def flag_name
|
||||
return @flag_name if @flag_name
|
||||
return self.class.flag_name(@char)
|
||||
end
|
||||
|
||||
def self.flag_name(char)
|
||||
return '_' + @@map[char] if @@map[char]
|
||||
return '_' + char
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
# better ARGF.
|
||||
def argf_each
|
||||
|
||||
if ARGV.count > 0
|
||||
|
||||
ARGV.each {|file|
|
||||
|
||||
File.open(file, "r") {|io|
|
||||
yield file, io
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
yield nil, $stdin
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def escape_cstr(x)
|
||||
|
||||
# escape a c string
|
||||
|
||||
x.gsub(/([\\"])/, "\\\\1")
|
||||
end
|
||||
|
||||
|
||||
code = ERB.new(DATA.read(), 0, "%<>")
|
||||
|
||||
argf_each {|filename, file|
|
||||
|
||||
|
||||
data = YAML.load(file)
|
||||
|
||||
help = data['help']
|
||||
options = data['options']
|
||||
|
||||
# options is an array of items which may be hashes, strings, or numbers.
|
||||
# normalize them.
|
||||
|
||||
options = options.map {|opt|
|
||||
|
||||
opt = case opt
|
||||
when String, Integer
|
||||
{ 'char' => opt }
|
||||
when Hash
|
||||
# {'o' => { ... }}
|
||||
# or
|
||||
# {'char' => , ... }
|
||||
if opt['char']
|
||||
opt
|
||||
else
|
||||
opt = opt.first
|
||||
opt[1].merge({ 'char' => opt[0] })
|
||||
end
|
||||
else
|
||||
raise "Unexpected data type: #{opt}"
|
||||
end
|
||||
|
||||
Option.new(opt)
|
||||
}
|
||||
|
||||
#data[options] = options
|
||||
# check for help?
|
||||
|
||||
basename = filename
|
||||
basename = $1 if filename && filename =~ /^(.*)\./
|
||||
|
||||
b = binding # bind help, options for ERB.
|
||||
|
||||
io = basename ? File.open(basename + ".c", "w") : $stdout
|
||||
io.write(code.result(b))
|
||||
|
||||
io.close unless io == $stdout
|
||||
|
||||
|
||||
io = basename ? File.open(basename + ".h", "w") : $stdout
|
||||
io.write(header_preamble)
|
||||
# two passes - one with arguments, one without.
|
||||
options.each {|opt|
|
||||
if opt.argument
|
||||
io.printf(" char *%s;\n", opt.flag_name)
|
||||
end
|
||||
}
|
||||
io.puts()
|
||||
options.each {|opt|
|
||||
if !opt.argument
|
||||
io.printf(" unsigned %s:1;\n", opt.flag_name)
|
||||
end
|
||||
}
|
||||
io.puts
|
||||
|
||||
io.write(header_postamble)
|
||||
io.close unless io == $stdout
|
||||
|
||||
|
||||
# #puts options.to_yaml
|
||||
# puts code.result(binding())
|
||||
|
||||
}
|
||||
|
||||
|
||||
__END__
|
||||
|
||||
#ifdef __ORCAC__
|
||||
#pragma optimize 79
|
||||
#pragma noroot
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "<%= basename + '.h' %>"
|
||||
|
||||
void FlagsHelp(void)
|
||||
{
|
||||
% help.each do |h|
|
||||
fputs("<%= escape_cstr(h) %>\n", stdout);
|
||||
% end
|
||||
fputs("\n", stdout);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
struct Flags flags;
|
||||
int FlagsParse(int argc, char **argv)
|
||||
{
|
||||
char *cp;
|
||||
char c;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
memset(&flags, 0, sizeof(flags));
|
||||
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
cp = argv[i];
|
||||
c = cp[0];
|
||||
|
||||
if (c != '-')
|
||||
return i;
|
||||
|
||||
// -- = end of options.
|
||||
if (cp[1] == '-' && cp[2] == 0)
|
||||
return i + 1;
|
||||
|
||||
// now scan all the flags in the string...
|
||||
for (j = 1; ; ++j)
|
||||
{
|
||||
int skip = 0;
|
||||
|
||||
c = cp[j];
|
||||
if (c == 0) break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
% if help && !options.find_index {|x| x.char == 'h' }
|
||||
case 'h':
|
||||
FlagsHelp();
|
||||
break;
|
||||
% end
|
||||
% #
|
||||
% options.each do |opt|
|
||||
case '<%= escape_cstr(opt.char) %>':
|
||||
% # check for an argument.
|
||||
% flag_name = 'flags.' + opt.flag_name
|
||||
% #
|
||||
% if opt.argument
|
||||
// -xarg or -x arg
|
||||
skip = 1;
|
||||
if (cp[j + 1])
|
||||
{
|
||||
<%= flag_name %> = cp + j + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++i >= argc)
|
||||
{
|
||||
fputs("option requires an argument -- <%= opt.char %>\n", stderr);
|
||||
return -1;
|
||||
}
|
||||
<%= flag_name %> = argv[i];
|
||||
}
|
||||
% else # no argument.
|
||||
<%= flag_name %> = 1;
|
||||
% end # if no argument.
|
||||
% #
|
||||
% # unset any exclusive or values
|
||||
% opt.xor.each do |xor_opt|
|
||||
flags.<%= Option.flag_name(xor_opt) %> = 0;
|
||||
%end
|
||||
break;
|
||||
% end # options.each
|
||||
|
||||
default:
|
||||
fprintf(stderr, "illegal option -- %c\n", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (skip) break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
61
makefile
Normal file
61
makefile
Normal file
@ -0,0 +1,61 @@
|
||||
# makefile
|
||||
|
||||
Libraries=~/mpw/Libraries/Libraries
|
||||
CLibraries=~/mpw/Libraries/CLibraries
|
||||
|
||||
# MPW 3.2
|
||||
LIBS = \
|
||||
$(Libraries)/Stubs.o \
|
||||
$(CLibraries)/StdCLib.o \
|
||||
$(Libraries)/Interface.o \
|
||||
$(Libraries)/Runtime.o \
|
||||
$(Libraries)/ToolLibs.o
|
||||
|
||||
LDFLAGS = -w -c 'MPS ' -t MPST \
|
||||
-sn STDIO=Main -sn INTENV=Main -sn %A5Init=Main
|
||||
|
||||
# MPW 3.5
|
||||
|
||||
# LIBS = \
|
||||
# $(CLibraries)/StdCLib.o \
|
||||
# $(Libraries)/Stubs.o \
|
||||
# $(Libraries)/IntEnv.o \
|
||||
# $(Libraries)/MacRuntime.o \
|
||||
# $(Libraries)/Interface.o \
|
||||
# $(Libraries)/ToolLibs.o
|
||||
|
||||
# LDFLAGS = -d -c 'MPS ' -t MPST
|
||||
|
||||
all: Help GetEnv Duplicate SetFile
|
||||
|
||||
clean:
|
||||
rm -f *.c.o
|
||||
rm -f Help GetEnv Duplicate SetFile
|
||||
|
||||
GetEnv: GetEnv.c.o
|
||||
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
Help: Help.c.o
|
||||
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
|
||||
Duplicate: Duplicate.c.o
|
||||
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
|
||||
SetFile: SetFile.c.o SetFile-flags.c.o
|
||||
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
|
||||
#SetFile.c : SetFile.rl
|
||||
# ragel -G2 -p -m -o $@ $<
|
||||
|
||||
|
||||
%.c.o : %.c
|
||||
mpw SC -p $< -o $@
|
||||
|
||||
# GetEnv.c.o : GetEnv.c
|
||||
# mpw SC -p GetEnv.c -o $@
|
||||
|
||||
# Help.c.o : Help.c
|
||||
# mpw SC -p Help.c -o $@
|
44
split-help.rb
Normal file
44
split-help.rb
Normal file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env ruby -w
|
||||
|
||||
|
||||
#
|
||||
# format
|
||||
# -
|
||||
# name # comment
|
||||
#
|
||||
|
||||
file = nil
|
||||
state = nil
|
||||
#ARGF.binmode
|
||||
#ARGF.set_encoding("BINARY")
|
||||
ARGF.each { |line|
|
||||
|
||||
line.chomp!
|
||||
|
||||
case state
|
||||
when nil
|
||||
if line == '-'
|
||||
state = :name
|
||||
end
|
||||
|
||||
when :name
|
||||
if line.match(/^([A-Za-z0-F]+)\s?#?/)
|
||||
state = :data
|
||||
filename = $1
|
||||
file = File::new("Help.Files/#{filename}", "w")
|
||||
#file.set_encoding("BINARY")
|
||||
end
|
||||
|
||||
when :data
|
||||
if line == '-'
|
||||
state = :name
|
||||
file = nil
|
||||
else
|
||||
file.puts(line)
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user