1 line
7.8 KiB
Perl
Executable File
1 line
7.8 KiB
Perl
Executable File
#!/usr/local/bin/perl
|
|
#
|
|
# this thing generates all sorts of component crap
|
|
#
|
|
# usage: makecomponent prefix outputfile.h outputfile.c inputfiles...
|
|
# eg: makecomponent PETE :include:petecomp.h petecomp.c :{ext}:editor:pete.h
|
|
#
|
|
# Will also generate seconds header file for CFM macros named
|
|
# ouputfilecfm.h.
|
|
#
|
|
# I left in my comments that begin with #**. They can be deleted since I was
|
|
# using them to walk through the code and figure it out.
|
|
#
|
|
|
|
|
|
#** get arguments, shift removed first item so you can get the next in line
|
|
#** $prefix = $ARGV[0]; shift;
|
|
$prefix = 'PETE';
|
|
#** $hfile = $ARGV[0]; shift;
|
|
$hfile = ':Editor:Source:Application Headers:petecomponent.h';
|
|
$cfile = ':Editor:Source:Editor Source:petecomponent.c';
|
|
$mfile = ':Editor:Source:Application Headers:petecfm.h';
|
|
|
|
|
|
#** open output files
|
|
open(HFILE,">$hfile")||die;
|
|
open(MFILE,">$mfile")||die;
|
|
open(CFILE,">$cfile")||die;
|
|
|
|
#put top of outputfilecfm.h here
|
|
print MFILE <<BOILER;
|
|
/* gComponentDispatchUPP is a global initialized to GetToolTrapAddress(_ComponentDispatch) */
|
|
extern UniversalProcPtr gComponentDispatchUPP;
|
|
|
|
BOILER
|
|
|
|
# put top of outputfile.h stuff here
|
|
print HFILE <<BOILER;
|
|
#ifndef PETECOMPONENT_H
|
|
#define PETECOMPONENT_H
|
|
|
|
#ifndef PETE_H
|
|
#include "pete.h"
|
|
#endif
|
|
|
|
#define TWOBYTESIZE(x) (sizeof(x) == 1 ? 2 : sizeof(x))
|
|
|
|
BOILER
|
|
|
|
#** $_ default variable still has the last parameter ':{ext}:editor:pete.h'
|
|
#** read each line from file
|
|
while (<>)
|
|
{
|
|
if (/^pascal/)
|
|
#** if "pascal" is at the beginning of the input line
|
|
#** only care about pascal type declarations in this file
|
|
{
|
|
chop;
|
|
#** chop CR
|
|
|
|
#
|
|
# make sure we can use whitespace for tokens
|
|
s/\(/ \(/g;
|
|
#** search for "(" replace with " (", all occurances in line
|
|
|
|
#
|
|
# trim the pascal part
|
|
s/pascal\s*//;
|
|
#** delete "pascal" and space (replace with nothing)
|
|
|
|
#
|
|
# nab the return type
|
|
#** "[ \t]+" is one or more spaces or tabs
|
|
#** "2" limits the result into two peices
|
|
#** $returns = the return type
|
|
#** $rest = the rest of the string
|
|
($returns,$rest) = split("[ \t]+",$_,2);
|
|
|
|
#
|
|
# nab the function name
|
|
#** do it again
|
|
($func,$rest) = split("[ \t]+",$rest,2);
|
|
|
|
#
|
|
# and the parameters
|
|
$rest =~ s/.*\(//;
|
|
#** delete all chars before and including the "("
|
|
$rest =~ s/\).*//;
|
|
#** delete all chars after and including the ")"
|
|
$params = $rest;
|
|
#** $params is comman delim param list
|
|
@params = split(',',$rest); #** @params is array of the parameters, cool!
|
|
|
|
#
|
|
# record the function name
|
|
$funcList[$#funcList+1] = $func; #** add the func name to an array each loop
|
|
|
|
#** got the info, now do something with it
|
|
|
|
#
|
|
# Declare the param structure
|
|
#** plug in function name and concat the strings together, write out to file
|
|
print MFILE "#define $func(";
|
|
|
|
for ($i=0;$i<=$#params;$i++)
|
|
{
|
|
if ($i) {print MFILE ",";}
|
|
print MFILE "p" . ($i+1);
|
|
}
|
|
print MFILE ") \\\n";
|
|
|
|
print MFILE "\tCallUniversalProc(gComponentDispatchUPP, \\\n";
|
|
print MFILE "\t\tkD0DispatchedPascalStackBased \\\n";
|
|
|
|
if ($returns ne "void")
|
|
{
|
|
print MFILE "\t\t | RESULT_SIZE(SIZE_CODE(sizeof($returns))) \\\n";
|
|
}
|
|
|
|
print MFILE "\t\t | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)";
|
|
|
|
for ($i=0;$i<=$#params;$i++)
|
|
{
|
|
($type,$littleParam) = split("[ \t]+",$params[$i]);
|
|
$littleParam =~ s/[ \t]+.*//;
|
|
#** deletes everything after the space
|
|
if ($littleParam =~ /^\*/)
|
|
#** if this is a pointer parameter
|
|
{
|
|
$type .= '*';
|
|
|
|
#** add * to type
|
|
}
|
|
print MFILE " \\\n\t\t | DISPATCHED_STACK_ROUTINE_PARAMETER(" . ($i+1) . ", SIZE_CODE(sizeof($type)))";
|
|
}
|
|
print MFILE " \\\n\t\t | DISPATCHED_STACK_ROUTINE_PARAMETER(" . ($#params + 2) . ", kTwoByteCode)";
|
|
print MFILE " \\\n\t\t | DISPATCHED_STACK_ROUTINE_PARAMETER(" . ($#params + 3) . ", kTwoByteCode)";
|
|
|
|
print MFILE ", \\\n\t\t0L, \\\n\t\t";
|
|
|
|
for ($i=0;$i<=$#params;$i++)
|
|
{
|
|
if ($i) {print MFILE ",";}
|
|
print MFILE "(p" . ($i+1) . ")";
|
|
}
|
|
|
|
print MFILE ", \\\n\t\tk" . ($func) . "Rtn";
|
|
print MFILE ", \\\n\t\tk" . ($func) . "ParamSize)\n\n";
|
|
|
|
#
|
|
# UPP enum and ParamSize
|
|
$sizeof = "TWOBYTESIZE(";
|
|
print HFILE "enum {\n";
|
|
print HFILE "\tupp" . $func . "ProcInfo = kPascalStackBased\n";
|
|
if ($returns ne "void")
|
|
{
|
|
print HFILE "\t\t| RESULT_SIZE(SIZE_CODE(sizeof($returns)))\n";
|
|
}
|
|
for ($i=0;$i<=$#params;$i++)
|
|
{
|
|
($type,$littleParam) = split("[ \t]+",$params[$i]);
|
|
$littleParam =~ s/[ \t]+.*//;
|
|
#** deletes everything after the space
|
|
if ($littleParam =~ /^\*/)
|
|
#** if this is a pointer parameter
|
|
{
|
|
$type .= '*';
|
|
|
|
#** add * to type
|
|
}
|
|
print HFILE "\t\t| STACK_ROUTINE_PARAMETER(" . ($i+1) . ", SIZE_CODE(sizeof($type)))\n";
|
|
if($i)
|
|
{
|
|
if($i!=1) {$sizeof .= " + TWOBYTESIZE(";}
|
|
$sizeof .= $type;
|
|
$sizeof .= ")"
|
|
}
|
|
}
|
|
print HFILE "};\n\n";
|
|
|
|
print HFILE "#define k" . ($func) . "ParamSize (" . ($sizeof) . ")\n\n";
|
|
|
|
}
|
|
|
|
} #** end of looping through input.h file
|
|
|
|
#
|
|
# a really big enum
|
|
print HFILE "\ntypedef enum\n{\n";
|
|
print HFILE "\tk$prefix" . "EnumStart=256,\n";
|
|
for ($i=0;$i<=$#funcList;$i++)
|
|
{
|
|
print HFILE "\tk$funcList[$i]" . "Rtn,\n";
|
|
}
|
|
print HFILE "\tk$prefix" . "EnumEnd\n";
|
|
print HFILE "} $prefix" . "ComponentRoutineEnum;\n\n";
|
|
|
|
# put bottom of outputfile.h file stuff here
|
|
print HFILE <<BOILER;
|
|
|
|
#endif
|
|
BOILER
|
|
|
|
# put top of C file stuff here
|
|
print CFILE <<BOILER; #** print everything out to file until you reach 'BOILER'
|
|
#include "petepch.h"
|
|
|
|
#if GENERATINGCFM
|
|
RoutineDescriptor MainRD = BUILD_ROUTINE_DESCRIPTOR(uppComponentRoutineProcInfo, main);
|
|
ProcInfoType __procinfo = uppComponentRoutineProcInfo;
|
|
#endif
|
|
|
|
pascal ComponentResult main(ComponentParameters *params, Handle globals)
|
|
{
|
|
ComponentFunctionUPP routine;
|
|
ComponentInstance inst;
|
|
ComponentResult errCode;
|
|
short refNum;
|
|
long response;
|
|
|
|
if((globals != nil) && ((**(PETEGlobalsHandle)globals).hasBeenCalledCallback != nil)) {
|
|
CallPETEHasBeenCalledProc((**(PETEGlobalsHandle)globals).hasBeenCalledCallback, true);
|
|
}
|
|
|
|
switch(params->what) {
|
|
case kComponentRegisterSelect :
|
|
errCode = Gestalt(gestaltProcessorType, &response);
|
|
if(errCode == noErr) {
|
|
if(response < gestalt68020) {
|
|
errCode = true;
|
|
}
|
|
} else {
|
|
errCode = true;
|
|
}
|
|
goto Exit;
|
|
|
|
case kComponentOpenSelect :
|
|
COMPONENT_UPP_DECLARATION(GetInstance, MyGetInstance, routine);
|
|
inst = (ComponentInstance)CallComponentFunction(params, routine);
|
|
refNum = OpenComponentResFile((Component)inst);
|
|
if(refNum <= 0) {
|
|
errCode = resFNotFound;
|
|
} else {
|
|
errCode = PETEInit((PETEGlobalsHandle *)&globals);
|
|
CloseComponentResFile(refNum);
|
|
}
|
|
if(errCode == noErr) {
|
|
SetComponentInstanceStorage(inst, globals);
|
|
}
|
|
goto Exit;
|
|
|
|
case kComponentCloseSelect :
|
|
if(globals != nil) {
|
|
errCode = PETECleanup((PETEGlobalsHandle)globals);
|
|
globals = nil;
|
|
} else {
|
|
errCode = noErr;
|
|
}
|
|
goto Exit;
|
|
|
|
case kComponentCanDoSelect :
|
|
COMPONENT_UPP_DECLARATION(CanDo, MyCanDo, routine);
|
|
errCode = CallComponentFunction(params, routine);
|
|
goto Exit;
|
|
|
|
case kComponentVersionSelect :
|
|
errCode = kPETECurrentVersion;
|
|
goto Exit;
|
|
|
|
BOILER
|
|
|
|
for ($i=0;$i<=$#funcList;$i++)
|
|
{
|
|
$littleFunc = $funcList[$i];
|
|
# $littleFunc =~ s/$prefix//;
|
|
print CFILE " case k" . $funcList[$i] . "Rtn:\n";
|
|
print CFILE " COMPONENT_UPP_DECLARATION($littleFunc,$littleFunc,routine);\n";
|
|
print CFILE " break;\n\n";
|
|
}
|
|
|
|
#Put bottom of C file here
|
|
print CFILE <<BOILER;
|
|
default :
|
|
errCode = badComponentSelector;
|
|
goto Exit;
|
|
}
|
|
errCode = CallComponentFunctionWithStorage(globals, params, routine);
|
|
|
|
Exit :
|
|
if((globals != nil) && ((**(PETEGlobalsHandle)globals).hasBeenCalledCallback != nil)) {
|
|
CallPETEHasBeenCalledProc((**(PETEGlobalsHandle)globals).hasBeenCalledCallback, false);
|
|
}
|
|
|
|
return errCode;
|
|
}
|
|
|
|
pascal ComponentInstance MyGetInstance(ComponentInstance inst)
|
|
{
|
|
return inst;
|
|
}
|
|
|
|
pascal ComponentResult MyCanDo(short selector)
|
|
{
|
|
return (selector > kPETEEnumStart && selector < kPETEEnumEnd);
|
|
}
|
|
BOILER
|