[comp.sys.mac.hypercard] HyperCard XFCNs in MPW C

STORKEL@RICE.BITNET (Scott Storkel) (01/19/88)

Help! I am trying to compile a Hypercard XFCN written in MPW C. The program
compiles fine, then I try to link it using the following commands:
     
      link -sn Main=Bool -sn STDIO=Bool:
           -sn INTENV=Bool -rt XFCN=5:
           -m BOOL Boolean.c.o "{CLibraries}"CRuntime.o:
           "{CLibraries}"CInterface.o:
           "{CLibraries}"StdCLib.o:
           "{CLibraries}"CSANELib.o:
           -o HyperCommands
     
When I  do this, the compiler gives me the error "Data initialization code is
not being called" and terminates. The output file contains the XFCN resources
Bool=5, and also SADEV=6, SACONSOL=7, and CSANELIB=8.
     
The code was written to conform to the XFCN guidelines available on INFO-MAC,
but uses some additional #include files. The link statement is the same as that
in CFlash.c, except for the additional link modules.
     
What am I doing wrong? How do I get this to compile as a single XCFN resource?
     
Thanks for the info,
     
Scott Storkel
Macintosh Software Development
Rice University

kdmoen@watcgl.waterloo.edu (Doug Moen) (01/31/88)

In article <226STORKEL@RICE> STORKEL@RICE.BITNET (Scott Storkel) writes:
>Help! I am trying to compile a Hypercard XFCN written in MPW C. The program
>compiles fine, then I try to link it using the following commands:
>     
>      link -sn Main=Bool -sn STDIO=Bool:
>           -sn INTENV=Bool -rt XFCN=5:
>           -m BOOL Boolean.c.o "{CLibraries}"CRuntime.o:
>           "{CLibraries}"CInterface.o:
>           "{CLibraries}"StdCLib.o:
>           "{CLibraries}"CSANELib.o:
>           -o HyperCommands
>     
>When I  do this, the compiler gives me the error "Data initialization code is
>not being called" and terminates. The output file contains the XFCN resources
>Bool=5, and also SADEV=6, SACONSOL=7, and CSANELIB=8.

You can't have global variables *or character string literals* in
an XFCN written in MPW C.

Boy was I pissed off when I figured this out.
I don't know of any reasonable workarounds, either.

Some kludges for faking string literals:
* You can put them into STR# resources
* You can use the following C function that I invented:

	strlit(p, s)
	char *p;
	{
		strcpy(p, (char *)&s);
		return p;
	}

Now you can replace character string literals like:
	"foobar"
with:
	char buf[256];
	...
	strlit(buf, 'foob','ar\0\0');

Both kludges are really pretty awful, but I have no better ideas right
now except to write a preprocessor for stripping out string literals
and replacing them with something that the linker won't choke on.

By the way, you can't put global variables or string literals into
INITs, desk accessories, and related code resources, either.

Does anybody at Apple care enough to fix this?
-- 
Doug Moen
University of Waterloo Computer Graphics Lab
UUCP:     {ihnp4,watmath}!watcgl!kdmoen
INTERNET: kdmoen@cgl.waterloo.edu

ephraim@think.COM (ephraim vishniac) (02/02/88)

In article <3105@watcgl.waterloo.edu> kdmoen@watcgl.waterloo.edu (Doug Moen) writes:
>You can't have global variables *or character string literals* in
>an XFCN written in MPW C.

>Boy was I pissed off when I figured this out.
>I don't know of any reasonable workarounds, either.

Sure you do.  As you go on to say:

>Some kludges for faking string literals:
>* You can put them into STR# resources

That's the correct method.  Or 'STR ' resources, or any custom
resource that takes your fancy (preferably with a ResEdit TMPL, to
make editing easy).

>Both kludges are really pretty awful, but I have no better ideas right
>now except to write a preprocessor for stripping out string literals
>and replacing them with something that the linker won't choke on.

What's awful about putting your strings into string list resources?
It's not popular C hacker's style, but it's a hell of a lot easier
than recompiling every time you want to change some trivial message.

>By the way, you can't put global variables or string literals into
>INITs, desk accessories, and related code resources, either.

>Does anybody at Apple care enough to fix this?

Probably not, since nothing is broken.  You've already mentioned the
correct method for embedding text in a program: use separate
resources.  Putting them directly into your code resources will cause
would-be translators of your work to curse your name forever.

Ephraim Vishniac					  ephraim@think.com
Thinking Machines Corporation / 245 First Street / Cambridge, MA 02142-1214

corwin@apple.UUCP (Someone Else) (02/02/88)

In article <3105@watcgl.waterloo.edu> kdmoen@watcgl.waterloo.edu (Doug Moen) writes:
>In article <226STORKEL@RICE> STORKEL@RICE.BITNET (Scott Storkel) writes:
>>Help! I am trying to compile a Hypercard XFCN written in MPW C. The program
>>compiles fine, then I try to link it using the following commands:
>>     
>>      link -sn Main=Bool -sn STDIO=Bool:
>>           -sn INTENV=Bool -rt XFCN=5:
>>           -m BOOL Boolean.c.o "{CLibraries}"CRuntime.o:
>>           "{CLibraries}"CInterface.o:
>>           "{CLibraries}"StdCLib.o:
>>           "{CLibraries}"CSANELib.o:
>>           -o HyperCommands

just a side note... it is much easier to use the -sg option than 
a bunch of -sn's  (it also works better!)

>>When I  do this, the compiler gives me the error "Data initialization code is
>>not being called" and terminates. The output file contains the XFCN resources
>>Bool=5, and also SADEV=6, SACONSOL=7, and CSANELIB=8.

it eliminates multiple code resources such as in the above case.

>You can't have global variables *or character string literals* in
>an XFCN written in MPW C.

>Some kludges for faking string literals:
>* You can put them into STR# resources

[code deleted]

>Now you can replace character string literals like:
>	"foobar"
>with:
>	char buf[256];
>	...
>	strlit(buf, 'foob','ar\0\0');

which is nice, as long as you are not using a MC68020... MPW C
has a tendancy to misalign longwords... the MC68020 can deal with
this... a MC68000 will crash.  I learned the hard way... I have 
somewhere between 20 and 40 XCMDs that used something similar...
care to guess how long it took me to rewrite all of them to use 
resources?

For the record, as long as you are not going to be running your
XCMD more than about 10,000 times before re-starting hypercard,
you can use strings (as well as several other things) with LSC.

(if anyone is interested, I have a code sample that will crash 
after ~10K executions)

-cory



-- 
#include <stddisclaimer.h>
UUCP: {sun,voder,nsc,mtxinu,dual}!apple!corwin
CSNET: corwin@apple.com
ARPA:  corwin@apple.com

steele@unc.cs.unc.edu (Oliver Steele) (02/03/88)

kdmoen@watcgl.waterloo.edu {Doug Moen} writes:
}You can't have global variables *or character string literals* in
}an XFCN written in MPW C.
}[....]
}Some kludges for faking string literals:
}* You can put them into STR# resources

ephraim@vidar.think.com.UUCP [ephraim vishniac] writes:
]That's the correct method.  Or 'STR ' resources, or any custom
]resource that takes your fancy (preferably with a ResEdit TMPL, to
]make editing easy).

}Both kludges are really pretty awful, but I have no better ideas right
}now except to write a preprocessor for stripping out string literals
}and replacing them with something that the linker won't choke on.

]What's awful about putting your strings into string list resources?
]It's not popular C hacker's style, but it's a hell of a lot easier
]than recompiling every time you want to change some trivial message.

What's awful is that most (all?) of the existing HyperCard resource
movers, XFCN installers, etc., will copy only your XFCN or XCMD, without
checking to see if there are any 'STR 's or 'STR#'s with the same number.
Perhaps it's time for Apple to roll out those RSV[12]s for X*s, but until
and unless some method of associating X*s with their owned resources
becomes a standard, don't use extra resources if your code is meant to
be user-installable.  Lost are the days when we can assume that anybody
installing or moving resources is a hacker with ResEdit.

----------------------------------------------------------------------------
Oliver Steele					   ...!uunet!mcnc!unc!steele
							   steele@cs.unc.edu
"If they weren't guilty, they wouldn't be suspects"
					-- Ed Meese

tomas@apple.UUCP (Tom Taylor) (02/09/88)

In article <3105@watcgl.waterloo.edu> kdmoen@watcgl.waterloo.edu (Doug Moen) writes:
>In article <226STORKEL@RICE> STORKEL@RICE.BITNET (Scott Storkel) writes:
>>Help! I am trying to compile a Hypercard XFCN written in MPW C. The program
>>compiles fine, then I try to link it using the following commands:
>>     
>>      link -sn Main=Bool -sn STDIO=Bool:
>>           -sn INTENV=Bool -rt XFCN=5:
>>           -m BOOL Boolean.c.o "{CLibraries}"CRuntime.o:
>>           "{CLibraries}"CInterface.o:
>>           "{CLibraries}"StdCLib.o:
>>           "{CLibraries}"CSANELib.o:
>>           -o HyperCommands
>>     
>>When I  do this, the compiler gives me the error "Data initialization code is
>>not being called" and terminates. The output file contains the XFCN resources
>>Bool=5, and also SADEV=6, SACONSOL=7, and CSANELIB=8.
>
>You can't have global variables *or character string literals* in
>an XFCN written in MPW C.
>
>Boy was I pissed off when I figured this out.
>I don't know of any reasonable workarounds, either.
>
>Some kludges for faking string literals:
>* You can put them into STR# resources
>* You can use the following C function that I invented:
>
>	strlit(p, s)
>	char *p;
>	{
>		strcpy(p, (char *)&s);
>		return p;
>	}
>
>Now you can replace character string literals like:
>	"foobar"
>with:
>	char buf[256];
>	...
>	strlit(buf, 'foob','ar\0\0');
>
>Both kludges are really pretty awful, but I have no better ideas right
>now except to write a preprocessor for stripping out string literals
>and replacing them with something that the linker won't choke on.
>
>By the way, you can't put global variables or string literals into
>INITs, desk accessories, and related code resources, either.
>
>Does anybody at Apple care enough to fix this?
>-- 
>Doug Moen
>University of Waterloo Computer Graphics Lab
>UUCP:     {ihnp4,watmath}!watcgl!kdmoen
>INTERNET: kdmoen@cgl.waterloo.edu

Here is a way, though not elegant, to put string literals in the
code of a standalone resource.  Basically, you put the string literals
in an assembly file with DC.B.  Each string must be declared in a
PROC statement.  On the C side, declare the strings as extern char *stringname.
When linking as a standalone code resource, the linker knows to force
all references to the string as code-to-code references, and so does not
use the jump table.

Example:

In ASM:

stringFoo	PROC	EXPORT
	DC.B	'This is a string'
	ENDPROC
	END

In C:

extern char *stringFoo;

NOTE: the link order is important... the C file with the code must
      appear in the link list before the asm file with the data.  The
      reason is that most routines that call these code resources simply
      load the resource and jump to the beginning.

This is not pretty.  I still recommend putting strings in resources.
The 3.0 C compiler has an option to put constants and strings at the
end of the code so that these problems will disappear.

Tom Taylor
Development Systems Group

john@viper.Lynx.MN.Org (John Stanley) (02/11/88)

In article <7360@apple.UUCP> tomas@apple.UUCP (Tom Taylor) writes:
 >
 >Here is a way, though not elegant, to put string literals in the
 >code of a standalone resource.  
.......
 >
 >Example:
 >
 >In ASM:
 >
 >stringFoo	PROC	EXPORT
 >	DC.B	'This is a string'
 >	ENDPROC
 >	END
 >
 >In C:
 >
 >extern char *stringFoo;

  I don't know much about using C on the Mac, but I do know a good
deal about mixing C and assembly language on a 68000 based machine and
this "looks very wrong"....

  If you define a data constant in assembly using DC.B you can then
access the string and/or data structure by defining it as external in
your C code, but you need to define it AS-A-STRING, not as a pointer.
If it were a pointer that would be different, but your example
explicitly defines the data to be at stringFoo, not a pointer to the
string... Thus the C define to access the assembly-string would be:

	extern char stringFoo[];

 >
 >Tom Taylor
 >Development Systems Group
 >

--- 
John Stanley (john@viper.UUCP)
Software Consultant - DynaSoft Systems
UUCP: ...{amdahl,ihnp4,rutgers}!meccts!viper!john