Compare commits

...

49 Commits

Author SHA1 Message Date
Andy McFadden
811ebe9ba3
Merge pull request #15 from fweimer-rh/c99
configure: Fix C99 compatibility issue
2023-01-27 07:26:12 -08:00
Florian Weimer
6eb33543cb configure: Fix C99 compatibility issue
Avoid calling the undeclared exit function.  This avoids a check
failure with a future compiler that does not support implicit
function declarations.
2023-01-27 10:22:42 +01:00
Andy McFadden
0f957f9e83 Update URL 2022-10-08 09:13:24 -07:00
Andy McFadden
918f318ca4 Update URL 2022-10-08 09:12:22 -07:00
Andy McFadden
ca8605c403 Update autoconf scripts
I re-ran "autoconf", which made minor changes to the nufxlib configure
script, and copied the latest (v2.71) config.sub/config.guess scripts.

(issue #14)
2022-07-20 09:43:57 -07:00
Andy McFadden
2a5e5bc299
Merge pull request #10 from ksherlock/pkg-config
pkg-config support for nufxlib
2020-10-15 10:45:50 -07:00
Kelvin Sherlock
ae66fba7bc pkg-config support
will generate nufxlib.pc and install to the pkgconfig directory
for use with the oft-used pkg-config utility.
2020-10-14 23:18:02 -04:00
Andy McFadden
0619ef3fe7
Merge pull request #9 from skitt/packaging-fixes
Packaging fixes
2019-05-04 14:35:40 -07:00
Stephen Kitt
7ec4eb46c7
Honour LDFLAGS when linking
Most of the build handles flags fine, since it uses the built-in Make
rules. However the linking step ignores LDFLAGS, which means some link
flags used in Linux distributions are ignored.

Signed-off-by: Stephen Kitt <steve@sk2.org>
2019-05-04 23:04:46 +02:00
Stephen Kitt
21a10ad266
Install to DESTDIR
Packaging systems commonly specify DESTDIR as a temporary directory in
which to install the build artifacts. Its use is transparent in other
contexts.

Signed-off-by: Stephen Kitt <steve@sk2.org>
2019-05-04 23:04:14 +02:00
Stephen Kitt
f6ff60420b
Add AC_DEFINE descriptions
This allows current autoheader to process configure.in, preserving the
comments in config.h.in.

Signed-off-by: Stephen Kitt <steve@sk2.org>
2019-05-04 23:02:16 +02:00
Stephen Kitt
ea89644bfa
Ensure the library is built before the samples
When building in parallel, Make can start building the samples before
it’s finished building the library, which causes the build to fail.
Adding an explicit dependency ensures that the library is built before
the samples.

Signed-off-by: Stephen Kitt <steve@sk2.org>
2019-05-04 23:00:48 +02:00
Andy McFadden
9fdc77a108 Add -fPIC to CFLAGS
It's needed for "make shared".  Not needed (or desired) for static
libs, but it's nearly harmless.
2018-08-07 20:47:56 -07:00
Andy McFadden
137cafa05b Update version for v3.1.0 release 2017-09-21 11:52:37 -07:00
Andy McFadden
20fe7efb4d Fix extraction of disk images
A recent change was causing NufxLib to try to create a fake
empty data thread in records that had nothing but a disk image
thread.
2016-01-11 09:11:30 -08:00
Andy McFadden
51af83986c Fix test-twirl
The test was expecting the order of threads not to change, which
was reasonable until we started throwing fake threads at it with
the recent change to "mask dataless".  We now employ a hack that
reorders the CRCs from data-class threads so that the data fork's
CRC always comes first.  Not a tremendously robust solution, but
it'll do.
2015-12-26 15:55:58 -08:00
Andy McFadden
bbeb9eaf90 Update ChangeLog
Probably silly now that everything is on github.
2015-12-26 15:41:11 -08:00
Andy McFadden
7f158dd206 Update "recognized extensions" table
Added ".cpp" and ".text" as recognized extensions, so that NuLib2
and CiderPress match.

Fixed up the table a bit, using better-suited types and removing
an unnecessary field.
2015-12-26 15:28:39 -08:00
Andy McFadden
eb40d65f1d Improve Mac OS X file type handling
The previous code only created files with 'pdos'/'pXYZ' attributes,
and didn't correctly recognize specific types like 'pdos'/'TEXT'.
The code should now perform the conversions according to the spec,
though it still doesn't handle the 'pdos'/'XY  ' case.
2015-12-26 15:22:16 -08:00
Andy McFadden
f37b387cc6 Fix handling of entries with missing threads
When GSHK adds files to an archive, it doesn't create threads for
zero-length data and resource forks.  NufxLib had a workaround
for this, but it wasn't handling all possible cases.  We now
fully handle "Miranda threads" (if you cannot afford a thread,
one will be provided for you).

This broke test-basic, because a callback gets called one extra
time now due to the additional thread.  It also broke test-twirl,
which uses "mask dataless" and is sensitive to the order in which
threads appear.  (test-twirl actually works just fine, but the
CRC check is too simple-minded, and is arguably incorrect.)

Since this can apparently break things, I'm making this a minor
version bump, to 3.1.0-a1.

I also tweaked the NuLib2 file listing to test for the extended
file storage type, rather than simply scanning for data threads.
Forked files are now listed as such, even when they're missing
the actual resource fork data thread.
2015-12-26 12:05:13 -08:00
Andy McFadden
bc96aa420b Update SysDefs for Visual Studio 2015
Apparently VS2015 now includes definitions for snprintf/vsnprintf.

Not tested with VS2015.
2015-11-15 15:36:01 -08:00
Andy McFadden
508531fb54 Windows 2015-03-08 11:33:17 -07:00
Andy McFadden
ae8eec5d1b Add arg to exerciser "af"
Updated the NuAddFile command to take an extra argument that
identifies the source as coming from a resource fork.  You can't
actually use this to create a forked entry without some behind-
the-scenes renaming, because the exerciser uses the disk filename
as the storage filename, and the "add file" code won't be able to
match the entries up.
2015-03-08 11:01:13 -07:00
Andy McFadden
8d2f1a5479 Add test-names to README-S.txt 2015-01-09 13:44:39 -08:00
Andy McFadden
506e278e34 Minor tweaks for consistency 2015-01-09 11:52:56 -08:00
Andy McFadden
5a5d8993d3 Bump version to 3.0.0 2015-01-09 10:59:33 -08:00
Andy McFadden
6ba112fdfe Include file/line info without DEBUG_MSGS
For some reason the __FILE__ and __LINE__ stuff was disabled when
DEBUG_MSGS wasn't enabled.  It's now enabled.
2015-01-07 15:06:25 -08:00
Andy McFadden
137f209a3f Set the Finder info before the access permissions
Looks like setxattr() requires write access, so we need to set
the Finder info before we "lock" the file.
2015-01-06 10:50:30 -08:00
Andy McFadden
e5b74c28f2 Add Unicode details to NOTES
Also, switch from plain text to markdown.  The plain text form is
nearly identical, but it's much nicer when viewed on github.
2015-01-04 15:31:35 -08:00
Andy McFadden
0137d4ef38 Win32 API fix 2015-01-04 11:29:18 -08:00
Andy McFadden
3ee3c9451e Update README 2015-01-03 17:33:35 -08:00
Andy McFadden
cf4ab2ee2f Mention OS X in README 2015-01-03 17:07:43 -08:00
Andy McFadden
76ee85b6ec Update README
Added note to Win32 section about missing Unicode support.
2015-01-03 17:05:58 -08:00
Andy McFadden
24a49dfece Update ChangeLog 2015-01-03 17:01:38 -08:00
Andy McFadden
132a8338b9 Fix Mac OS X behavior
Some fixes to the Mac OS X build:

- Replace the Carbon calls that were used to set the creator
and file type with xattr calls.  The Carbon stuff still worked
but caused deprecation warnings.  Stop linking against Carbon.

- Correct the way resource forks are accessed (from "/rsrc" to
"/..namedfork/rsrc").  The native resource fork support is
incomplete and doesn't work quite right, so it's now disabled.
(Which means the corrections to the file name don't actually do
anything, but you can at least play with it.)

- Correct the file/aux type conversion, which appeared to do
useful things but actually didn't in some circumstances (e.g. when
adding files, the code for acquiring the file types needs to be in
NuLib2, not NufxLib).

- Set creator and file type to 'pdos' values when extracting from
a Binary ][ archive.

Also, drop some old purify/quantify stuff.
2015-01-03 15:59:37 -08:00
Andy McFadden
1286c3518e Minor Mac fixes
Eliminated the two inline functions.  Support for function inlining
in plain C is a bit uneven.  The CRC calculation is now a macro,
and the thread get-by-index is a plain function.
2015-01-03 11:24:12 -08:00
Andy McFadden
c6c7133d43 Drop SunOS 4 support 2015-01-02 18:17:00 -08:00
Andy McFadden
ad2ec98e8b Win32 fix 2015-01-02 17:44:10 -08:00
Andy McFadden
e7bf743afd Missed a filename 2015-01-02 17:23:35 -08:00
Andy McFadden
e2088e64d3 Distinguish Unicode and Mac OS Roman strings
NufxLib has historically made no effort to distinguish between
the character set used for filenames on the local disk, and for
filenames stored within the archive.  Now all Unicode filename
strings use the UNICHAR type and have "UNI" in the name, and all
Mac OS Roman strings have "MOR" in the name.  (The naming
convention makes it obvious when you're assigning the wrong thing;
on Linux both formats are char*, so the compiler won't tell you
if you get it wrong.)

The distinction is necessary because filesystems generally support
Unicode these days, but on Windows you need to use a separate
set of wide-character file I/O functions.  (On Linux it all works
with "narrow" strings, and the UTF-8 encoding is interpreted by
applications.)  The character set used for NuFX archive filenames
is MOR, matching what GS/OS + HFS supported, and we want to be able
to convert back and forth between MOR and a Unicode representation.

This change updates the various character types and string names,
adds conversion functions, and updates NuLib2 for proper execution
on Linux.  It does not include the (probably extensive) changes
required for Windows UTF-16 support.  Instead, the conversion
functions are no-ops, which should result in NuLib2 for Windows
continuing to behave in the same slightly broken way.

This adds "test-names", which exercises Unicode filenames a bit.
It will not pass on Win32.

Also, tweaked the Linux makefiles to have explicit dependencies,
rather than empty space and an expectation that "makedepend" exists.

Also, minor source code cleanups.

While this probably doesn't affect binary compatibility -- it's
mainly a matter of naming and string interpretation -- there's
enough going on that it should be considered an API revision, so
this updates the version to 3.0.0.
2015-01-02 17:14:34 -08:00
Andy McFadden
f4dea8b251 Update READMEs
Updated the build instructions in the READMEs.
2014-12-23 11:29:01 -08:00
Andy McFadden
5d5dd3900f Missed a "uint". 2014-12-22 16:20:39 -08:00
Andy McFadden
dbbbe6a858 Version bump to 2.3.0 2014-12-22 16:12:06 -08:00
Andy McFadden
524e0926e7 Fix include guards
Symbols starting with "__" are reserved for use by the compiler.
2014-12-22 16:06:55 -08:00
Andy McFadden
9666ebd97a Move method return type to declaration line
Having the method name up against the left edge used to be common
practice, because you could jump to a method quickly by searching
for "^name".  Now we have "ctags" and IDEs.
2014-12-22 16:00:33 -08:00
Andy McFadden
20c9ac1195 Use integer types with explicit widths
Replace types like "unsigned char" and "ushort" with <stdint.h>
types like uint8_t.

Remove uchar/ushort/uint/ulong from autoconf.
2014-12-22 14:56:12 -08:00
Andy McFadden
ce1b57e2ad Change "nil" to "NULL" 2014-12-21 18:17:23 -08:00
Andy McFadden
cf433eeae0 Don't delete Version.c
We used to generate Version.c, so it was being removed by the
"distclean" target.
2014-12-21 10:18:26 -08:00
Andy McFadden
281813a8ea Tweak .gitignore 2014-12-11 16:28:38 -08:00
78 changed files with 10483 additions and 8482 deletions

View File

@ -7,9 +7,8 @@ operate on ShrinkIt and Binary II files (.shk, .sdk, .bxy, .bse, .bny, .bqy).
NufxLib is a library of code that supports ShrinkIt archives. It's
used by NuLib2 and CiderPress.
A pre-built NuLib2 binary is available for x86 Windows. For Linux systems,
you can download the source code and build it.
A pre-built NuLib2 binary is available for x86 Windows. For Linux and
Mac OS X systems, you can download the source code and build it.
More information, including full documentation for NuLib2 and NufxLib,
can be found on http://www.nulib.com/.
can be found on https://nulib.com/ (or https://fadden.github.io/nulib2).

21
nufxlib/.gitignore vendored
View File

@ -1,12 +1,17 @@
# config-generated sources
Makefile
Version.c
config.h
config.log
config.status
exerciser
imgconv
launder
test-basic
test-extract
test-simple
test-twirl
nufxlib.pc
# generated binaries
libnufx.a
samples/exerciser
samples/imgconv
samples/launder
samples/test-basic
samples/test-extract
samples/test-names
samples/test-simple
samples/test-twirl

View File

@ -16,13 +16,13 @@
#endif
/* master header identification */
static const uchar kNuMasterID[kNufileIDLen] =
static const uint8_t kNuMasterID[kNufileIDLen] =
{ 0x4e, 0xf5, 0x46, 0xe9, 0x6c, 0xe5 };
/* other identification; can be no longer than kNufileIDLen */
static const uchar kNuBinary2ID[] =
static const uint8_t kNuBinary2ID[] =
{ 0x0a, 0x47, 0x4c };
static const uchar kNuSHKSEAID[] =
static const uint8_t kNuSHKSEAID[] =
{ 0xa2, 0x2e, 0x00 };
/*
@ -53,19 +53,16 @@ static void Nu_CloseAndFree(NuArchive* pArchive);
/*
* Allocate and initialize a new NuArchive structure.
*/
static NuError
Nu_NuArchiveNew(NuArchive** ppArchive)
static NuError Nu_NuArchiveNew(NuArchive** ppArchive)
{
Assert(ppArchive != nil);
Assert(ppArchive != NULL);
/* validate some assumptions we make throughout the code */
Assert(sizeof(int) >= 2);
Assert(sizeof(ushort) >= 2);
Assert(sizeof(ulong) >= 4);
Assert(sizeof(void*) >= sizeof(NuArchive*));
*ppArchive = Nu_Calloc(nil, sizeof(**ppArchive));
if (*ppArchive == nil)
*ppArchive = Nu_Calloc(NULL, sizeof(**ppArchive));
if (*ppArchive == NULL)
return kNuErrMalloc;
(*ppArchive)->structMagic = kNuArchiveStructMagic;
@ -107,10 +104,9 @@ Nu_NuArchiveNew(NuArchive** ppArchive)
/*
* Free up a NuArchive structure and its contents.
*/
static NuError
Nu_NuArchiveFree(NuArchive* pArchive)
static NuError Nu_NuArchiveFree(NuArchive* pArchive)
{
Assert(pArchive != nil);
Assert(pArchive != NULL);
Assert(pArchive->structMagic == kNuArchiveStructMagic);
(void) Nu_RecordSet_FreeAllRecords(pArchive, &pArchive->origRecordSet);
@ -118,15 +114,15 @@ Nu_NuArchiveFree(NuArchive* pArchive)
(void) Nu_RecordSet_FreeAllRecords(pArchive, &pArchive->copyRecordSet);
(void) Nu_RecordSet_FreeAllRecords(pArchive, &pArchive->newRecordSet);
Nu_Free(nil, pArchive->archivePathname);
Nu_Free(nil, pArchive->tmpPathname);
Nu_Free(nil, pArchive->compBuf);
Nu_Free(nil, pArchive->lzwCompressState);
Nu_Free(nil, pArchive->lzwExpandState);
Nu_Free(NULL, pArchive->archivePathnameUNI);
Nu_Free(NULL, pArchive->tmpPathnameUNI);
Nu_Free(NULL, pArchive->compBuf);
Nu_Free(NULL, pArchive->lzwCompressState);
Nu_Free(NULL, pArchive->lzwExpandState);
/* mark it as deceased to prevent further use, then free it */
pArchive->structMagic = kNuArchiveStructMagic ^ 0xffffffff;
Nu_Free(nil, pArchive);
Nu_Free(NULL, pArchive);
return kNuErrNone;
}
@ -135,13 +131,12 @@ Nu_NuArchiveFree(NuArchive* pArchive)
/*
* Copy a NuMasterHeader struct.
*/
void
Nu_MasterHeaderCopy(NuArchive* pArchive, NuMasterHeader* pDstHeader,
void Nu_MasterHeaderCopy(NuArchive* pArchive, NuMasterHeader* pDstHeader,
const NuMasterHeader* pSrcHeader)
{
Assert(pArchive != nil);
Assert(pDstHeader != nil);
Assert(pSrcHeader != nil);
Assert(pArchive != NULL);
Assert(pDstHeader != NULL);
Assert(pSrcHeader != NULL);
*pDstHeader = *pSrcHeader;
}
@ -149,10 +144,10 @@ Nu_MasterHeaderCopy(NuArchive* pArchive, NuMasterHeader* pDstHeader,
/*
* Get a pointer to the archive master header (this is an API call).
*/
NuError
Nu_GetMasterHeader(NuArchive* pArchive, const NuMasterHeader** ppMasterHeader)
NuError Nu_GetMasterHeader(NuArchive* pArchive,
const NuMasterHeader** ppMasterHeader)
{
if (ppMasterHeader == nil)
if (ppMasterHeader == NULL)
return kNuErrInvalidArg;
*ppMasterHeader = &pArchive->masterHeader;
@ -164,16 +159,15 @@ Nu_GetMasterHeader(NuArchive* pArchive, const NuMasterHeader** ppMasterHeader)
/*
* Allocate the general-purpose compression buffer, if needed.
*/
NuError
Nu_AllocCompressionBufferIFN(NuArchive* pArchive)
NuError Nu_AllocCompressionBufferIFN(NuArchive* pArchive)
{
Assert(pArchive != nil);
Assert(pArchive != NULL);
if (pArchive->compBuf != nil)
if (pArchive->compBuf != NULL)
return kNuErrNone;
pArchive->compBuf = Nu_Malloc(pArchive, kNuGenCompBufSize);
if (pArchive->compBuf == nil)
if (pArchive->compBuf == NULL)
return kNuErrMalloc;
return kNuErrNone;
@ -183,8 +177,7 @@ Nu_AllocCompressionBufferIFN(NuArchive* pArchive)
/*
* Return a unique value.
*/
NuRecordIdx
Nu_GetNextRecordIdx(NuArchive* pArchive)
NuRecordIdx Nu_GetNextRecordIdx(NuArchive* pArchive)
{
return pArchive->nextRecordIdx++;
}
@ -192,8 +185,7 @@ Nu_GetNextRecordIdx(NuArchive* pArchive)
/*
* Return a unique value.
*/
NuThreadIdx
Nu_GetNextThreadIdx(NuArchive* pArchive)
NuThreadIdx Nu_GetNextThreadIdx(NuArchive* pArchive)
{
return pArchive->nextRecordIdx++; /* just use the record counter */
}
@ -208,8 +200,7 @@ Nu_GetNextThreadIdx(NuArchive* pArchive)
/*
* Copy the wrapper from the archive file to the temp file.
*/
NuError
Nu_CopyWrapperToTemp(NuArchive* pArchive)
NuError Nu_CopyWrapperToTemp(NuArchive* pArchive)
{
NuError err;
@ -247,13 +238,12 @@ bail:
* guess some of the SEA weirdness stems from some far-sighted support
* for multiple archives within a single SEA wrapper.
*/
NuError
Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp)
NuError Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp)
{
NuError err = kNuErrNone;
Boolean hasBinary2, hasSea;
uchar identBuf[kNufileIDLen];
ulong archiveLen, archiveLen512;
uint8_t identBuf[kNufileIDLen];
uint32_t archiveLen, archiveLen512;
Assert(pArchive->newMasterHeader.isValid); /* need new crc and len */
@ -306,20 +296,20 @@ Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp)
err = Nu_FSeek(fp, kNuBNYFileSizeLo - kNufileIDLen, SEEK_CUR);
BailError(err);
Nu_WriteTwo(pArchive, fp, (ushort)(archiveLen512 & 0xffff));
Nu_WriteTwo(pArchive, fp, (uint16_t)(archiveLen512 & 0xffff));
err = Nu_FSeek(fp, kNuBNYFileSizeHi - (kNuBNYFileSizeLo+2), SEEK_CUR);
BailError(err);
Nu_WriteTwo(pArchive, fp, (ushort)(archiveLen512 >> 16));
Nu_WriteTwo(pArchive, fp, (uint16_t)(archiveLen512 >> 16));
err = Nu_FSeek(fp, kNuBNYEOFLo - (kNuBNYFileSizeHi+2), SEEK_CUR);
BailError(err);
Nu_WriteTwo(pArchive, fp, (ushort)(archiveLen & 0xffff));
Nu_WriteOne(pArchive, fp, (uchar)((archiveLen >> 16) & 0xff));
Nu_WriteTwo(pArchive, fp, (uint16_t)(archiveLen & 0xffff));
Nu_WriteOne(pArchive, fp, (uint8_t)((archiveLen >> 16) & 0xff));
err = Nu_FSeek(fp, kNuBNYEOFHi - (kNuBNYEOFLo+3), SEEK_CUR);
BailError(err);
Nu_WriteOne(pArchive, fp, (uchar)(archiveLen >> 24));
Nu_WriteOne(pArchive, fp, (uint8_t)(archiveLen >> 24));
err = Nu_FSeek(fp, kNuBNYDiskSpace - (kNuBNYEOFHi+1), SEEK_CUR);
BailError(err);
@ -358,11 +348,11 @@ Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp)
err = Nu_FSeek(fp, kNuSEALength1 - (kNuSEAFunkySize+4), SEEK_CUR);
BailError(err);
Nu_WriteTwo(pArchive, fp, (ushort)archiveLen);
Nu_WriteTwo(pArchive, fp, (uint16_t)archiveLen);
err = Nu_FSeek(fp, kNuSEALength2 - (kNuSEALength1+2), SEEK_CUR);
BailError(err);
Nu_WriteTwo(pArchive, fp, (ushort)archiveLen);
Nu_WriteTwo(pArchive, fp, (uint16_t)archiveLen);
/* seek past end of SEA wrapper */
err = Nu_FSeek(fp, kNuSEAOffset - (kNuSEALength2+2), SEEK_CUR);
@ -399,8 +389,7 @@ bail:
* require additional disk space to be used, assuming a filesystem block
* size of at least 128 bytes.
*/
NuError
Nu_AdjustWrapperPadding(NuArchive* pArchive, FILE* fp)
NuError Nu_AdjustWrapperPadding(NuArchive* pArchive, FILE* fp)
{
NuError err = kNuErrNone;
Boolean hasBinary2, hasSea;
@ -495,17 +484,16 @@ bail:
*
* On exit, the stream will be positioned just past the master header.
*/
static NuError
Nu_ReadMasterHeader(NuArchive* pArchive)
static NuError Nu_ReadMasterHeader(NuArchive* pArchive)
{
NuError err;
ushort crc;
uint16_t crc;
FILE* fp;
NuMasterHeader* pHeader;
Boolean isBinary2 = false;
Boolean isSea = false;
Assert(pArchive != nil);
Assert(pArchive != NULL);
fp = pArchive->archiveFp; /* saves typing */
pHeader = &pArchive->masterHeader;
@ -640,7 +628,7 @@ retry:
/* compare the CRC */
if (!pArchive->valIgnoreCRC && crc != pHeader->mhMasterCRC) {
if (!Nu_ShouldIgnoreBadCRC(pArchive, nil, kNuErrBadMHCRC)) {
if (!Nu_ShouldIgnoreBadCRC(pArchive, NULL, kNuErrBadMHCRC)) {
err = kNuErrBadMHCRC;
Nu_ReportError(NU_BLOB, err, "Stored MH CRC=0x%04x, calc=0x%04x",
pHeader->mhMasterCRC, crc);
@ -669,7 +657,7 @@ retry:
if (pHeader->mhMasterEOF == kNuMasterHeaderSize) {
err = kNuErrNoRecords;
Nu_ReportError(NU_BLOB, err,
"Master EOF is %ld, archive is probably truncated",
"Master EOF is %u, archive is probably truncated",
pHeader->mhMasterEOF);
goto bail;
}
@ -712,12 +700,11 @@ bail:
* Prepare the NuArchive and NuMasterHeader structures for use with a
* newly-created archive.
*/
static void
Nu_InitNewArchive(NuArchive* pArchive)
static void Nu_InitNewArchive(NuArchive* pArchive)
{
NuMasterHeader* pHeader;
Assert(pArchive != nil);
Assert(pArchive != NULL);
pHeader = &pArchive->masterHeader;
@ -741,14 +728,13 @@ Nu_InitNewArchive(NuArchive* pArchive)
/*
* Open an archive in streaming read-only mode.
*/
NuError
Nu_StreamOpenRO(FILE* infp, NuArchive** ppArchive)
NuError Nu_StreamOpenRO(FILE* infp, NuArchive** ppArchive)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
Assert(infp != nil);
Assert(ppArchive != nil);
Assert(infp != NULL);
Assert(ppArchive != NULL);
err = Nu_NuArchiveNew(ppArchive);
if (err != kNuErrNone)
@ -757,16 +743,16 @@ Nu_StreamOpenRO(FILE* infp, NuArchive** ppArchive)
pArchive->openMode = kNuOpenStreamingRO;
pArchive->archiveFp = infp;
pArchive->archivePathname = strdup("(stream)");
pArchive->archivePathnameUNI = strdup("(stream)");
err = Nu_ReadMasterHeader(pArchive);
BailError(err);
bail:
if (err != kNuErrNone) {
if (pArchive != nil)
if (pArchive != NULL)
(void) Nu_NuArchiveFree(pArchive);
*ppArchive = nil;
*ppArchive = NULL;
}
return err;
}
@ -775,21 +761,24 @@ bail:
/*
* Open an archive in non-streaming read-only mode.
*/
NuError
Nu_OpenRO(const char* archivePathname, NuArchive** ppArchive)
NuError Nu_OpenRO(const UNICHAR* archivePathnameUNI, NuArchive** ppArchive)
{
NuError err;
NuArchive* pArchive = nil;
FILE* fp = nil;
NuArchive* pArchive = NULL;
FILE* fp = NULL;
if (archivePathname == nil || !strlen(archivePathname) || ppArchive == nil)
if (archivePathnameUNI == NULL || !strlen(archivePathnameUNI) ||
ppArchive == NULL)
{
return kNuErrInvalidArg;
}
*ppArchive = nil;
*ppArchive = NULL;
fp = fopen(archivePathname, kNuFileOpenReadOnly);
if (fp == nil) {
Nu_ReportError(NU_BLOB, errno, "Unable to open '%s'", archivePathname);
fp = fopen(archivePathnameUNI, kNuFileOpenReadOnly);
if (fp == NULL) {
Nu_ReportError(NU_BLOB, errno, "Unable to open '%s'",
archivePathnameUNI);
err = kNuErrFileOpen;
goto bail;
}
@ -801,19 +790,19 @@ Nu_OpenRO(const char* archivePathname, NuArchive** ppArchive)
pArchive->openMode = kNuOpenRO;
pArchive->archiveFp = fp;
fp = nil;
pArchive->archivePathname = strdup(archivePathname);
fp = NULL;
pArchive->archivePathnameUNI = strdup(archivePathnameUNI);
err = Nu_ReadMasterHeader(pArchive);
BailError(err);
bail:
if (err != kNuErrNone) {
if (pArchive != nil) {
if (pArchive != NULL) {
(void) Nu_CloseAndFree(pArchive);
*ppArchive = nil;
*ppArchive = NULL;
}
if (fp != nil)
if (fp != NULL)
fclose(fp);
}
return err;
@ -822,15 +811,15 @@ bail:
/*
* Open a temp file. If "fileName" contains six Xs ("XXXXXX"), it will
* be treated as a mktemp-style template, and modified before use.
* be treated as a mktemp-style template, and modified before use (so
* pass a copy of the string in).
*
* Thought for the day: consider using Win32 SetFileAttributes() to make
* temp files hidden. We will need to un-hide it before rolling it over.
*/
static NuError
Nu_OpenTempFile(char* fileName, FILE** pFp)
static NuError Nu_OpenTempFile(UNICHAR* fileNameUNI, FILE** pFp)
{
NuArchive* pArchive = nil; /* dummy for NU_BLOB */
NuArchive* pArchive = NULL; /* dummy for NU_BLOB */
NuError err = kNuErrNone;
int len;
@ -843,25 +832,25 @@ Nu_OpenTempFile(char* fileName, FILE** pFp)
* to complain about mktemp, since it's generally a bad way to do
* things.
*/
len = strlen(fileName);
if (len > 6 && strcmp(fileName + len - 6, "XXXXXX") == 0) {
len = strlen(fileNameUNI);
if (len > 6 && strcmp(fileNameUNI + len - 6, "XXXXXX") == 0) {
#if defined(HAVE_MKSTEMP) && defined(HAVE_FDOPEN)
int fd;
DBUG(("+++ Using mkstemp\n"));
/* this modifies the template *and* opens the file */
fd = mkstemp(fileName);
fd = mkstemp(fileNameUNI);
if (fd < 0) {
err = errno ? errno : kNuErrFileOpen;
Nu_ReportError(NU_BLOB, kNuErrNone, "mkstemp failed on '%s'",
fileName);
fileNameUNI);
goto bail;
}
DBUG(("--- Fd-opening temp file '%s'\n", fileName));
DBUG(("--- Fd-opening temp file '%s'\n", fileNameUNI));
*pFp = fdopen(fd, kNuFileOpenReadWriteCreat);
if (*pFp == nil) {
if (*pFp == NULL) {
close(fd);
err = errno ? errno : kNuErrFileOpen;
goto bail;
@ -874,10 +863,10 @@ Nu_OpenTempFile(char* fileName, FILE** pFp)
char* result;
DBUG(("+++ Using mktemp\n"));
result = mktemp(fileName);
if (result == nil) {
result = mktemp(fileNameUNI);
if (result == NULL) {
Nu_ReportError(NU_BLOB, kNuErrNone, "mktemp failed on '%s'",
fileName);
fileNameUNI);
err = kNuErrInternal;
goto bail;
}
@ -886,34 +875,33 @@ Nu_OpenTempFile(char* fileName, FILE** pFp)
#endif
}
DBUG(("--- Opening temp file '%s'\n", fileName));
DBUG(("--- Opening temp file '%s'\n", fileNameUNI));
#if defined(HAVE_FDOPEN)
{
int fd;
fd = open(fileName, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600);
fd = open(fileNameUNI, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600);
if (fd < 0) {
err = errno ? errno : kNuErrFileOpen;
goto bail;
}
*pFp = fdopen(fd, kNuFileOpenReadWriteCreat);
if (*pFp == nil) {
if (*pFp == NULL) {
close(fd);
err = errno ? errno : kNuErrFileOpen;
goto bail;
}
}
#else
/* (not sure how portable "access" is... I think it's POSIX) */
if (access(fileName, F_OK) == 0) {
if (access(fileNameUNI, F_OK) == 0) {
err = kNuErrFileExists;
goto bail;
}
*pFp = fopen(fileName, kNuFileOpenReadWriteCreat);
if (*pFp == nil) {
*pFp = fopen(fileNameUNI, kNuFileOpenReadWriteCreat);
if (*pFp == NULL) {
err = errno ? errno : kNuErrFileOpen;
goto bail;
}
@ -928,26 +916,25 @@ bail:
* Open an archive in read-write mode, optionally creating it if it doesn't
* exist.
*/
NuError
Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
NuArchive** ppArchive)
NuError Nu_OpenRW(const UNICHAR* archivePathnameUNI,
const UNICHAR* tmpPathnameUNI, uint32_t flags, NuArchive** ppArchive)
{
NuError err;
FILE* fp = nil;
FILE* tmpFp = nil;
NuArchive* pArchive = nil;
char* tmpPathDup = nil;
FILE* fp = NULL;
FILE* tmpFp = NULL;
NuArchive* pArchive = NULL;
char* tmpPathDup = NULL;
Boolean archiveExists;
Boolean newlyCreated;
if (archivePathname == nil || !strlen(archivePathname) ||
tmpPathname == nil || !strlen(tmpPathname) || ppArchive == nil ||
(flags & ~(kNuOpenCreat|kNuOpenExcl)) != 0)
if (archivePathnameUNI == NULL || !strlen(archivePathnameUNI) ||
tmpPathnameUNI == NULL || !strlen(tmpPathnameUNI) ||
ppArchive == NULL || (flags & ~(kNuOpenCreat|kNuOpenExcl)) != 0)
{
return kNuErrInvalidArg;
}
archiveExists = (access(archivePathname, F_OK) == 0);
archiveExists = (access(archivePathnameUNI, F_OK) == 0);
/*
* Open or create archive file.
@ -955,27 +942,30 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
if (archiveExists) {
if ((flags & kNuOpenCreat) && (flags & kNuOpenExcl)) {
err = kNuErrFileExists;
Nu_ReportError(NU_BLOB, err, "File '%s' exists", archivePathname);
Nu_ReportError(NU_BLOB, err, "File '%s' exists",
archivePathnameUNI);
goto bail;
}
fp = fopen(archivePathname, kNuFileOpenReadWrite);
fp = fopen(archivePathnameUNI, kNuFileOpenReadWrite);
newlyCreated = false;
} else {
if (!(flags & kNuOpenCreat)) {
err = kNuErrFileNotFound;
Nu_ReportError(NU_BLOB, err, "File '%s' not found",archivePathname);
Nu_ReportError(NU_BLOB, err, "File '%s' not found",
archivePathnameUNI);
goto bail;
}
fp = fopen(archivePathname, kNuFileOpenReadWriteCreat);
fp = fopen(archivePathnameUNI, kNuFileOpenReadWriteCreat);
newlyCreated = true;
}
if (fp == nil) {
if (fp == NULL) {
if (errno == EACCES)
err = kNuErrFileAccessDenied;
else
err = kNuErrFileOpen;
Nu_ReportError(NU_BLOB, errno, "Unable to open '%s'", archivePathname);
Nu_ReportError(NU_BLOB, errno, "Unable to open '%s'",
archivePathnameUNI);
goto bail;
}
@ -985,7 +975,7 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
if (archiveExists && !newlyCreated) {
long length;
err = Nu_GetFileLength(nil, fp, &length);
err = Nu_GetFileLength(NULL, fp, &length);
BailError(err);
if (!length) {
@ -1003,12 +993,12 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
* So, create a temp file whether we think we need one or not. Won't
* do any harm, and might save us some troubles later.
*/
tmpPathDup = strdup(tmpPathname);
tmpPathDup = strdup(tmpPathnameUNI);
BailNil(tmpPathDup);
err = Nu_OpenTempFile(tmpPathDup, &tmpFp);
if (err != kNuErrNone) {
Nu_ReportError(NU_BLOB, err, "Failed opening temp file '%s'",
tmpPathname);
tmpPathnameUNI);
goto bail;
}
@ -1019,13 +1009,13 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
pArchive->openMode = kNuOpenRW;
pArchive->newlyCreated = newlyCreated;
pArchive->archivePathname = strdup(archivePathname);
pArchive->archivePathnameUNI = strdup(archivePathnameUNI);
pArchive->archiveFp = fp;
fp = nil;
fp = NULL;
pArchive->tmpFp = tmpFp;
tmpFp = nil;
pArchive->tmpPathname = tmpPathDup;
tmpPathDup = nil;
tmpFp = NULL;
pArchive->tmpPathnameUNI = tmpPathDup;
tmpPathDup = NULL;
if (archiveExists && !newlyCreated) {
err = Nu_ReadMasterHeader(pArchive);
@ -1036,15 +1026,15 @@ Nu_OpenRW(const char* archivePathname, const char* tmpPathname, ulong flags,
bail:
if (err != kNuErrNone) {
if (pArchive != nil) {
if (pArchive != NULL) {
(void) Nu_CloseAndFree(pArchive);
*ppArchive = nil;
*ppArchive = NULL;
}
if (fp != nil)
if (fp != NULL)
fclose(fp);
if (tmpFp != nil)
if (tmpFp != NULL)
fclose(tmpFp);
if (tmpPathDup != nil)
if (tmpPathDup != NULL)
Nu_Free(pArchive, tmpPathDup);
}
return err;
@ -1060,17 +1050,16 @@ bail:
/*
* Write the NuFX master header at the current offset.
*/
NuError
Nu_WriteMasterHeader(NuArchive* pArchive, FILE* fp,
NuError Nu_WriteMasterHeader(NuArchive* pArchive, FILE* fp,
NuMasterHeader* pHeader)
{
NuError err;
long crcOffset;
ushort crc;
uint16_t crc;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pHeader != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pHeader != NULL);
Assert(pHeader->isValid);
Assert(pHeader->mhMasterVersion == kNuOurMHVersion);
@ -1122,23 +1111,22 @@ bail:
* If it's a brand-new archive, and we didn't add anything to it, then we
* want to remove the stub archive file.
*/
static void
Nu_CloseAndFree(NuArchive* pArchive)
static void Nu_CloseAndFree(NuArchive* pArchive)
{
if (pArchive->archiveFp != nil) {
if (pArchive->archiveFp != NULL) {
DBUG(("--- Closing archive\n"));
fclose(pArchive->archiveFp);
pArchive->archiveFp = nil;
pArchive->archiveFp = NULL;
}
if (pArchive->tmpFp != nil) {
if (pArchive->tmpFp != NULL) {
DBUG(("--- Closing and removing temp file\n"));
fclose(pArchive->tmpFp);
pArchive->tmpFp = nil;
Assert(pArchive->tmpPathname != nil);
if (remove(pArchive->tmpPathname) != 0) {
pArchive->tmpFp = NULL;
Assert(pArchive->tmpPathnameUNI != NULL);
if (remove(pArchive->tmpPathnameUNI) != 0) {
Nu_ReportError(NU_BLOB, errno, "Unable to remove temp file '%s'",
pArchive->tmpPathname);
pArchive->tmpPathnameUNI);
/* keep going */
}
}
@ -1146,9 +1134,9 @@ Nu_CloseAndFree(NuArchive* pArchive)
if (pArchive->newlyCreated && Nu_RecordSet_IsEmpty(&pArchive->origRecordSet))
{
DBUG(("--- Newly-created archive unmodified; removing it\n"));
if (remove(pArchive->archivePathname) != 0) {
if (remove(pArchive->archivePathnameUNI) != 0) {
Nu_ReportError(NU_BLOB, errno, "Unable to remove archive file '%s'",
pArchive->archivePathname);
pArchive->archivePathnameUNI);
}
}
@ -1158,13 +1146,12 @@ Nu_CloseAndFree(NuArchive* pArchive)
/*
* Flush pending changes to the archive, then close it.
*/
NuError
Nu_Close(NuArchive* pArchive)
NuError Nu_Close(NuArchive* pArchive)
{
NuError err = kNuErrNone;
long flushStatus;
uint32_t flushStatus;
Assert(pArchive != nil);
Assert(pArchive != NULL);
if (!Nu_IsReadOnly(pArchive))
err = Nu_Flush(pArchive, &flushStatus);
@ -1190,29 +1177,28 @@ Nu_Close(NuArchive* pArchive)
/*
* Delete the archive file, which should already have been closed.
*/
NuError
Nu_DeleteArchiveFile(NuArchive* pArchive)
NuError Nu_DeleteArchiveFile(NuArchive* pArchive)
{
Assert(pArchive != nil);
Assert(pArchive->archiveFp == nil);
Assert(pArchive->archivePathname != nil);
Assert(pArchive != NULL);
Assert(pArchive->archiveFp == NULL);
Assert(pArchive->archivePathnameUNI != NULL);
return Nu_DeleteFile(pArchive->archivePathname);
return Nu_DeleteFile(pArchive->archivePathnameUNI);
}
/*
* Rename the temp file on top of the original archive. The temp file
* should be closed, and the archive file should be deleted.
*/
NuError
Nu_RenameTempToArchive(NuArchive* pArchive)
NuError Nu_RenameTempToArchive(NuArchive* pArchive)
{
Assert(pArchive != nil);
Assert(pArchive->archiveFp == nil);
Assert(pArchive->tmpFp == nil);
Assert(pArchive->archivePathname != nil);
Assert(pArchive->tmpPathname != nil);
Assert(pArchive != NULL);
Assert(pArchive->archiveFp == NULL);
Assert(pArchive->tmpFp == NULL);
Assert(pArchive->archivePathnameUNI != NULL);
Assert(pArchive->tmpPathnameUNI != NULL);
return Nu_RenameFile(pArchive->tmpPathname, pArchive->archivePathname);
return Nu_RenameFile(pArchive->tmpPathnameUNI,
pArchive->archivePathnameUNI);
}

View File

@ -26,45 +26,41 @@
/*
* Read one byte, optionally computing a CRC.
*/
uchar
Nu_ReadOneC(NuArchive* pArchive, FILE* fp, ushort* pCrc)
uint8_t Nu_ReadOneC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
{
int ic;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
return (uchar) ic;
return (uint8_t) ic;
}
uchar
Nu_ReadOne(NuArchive* pArchive, FILE* fp)
uint8_t Nu_ReadOne(NuArchive* pArchive, FILE* fp)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
return Nu_ReadOneC(pArchive, fp, &dummyCrc);
}
/*
* Write one byte, optionally computing a CRC.
*/
void
Nu_WriteOneC(NuArchive* pArchive, FILE* fp, uchar val, ushort* pCrc)
void Nu_WriteOneC(NuArchive* pArchive, FILE* fp, uint8_t val, uint16_t* pCrc)
{
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
putc(val, fp);
}
void
Nu_WriteOne(NuArchive* pArchive, FILE* fp, uchar val)
void Nu_WriteOne(NuArchive* pArchive, FILE* fp, uint8_t val)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
Nu_WriteOneC(pArchive, fp, val, &dummyCrc);
}
@ -72,27 +68,25 @@ Nu_WriteOne(NuArchive* pArchive, FILE* fp, uchar val)
/*
* Read two little-endian bytes, optionally computing a CRC.
*/
ushort
Nu_ReadTwoC(NuArchive* pArchive, FILE* fp, ushort* pCrc)
uint16_t Nu_ReadTwoC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
{
int ic1, ic2;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
ic1 = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic1, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic1, *pCrc);
ic2 = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic2, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic2, *pCrc);
return ic1 | ic2 << 8;
}
ushort
Nu_ReadTwo(NuArchive* pArchive, FILE* fp)
uint16_t Nu_ReadTwo(NuArchive* pArchive, FILE* fp)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
return Nu_ReadTwoC(pArchive, fp, &dummyCrc);
}
@ -100,28 +94,26 @@ Nu_ReadTwo(NuArchive* pArchive, FILE* fp)
/*
* Write two little-endian bytes, optionally computing a CRC.
*/
void
Nu_WriteTwoC(NuArchive* pArchive, FILE* fp, ushort val, ushort* pCrc)
void Nu_WriteTwoC(NuArchive* pArchive, FILE* fp, uint16_t val, uint16_t* pCrc)
{
int ic1, ic2;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
ic1 = val & 0xff;
*pCrc = Nu_UpdateCRC16((uchar)ic1, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic1, *pCrc);
ic2 = val >> 8;
*pCrc = Nu_UpdateCRC16((uchar)ic2, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic2, *pCrc);
putc(ic1, fp);
putc(ic2, fp);
}
void
Nu_WriteTwo(NuArchive* pArchive, FILE* fp, ushort val)
void Nu_WriteTwo(NuArchive* pArchive, FILE* fp, uint16_t val)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
Nu_WriteTwoC(pArchive, fp, val, &dummyCrc);
}
@ -129,31 +121,29 @@ Nu_WriteTwo(NuArchive* pArchive, FILE* fp, ushort val)
/*
* Read four little-endian bytes, optionally computing a CRC.
*/
ulong
Nu_ReadFourC(NuArchive* pArchive, FILE* fp, ushort* pCrc)
uint32_t Nu_ReadFourC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
{
int ic1, ic2, ic3, ic4;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
ic1 = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic1, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic1, *pCrc);
ic2 = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic2, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic2, *pCrc);
ic3 = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic3, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic3, *pCrc);
ic4 = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic4, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic4, *pCrc);
return ic1 | ic2 << 8 | (ulong)ic3 << 16 | (ulong)ic4 << 24;
return ic1 | ic2 << 8 | (uint32_t)ic3 << 16 | (uint32_t)ic4 << 24;
}
ulong
Nu_ReadFour(NuArchive* pArchive, FILE* fp)
uint32_t Nu_ReadFour(NuArchive* pArchive, FILE* fp)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
return Nu_ReadFourC(pArchive, fp, &dummyCrc);
}
@ -161,23 +151,22 @@ Nu_ReadFour(NuArchive* pArchive, FILE* fp)
/*
* Write four little-endian bytes, optionally computing a CRC.
*/
void
Nu_WriteFourC(NuArchive* pArchive, FILE* fp, ulong val, ushort* pCrc)
void Nu_WriteFourC(NuArchive* pArchive, FILE* fp, uint32_t val, uint16_t* pCrc)
{
int ic1, ic2, ic3, ic4;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
ic1 = val & 0xff;
*pCrc = Nu_UpdateCRC16((uchar)ic1, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic1, *pCrc);
ic2 = (val >> 8) & 0xff;
*pCrc = Nu_UpdateCRC16((uchar)ic2, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic2, *pCrc);
ic3 = (val >> 16) & 0xff;
*pCrc = Nu_UpdateCRC16((uchar)ic3, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic3, *pCrc);
ic4 = val >> 24;
*pCrc = Nu_UpdateCRC16((uchar)ic4, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic4, *pCrc);
putc(ic1, fp);
putc(ic2, fp);
@ -185,10 +174,9 @@ Nu_WriteFourC(NuArchive* pArchive, FILE* fp, ulong val, ushort* pCrc)
putc(ic4, fp);
}
void
Nu_WriteFour(NuArchive* pArchive, FILE* fp, ulong val)
void Nu_WriteFour(NuArchive* pArchive, FILE* fp, uint32_t val)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
Nu_WriteFourC(pArchive, fp, val, &dummyCrc);
}
@ -200,48 +188,46 @@ Nu_WriteFour(NuArchive* pArchive, FILE* fp, ulong val)
* and GS/ShrinkIt. It's easy enough to deal with, and I figure the less
* messing-with, the better.
*/
NuDateTime
Nu_ReadDateTimeC(NuArchive* pArchive, FILE* fp, ushort* pCrc)
NuDateTime Nu_ReadDateTimeC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
{
NuDateTime temp;
int ic;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
temp.second = ic;
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
temp.minute = ic;
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
temp.hour = ic;
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
temp.year = ic;
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
temp.day = ic;
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
temp.month = ic;
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
temp.extra = ic;
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
temp.weekDay = ic;
return temp;
}
NuDateTime
Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, ushort* pCrc)
NuDateTime Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, uint16_t* pCrc)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
return Nu_ReadDateTimeC(pArchive, fp, &dummyCrc);
}
@ -249,46 +235,44 @@ Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, ushort* pCrc)
/*
* Write an 8-byte NuFX Date/Time structure.
*/
void
Nu_WriteDateTimeC(NuArchive* pArchive, FILE* fp, NuDateTime dateTime,
ushort* pCrc)
void Nu_WriteDateTimeC(NuArchive* pArchive, FILE* fp, NuDateTime dateTime,
uint16_t* pCrc)
{
int ic;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
ic = dateTime.second;
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
putc(ic, fp);
ic = dateTime.minute;
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
putc(ic, fp);
ic = dateTime.hour;
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
putc(ic, fp);
ic = dateTime.year;
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
putc(ic, fp);
ic = dateTime.day;
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
putc(ic, fp);
ic = dateTime.month;
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
putc(ic, fp);
ic = dateTime.extra;
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
putc(ic, fp);
ic = dateTime.weekDay;
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
putc(ic, fp);
}
void
Nu_WriteDateTime(NuArchive* pArchive, FILE* fp, NuDateTime dateTime)
void Nu_WriteDateTime(NuArchive* pArchive, FILE* fp, NuDateTime dateTime)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
Nu_WriteDateTimeC(pArchive, fp, dateTime, &dummyCrc);
}
@ -296,30 +280,28 @@ Nu_WriteDateTime(NuArchive* pArchive, FILE* fp, NuDateTime dateTime)
/*
* Read N bytes from the stream, optionally computing a CRC.
*/
void
Nu_ReadBytesC(NuArchive* pArchive, FILE* fp, void* vbuffer, long count,
ushort* pCrc)
void Nu_ReadBytesC(NuArchive* pArchive, FILE* fp, void* vbuffer, long count,
uint16_t* pCrc)
{
uchar* buffer = vbuffer;
uint8_t* buffer = vbuffer;
int ic;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(buffer != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
Assert(buffer != NULL);
Assert(count > 0);
while (count--) {
ic = getc(fp);
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
*buffer++ = ic;
}
}
void
Nu_ReadBytes(NuArchive* pArchive, FILE* fp, void* vbuffer, long count)
void Nu_ReadBytes(NuArchive* pArchive, FILE* fp, void* vbuffer, long count)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
Nu_ReadBytesC(pArchive, fp, vbuffer, count, &dummyCrc);
}
@ -327,30 +309,29 @@ Nu_ReadBytes(NuArchive* pArchive, FILE* fp, void* vbuffer, long count)
/*
* Write N bytes to the stream, optionally computing a CRC.
*/
void
Nu_WriteBytesC(NuArchive* pArchive, FILE* fp, const void* vbuffer, long count,
ushort* pCrc)
void Nu_WriteBytesC(NuArchive* pArchive, FILE* fp, const void* vbuffer,
long count, uint16_t* pCrc)
{
const uchar* buffer = vbuffer;
const uint8_t* buffer = vbuffer;
int ic;
Assert(pArchive != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(buffer != nil);
Assert(pArchive != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
Assert(buffer != NULL);
Assert(count > 0);
while (count--) {
ic = *buffer++;
*pCrc = Nu_UpdateCRC16((uchar)ic, *pCrc);
*pCrc = Nu_UpdateCRC16((uint8_t)ic, *pCrc);
putc(ic, fp);
}
}
void
Nu_WriteBytes(NuArchive* pArchive, FILE* fp, const void* vbuffer, long count)
void Nu_WriteBytes(NuArchive* pArchive, FILE* fp, const void* vbuffer,
long count)
{
ushort dummyCrc CLEAN_INIT;
uint16_t dummyCrc CLEAN_INIT;
Nu_WriteBytesC(pArchive, fp, vbuffer, count, &dummyCrc);
}
@ -365,8 +346,7 @@ Nu_WriteBytes(NuArchive* pArchive, FILE* fp, const void* vbuffer, long count)
* Determine whether the stream completed the last set of operations
* successfully.
*/
NuError
Nu_HeaderIOFailed(NuArchive* pArchive, FILE* fp)
NuError Nu_HeaderIOFailed(NuArchive* pArchive, FILE* fp)
{
if (feof(fp) || ferror(fp))
return kNuErrFile;
@ -381,8 +361,7 @@ Nu_HeaderIOFailed(NuArchive* pArchive, FILE* fp)
*
* The values for "ptrname" are the same as for fseek().
*/
NuError
Nu_SeekArchive(NuArchive* pArchive, FILE* fp, long offset, int ptrname)
NuError Nu_SeekArchive(NuArchive* pArchive, FILE* fp, long offset, int ptrname)
{
if (Nu_IsStreaming(pArchive)) {
Assert(ptrname == SEEK_CUR);
@ -408,10 +387,9 @@ Nu_SeekArchive(NuArchive* pArchive, FILE* fp, long offset, int ptrname)
*
* Note that rewind(3S) resets the error indication, but this doesn't.
*/
NuError
Nu_RewindArchive(NuArchive* pArchive)
NuError Nu_RewindArchive(NuArchive* pArchive)
{
Assert(pArchive != nil);
Assert(pArchive != NULL);
Assert(!Nu_IsStreaming(pArchive));
if (Nu_SeekArchive(pArchive, pArchive->archiveFp,

View File

@ -25,13 +25,11 @@
/*
* Alloc and free functions provided to libbz2.
*/
static void*
Nu_bzalloc(void* opaque, int items, int size)
static void* Nu_bzalloc(void* opaque, int items, int size)
{
return Nu_Malloc(opaque, items * size);
}
static void
Nu_bzfree(void* opaque, void* address)
static void Nu_bzfree(void* opaque, void* address)
{
Nu_Free(opaque, address);
}
@ -46,21 +44,20 @@ Nu_bzfree(void* opaque, void* address)
/*
* Compress "srcLen" bytes from "pStraw" to "fp".
*/
NuError
Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc)
NuError Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
{
NuError err = kNuErrNone;
bz_stream bzstream;
int bzerr;
uchar* outbuf = nil;
uint8_t* outbuf = NULL;
Assert(pArchive != nil);
Assert(pStraw != nil);
Assert(fp != nil);
Assert(pArchive != NULL);
Assert(pStraw != NULL);
Assert(fp != NULL);
Assert(srcLen > 0);
Assert(pDstLen != nil);
Assert(pCrc != nil);
Assert(pDstLen != NULL);
Assert(pCrc != NULL);
err = Nu_AllocCompressionBufferIFN(pArchive);
if (err != kNuErrNone)
@ -76,7 +73,7 @@ Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
bzstream.bzalloc = Nu_bzalloc;
bzstream.bzfree = Nu_bzfree;
bzstream.opaque = pArchive;
bzstream.next_in = nil;
bzstream.next_in = NULL;
bzstream.avail_in = 0;
bzstream.next_out = outbuf;
bzstream.avail_out = kNuGenCompBufSize;
@ -98,7 +95,7 @@ Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
* Loop while we have data.
*/
do {
ulong getSize;
uint32_t getSize;
int action;
/* should be able to read a full buffer every time */
@ -139,8 +136,8 @@ Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
(bzerr == BZ_STREAM_END && bzstream.avail_out != kNuGenCompBufSize))
{
DBUG(("+++ writing %d bytes\n",
(uchar*)bzstream.next_out - outbuf));
err = Nu_FWrite(fp, outbuf, (uchar*)bzstream.next_out - outbuf);
(uint8_t*)bzstream.next_out - outbuf));
err = Nu_FWrite(fp, outbuf, (uint8_t*)bzstream.next_out - outbuf);
if (err != kNuErrNone) {
Nu_ReportError(NU_BLOB, err, "fwrite failed in bzip2");
goto bz_bail;
@ -158,8 +155,8 @@ bz_bail:
BZ2_bzCompressEnd(&bzstream); /* free up any allocated structures */
bail:
if (outbuf != nil)
free(outbuf);
if (outbuf != NULL)
Nu_Free(NULL, outbuf);
return err;
}
@ -173,20 +170,19 @@ bail:
/*
* Expand from "infp" to "pFunnel".
*/
NuError
Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
NuError Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc)
{
NuError err = kNuErrNone;
bz_stream bzstream;
int bzerr;
ulong compRemaining;
uchar* outbuf;
uint32_t compRemaining;
uint8_t* outbuf;
Assert(pArchive != nil);
Assert(pThread != nil);
Assert(infp != nil);
Assert(pFunnel != nil);
Assert(pArchive != NULL);
Assert(pThread != NULL);
Assert(infp != NULL);
Assert(pFunnel != NULL);
err = Nu_AllocCompressionBufferIFN(pArchive);
if (err != kNuErrNone)
@ -204,7 +200,7 @@ Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
bzstream.bzalloc = Nu_bzalloc;
bzstream.bzfree = Nu_bzfree;
bzstream.opaque = pArchive;
bzstream.next_in = nil;
bzstream.next_in = NULL;
bzstream.avail_in = 0;
bzstream.next_out = outbuf;
bzstream.avail_out = kNuGenCompBufSize;
@ -226,7 +222,7 @@ Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
* Loop while we have data.
*/
do {
ulong getSize;
uint32_t getSize;
/* read as much as we can */
if (bzstream.avail_in == 0) {
@ -258,17 +254,18 @@ Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
/* write every time there's anything (buffer will usually be full) */
if (bzstream.avail_out != kNuGenCompBufSize) {
DBUG(("+++ writing %d bytes\n",(uchar*)bzstream.next_out - outbuf));
DBUG(("+++ writing %d bytes\n",
(uint8_t*) bzstream.next_out - outbuf));
err = Nu_FunnelWrite(pArchive, pFunnel, outbuf,
(uchar*)bzstream.next_out - outbuf);
(uint8_t*)bzstream.next_out - outbuf);
if (err != kNuErrNone) {
Nu_ReportError(NU_BLOB, err, "write failed in bzip2");
goto bz_bail;
}
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = Nu_CalcCRC16(*pCrc, outbuf,
(uchar*) bzstream.next_out - outbuf);
(uint8_t*) bzstream.next_out - outbuf);
bzstream.next_out = outbuf;
bzstream.avail_out = kNuGenCompBufSize;
@ -291,8 +288,8 @@ bz_bail:
BZ2_bzDecompressEnd(&bzstream); /* free up any allocated structures */
bail:
if (outbuf != nil)
free(outbuf);
if (outbuf != NULL)
Nu_Free(NULL, outbuf);
return err;
}

View File

@ -1,3 +1,25 @@
2017/09/21 ***** v3.1.0 shipped *****
2016/01/11 fadden
- Fix handling of disk images (broken by previous change).
2015/12/26 fadden
- Fix handling of entries with missing threads.
- Improve handling of Mac OS X file type attributes.
2015/01/09 ***** v3.0.0 shipped *****
2015/01/03 fadden
- Mac OS X: replace Carbon FinderInfo calls with BSD xattr.
- Mac OS X: fix resource fork naming.
- Mac OS X: disable use of native resource forks.
2015/01/02 fadden
- Distinguish Unicode and Mac OS Roman strings.
2014/12/22 fadden
- Source code cleanup.
2014/10/30 ***** v2.2.2 shipped *****
2014/10/28 fadden

553
nufxlib/Charset.c Normal file
View File

@ -0,0 +1,553 @@
/*
* NuFX archive manipulation library
* Copyright (C) 2014 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING-LIB.
*
* Miscellaneous NufxLib utility functions.
*/
#include "NufxLibPriv.h"
/*
* Convert Mac OS Roman to Unicode. Mapping comes from:
*
* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT
*
* We use the "Control Pictures" block for the control characters
* (0x00-0x1f, 0x7f --> 0x2400-0x241f, 0x2421). This is a bit nicer
* than embedding control characters in filenames.
*/
static const uint16_t gMORToUnicode[256] = {
/*0x00*/ 0x2400, // [control] NULL
/*0x01*/ 0x2401, // [control] START OF HEADING
/*0x02*/ 0x2402, // [control] START OF TEXT
/*0x03*/ 0x2403, // [control] END OF TEXT
/*0x04*/ 0x2404, // [control] END OF TRANSMISSION
/*0x05*/ 0x2405, // [control] ENQUIRY
/*0x06*/ 0x2406, // [control] ACKNOWLEDGE
/*0x07*/ 0x2407, // [control] BELL
/*0x08*/ 0x2408, // [control] BACKSPACE
/*0x09*/ 0x2409, // [control] HORIZONTAL TABULATION
/*0x0a*/ 0x240a, // [control] LINE FEED
/*0x0b*/ 0x240b, // [control] VERTICAL TABULATION
/*0x0c*/ 0x240c, // [control] FORM FEED
/*0x0d*/ 0x240d, // [control] CARRIAGE RETURN
/*0x0e*/ 0x240e, // [control] SHIFT OUT
/*0x0f*/ 0x240f, // [control] SHIFT IN
/*0x10*/ 0x2410, // [control] DATA LINK ESCAPE
/*0x11*/ 0x2411, // [control] DEVICE CONTROL ONE
/*0x12*/ 0x2412, // [control] DEVICE CONTROL TWO
/*0x13*/ 0x2413, // [control] DEVICE CONTROL THREE
/*0x14*/ 0x2414, // [control] DEVICE CONTROL FOUR
/*0x15*/ 0x2415, // [control] NEGATIVE ACKNOWLEDGE
/*0x16*/ 0x2416, // [control] SYNCHRONOUS IDLE
/*0x17*/ 0x2417, // [control] END OF TRANSMISSION BLOCK
/*0x18*/ 0x2418, // [control] CANCEL
/*0x19*/ 0x2419, // [control] END OF MEDIUM
/*0x1a*/ 0x241a, // [control] SUBSTITUTE
/*0x1b*/ 0x241b, // [control] ESCAPE
/*0x1c*/ 0x241c, // [control] FILE SEPARATOR
/*0x1d*/ 0x241d, // [control] GROUP SEPARATOR
/*0x1e*/ 0x241e, // [control] RECORD SEPARATOR
/*0x1f*/ 0x241f, // [control] UNIT SEPARATOR
/*0x20*/ 0x0020, // SPACE
/*0x21*/ 0x0021, // EXCLAMATION MARK
/*0x22*/ 0x0022, // QUOTATION MARK
/*0x23*/ 0x0023, // NUMBER SIGN
/*0x24*/ 0x0024, // DOLLAR SIGN
/*0x25*/ 0x0025, // PERCENT SIGN
/*0x26*/ 0x0026, // AMPERSAND
/*0x27*/ 0x0027, // APOSTROPHE
/*0x28*/ 0x0028, // LEFT PARENTHESIS
/*0x29*/ 0x0029, // RIGHT PARENTHESIS
/*0x2A*/ 0x002A, // ASTERISK
/*0x2B*/ 0x002B, // PLUS SIGN
/*0x2C*/ 0x002C, // COMMA
/*0x2D*/ 0x002D, // HYPHEN-MINUS
/*0x2E*/ 0x002E, // FULL STOP
/*0x2F*/ 0x002F, // SOLIDUS
/*0x30*/ 0x0030, // DIGIT ZERO
/*0x31*/ 0x0031, // DIGIT ONE
/*0x32*/ 0x0032, // DIGIT TWO
/*0x33*/ 0x0033, // DIGIT THREE
/*0x34*/ 0x0034, // DIGIT FOUR
/*0x35*/ 0x0035, // DIGIT FIVE
/*0x36*/ 0x0036, // DIGIT SIX
/*0x37*/ 0x0037, // DIGIT SEVEN
/*0x38*/ 0x0038, // DIGIT EIGHT
/*0x39*/ 0x0039, // DIGIT NINE
/*0x3A*/ 0x003A, // COLON
/*0x3B*/ 0x003B, // SEMICOLON
/*0x3C*/ 0x003C, // LESS-THAN SIGN
/*0x3D*/ 0x003D, // EQUALS SIGN
/*0x3E*/ 0x003E, // GREATER-THAN SIGN
/*0x3F*/ 0x003F, // QUESTION MARK
/*0x40*/ 0x0040, // COMMERCIAL AT
/*0x41*/ 0x0041, // LATIN CAPITAL LETTER A
/*0x42*/ 0x0042, // LATIN CAPITAL LETTER B
/*0x43*/ 0x0043, // LATIN CAPITAL LETTER C
/*0x44*/ 0x0044, // LATIN CAPITAL LETTER D
/*0x45*/ 0x0045, // LATIN CAPITAL LETTER E
/*0x46*/ 0x0046, // LATIN CAPITAL LETTER F
/*0x47*/ 0x0047, // LATIN CAPITAL LETTER G
/*0x48*/ 0x0048, // LATIN CAPITAL LETTER H
/*0x49*/ 0x0049, // LATIN CAPITAL LETTER I
/*0x4A*/ 0x004A, // LATIN CAPITAL LETTER J
/*0x4B*/ 0x004B, // LATIN CAPITAL LETTER K
/*0x4C*/ 0x004C, // LATIN CAPITAL LETTER L
/*0x4D*/ 0x004D, // LATIN CAPITAL LETTER M
/*0x4E*/ 0x004E, // LATIN CAPITAL LETTER N
/*0x4F*/ 0x004F, // LATIN CAPITAL LETTER O
/*0x50*/ 0x0050, // LATIN CAPITAL LETTER P
/*0x51*/ 0x0051, // LATIN CAPITAL LETTER Q
/*0x52*/ 0x0052, // LATIN CAPITAL LETTER R
/*0x53*/ 0x0053, // LATIN CAPITAL LETTER S
/*0x54*/ 0x0054, // LATIN CAPITAL LETTER T
/*0x55*/ 0x0055, // LATIN CAPITAL LETTER U
/*0x56*/ 0x0056, // LATIN CAPITAL LETTER V
/*0x57*/ 0x0057, // LATIN CAPITAL LETTER W
/*0x58*/ 0x0058, // LATIN CAPITAL LETTER X
/*0x59*/ 0x0059, // LATIN CAPITAL LETTER Y
/*0x5A*/ 0x005A, // LATIN CAPITAL LETTER Z
/*0x5B*/ 0x005B, // LEFT SQUARE BRACKET
/*0x5C*/ 0x005C, // REVERSE SOLIDUS
/*0x5D*/ 0x005D, // RIGHT SQUARE BRACKET
/*0x5E*/ 0x005E, // CIRCUMFLEX ACCENT
/*0x5F*/ 0x005F, // LOW LINE
/*0x60*/ 0x0060, // GRAVE ACCENT
/*0x61*/ 0x0061, // LATIN SMALL LETTER A
/*0x62*/ 0x0062, // LATIN SMALL LETTER B
/*0x63*/ 0x0063, // LATIN SMALL LETTER C
/*0x64*/ 0x0064, // LATIN SMALL LETTER D
/*0x65*/ 0x0065, // LATIN SMALL LETTER E
/*0x66*/ 0x0066, // LATIN SMALL LETTER F
/*0x67*/ 0x0067, // LATIN SMALL LETTER G
/*0x68*/ 0x0068, // LATIN SMALL LETTER H
/*0x69*/ 0x0069, // LATIN SMALL LETTER I
/*0x6A*/ 0x006A, // LATIN SMALL LETTER J
/*0x6B*/ 0x006B, // LATIN SMALL LETTER K
/*0x6C*/ 0x006C, // LATIN SMALL LETTER L
/*0x6D*/ 0x006D, // LATIN SMALL LETTER M
/*0x6E*/ 0x006E, // LATIN SMALL LETTER N
/*0x6F*/ 0x006F, // LATIN SMALL LETTER O
/*0x70*/ 0x0070, // LATIN SMALL LETTER P
/*0x71*/ 0x0071, // LATIN SMALL LETTER Q
/*0x72*/ 0x0072, // LATIN SMALL LETTER R
/*0x73*/ 0x0073, // LATIN SMALL LETTER S
/*0x74*/ 0x0074, // LATIN SMALL LETTER T
/*0x75*/ 0x0075, // LATIN SMALL LETTER U
/*0x76*/ 0x0076, // LATIN SMALL LETTER V
/*0x77*/ 0x0077, // LATIN SMALL LETTER W
/*0x78*/ 0x0078, // LATIN SMALL LETTER X
/*0x79*/ 0x0079, // LATIN SMALL LETTER Y
/*0x7A*/ 0x007A, // LATIN SMALL LETTER Z
/*0x7B*/ 0x007B, // LEFT CURLY BRACKET
/*0x7C*/ 0x007C, // VERTICAL LINE
/*0x7D*/ 0x007D, // RIGHT CURLY BRACKET
/*0x7E*/ 0x007E, // TILDE
/*0x7f*/ 0x2421, // [control] DELETE
/*0x80*/ 0x00C4, // LATIN CAPITAL LETTER A WITH DIAERESIS
/*0x81*/ 0x00C5, // LATIN CAPITAL LETTER A WITH RING ABOVE
/*0x82*/ 0x00C7, // LATIN CAPITAL LETTER C WITH CEDILLA
/*0x83*/ 0x00C9, // LATIN CAPITAL LETTER E WITH ACUTE
/*0x84*/ 0x00D1, // LATIN CAPITAL LETTER N WITH TILDE
/*0x85*/ 0x00D6, // LATIN CAPITAL LETTER O WITH DIAERESIS
/*0x86*/ 0x00DC, // LATIN CAPITAL LETTER U WITH DIAERESIS
/*0x87*/ 0x00E1, // LATIN SMALL LETTER A WITH ACUTE
/*0x88*/ 0x00E0, // LATIN SMALL LETTER A WITH GRAVE
/*0x89*/ 0x00E2, // LATIN SMALL LETTER A WITH CIRCUMFLEX
/*0x8A*/ 0x00E4, // LATIN SMALL LETTER A WITH DIAERESIS
/*0x8B*/ 0x00E3, // LATIN SMALL LETTER A WITH TILDE
/*0x8C*/ 0x00E5, // LATIN SMALL LETTER A WITH RING ABOVE
/*0x8D*/ 0x00E7, // LATIN SMALL LETTER C WITH CEDILLA
/*0x8E*/ 0x00E9, // LATIN SMALL LETTER E WITH ACUTE
/*0x8F*/ 0x00E8, // LATIN SMALL LETTER E WITH GRAVE
/*0x90*/ 0x00EA, // LATIN SMALL LETTER E WITH CIRCUMFLEX
/*0x91*/ 0x00EB, // LATIN SMALL LETTER E WITH DIAERESIS
/*0x92*/ 0x00ED, // LATIN SMALL LETTER I WITH ACUTE
/*0x93*/ 0x00EC, // LATIN SMALL LETTER I WITH GRAVE
/*0x94*/ 0x00EE, // LATIN SMALL LETTER I WITH CIRCUMFLEX
/*0x95*/ 0x00EF, // LATIN SMALL LETTER I WITH DIAERESIS
/*0x96*/ 0x00F1, // LATIN SMALL LETTER N WITH TILDE
/*0x97*/ 0x00F3, // LATIN SMALL LETTER O WITH ACUTE
/*0x98*/ 0x00F2, // LATIN SMALL LETTER O WITH GRAVE
/*0x99*/ 0x00F4, // LATIN SMALL LETTER O WITH CIRCUMFLEX
/*0x9A*/ 0x00F6, // LATIN SMALL LETTER O WITH DIAERESIS
/*0x9B*/ 0x00F5, // LATIN SMALL LETTER O WITH TILDE
/*0x9C*/ 0x00FA, // LATIN SMALL LETTER U WITH ACUTE
/*0x9D*/ 0x00F9, // LATIN SMALL LETTER U WITH GRAVE
/*0x9E*/ 0x00FB, // LATIN SMALL LETTER U WITH CIRCUMFLEX
/*0x9F*/ 0x00FC, // LATIN SMALL LETTER U WITH DIAERESIS
/*0xA0*/ 0x2020, // DAGGER
/*0xA1*/ 0x00B0, // DEGREE SIGN
/*0xA2*/ 0x00A2, // CENT SIGN
/*0xA3*/ 0x00A3, // POUND SIGN
/*0xA4*/ 0x00A7, // SECTION SIGN
/*0xA5*/ 0x2022, // BULLET
/*0xA6*/ 0x00B6, // PILCROW SIGN
/*0xA7*/ 0x00DF, // LATIN SMALL LETTER SHARP S
/*0xA8*/ 0x00AE, // REGISTERED SIGN
/*0xA9*/ 0x00A9, // COPYRIGHT SIGN
/*0xAA*/ 0x2122, // TRADE MARK SIGN
/*0xAB*/ 0x00B4, // ACUTE ACCENT
/*0xAC*/ 0x00A8, // DIAERESIS
/*0xAD*/ 0x2260, // NOT EQUAL TO
/*0xAE*/ 0x00C6, // LATIN CAPITAL LETTER AE
/*0xAF*/ 0x00D8, // LATIN CAPITAL LETTER O WITH STROKE
/*0xB0*/ 0x221E, // INFINITY
/*0xB1*/ 0x00B1, // PLUS-MINUS SIGN
/*0xB2*/ 0x2264, // LESS-THAN OR EQUAL TO
/*0xB3*/ 0x2265, // GREATER-THAN OR EQUAL TO
/*0xB4*/ 0x00A5, // YEN SIGN
/*0xB5*/ 0x00B5, // MICRO SIGN
/*0xB6*/ 0x2202, // PARTIAL DIFFERENTIAL
/*0xB7*/ 0x2211, // N-ARY SUMMATION
/*0xB8*/ 0x220F, // N-ARY PRODUCT
/*0xB9*/ 0x03C0, // GREEK SMALL LETTER PI
/*0xBA*/ 0x222B, // INTEGRAL
/*0xBB*/ 0x00AA, // FEMININE ORDINAL INDICATOR
/*0xBC*/ 0x00BA, // MASCULINE ORDINAL INDICATOR
/*0xBD*/ 0x03A9, // GREEK CAPITAL LETTER OMEGA
/*0xBE*/ 0x00E6, // LATIN SMALL LETTER AE
/*0xBF*/ 0x00F8, // LATIN SMALL LETTER O WITH STROKE
/*0xC0*/ 0x00BF, // INVERTED QUESTION MARK
/*0xC1*/ 0x00A1, // INVERTED EXCLAMATION MARK
/*0xC2*/ 0x00AC, // NOT SIGN
/*0xC3*/ 0x221A, // SQUARE ROOT
/*0xC4*/ 0x0192, // LATIN SMALL LETTER F WITH HOOK
/*0xC5*/ 0x2248, // ALMOST EQUAL TO
/*0xC6*/ 0x2206, // INCREMENT
/*0xC7*/ 0x00AB, // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
/*0xC8*/ 0x00BB, // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
/*0xC9*/ 0x2026, // HORIZONTAL ELLIPSIS
/*0xCA*/ 0x00A0, // NO-BREAK SPACE
/*0xCB*/ 0x00C0, // LATIN CAPITAL LETTER A WITH GRAVE
/*0xCC*/ 0x00C3, // LATIN CAPITAL LETTER A WITH TILDE
/*0xCD*/ 0x00D5, // LATIN CAPITAL LETTER O WITH TILDE
/*0xCE*/ 0x0152, // LATIN CAPITAL LIGATURE OE
/*0xCF*/ 0x0153, // LATIN SMALL LIGATURE OE
/*0xD0*/ 0x2013, // EN DASH
/*0xD1*/ 0x2014, // EM DASH
/*0xD2*/ 0x201C, // LEFT DOUBLE QUOTATION MARK
/*0xD3*/ 0x201D, // RIGHT DOUBLE QUOTATION MARK
/*0xD4*/ 0x2018, // LEFT SINGLE QUOTATION MARK
/*0xD5*/ 0x2019, // RIGHT SINGLE QUOTATION MARK
/*0xD6*/ 0x00F7, // DIVISION SIGN
/*0xD7*/ 0x25CA, // LOZENGE
/*0xD8*/ 0x00FF, // LATIN SMALL LETTER Y WITH DIAERESIS
/*0xD9*/ 0x0178, // LATIN CAPITAL LETTER Y WITH DIAERESIS
/*0xDA*/ 0x2044, // FRACTION SLASH
/*0xDB*/ 0x00A4, // CURRENCY SIGN (was EURO SIGN)
/*0xDC*/ 0x2039, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
/*0xDD*/ 0x203A, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
/*0xDE*/ 0xFB01, // LATIN SMALL LIGATURE FI
/*0xDF*/ 0xFB02, // LATIN SMALL LIGATURE FL
/*0xE0*/ 0x2021, // DOUBLE DAGGER
/*0xE1*/ 0x00B7, // MIDDLE DOT
/*0xE2*/ 0x201A, // SINGLE LOW-9 QUOTATION MARK
/*0xE3*/ 0x201E, // DOUBLE LOW-9 QUOTATION MARK
/*0xE4*/ 0x2030, // PER MILLE SIGN
/*0xE5*/ 0x00C2, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
/*0xE6*/ 0x00CA, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
/*0xE7*/ 0x00C1, // LATIN CAPITAL LETTER A WITH ACUTE
/*0xE8*/ 0x00CB, // LATIN CAPITAL LETTER E WITH DIAERESIS
/*0xE9*/ 0x00C8, // LATIN CAPITAL LETTER E WITH GRAVE
/*0xEA*/ 0x00CD, // LATIN CAPITAL LETTER I WITH ACUTE
/*0xEB*/ 0x00CE, // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
/*0xEC*/ 0x00CF, // LATIN CAPITAL LETTER I WITH DIAERESIS
/*0xED*/ 0x00CC, // LATIN CAPITAL LETTER I WITH GRAVE
/*0xEE*/ 0x00D3, // LATIN CAPITAL LETTER O WITH ACUTE
/*0xEF*/ 0x00D4, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
/*0xF0*/ 0xF8FF, // Apple logo
/*0xF1*/ 0x00D2, // LATIN CAPITAL LETTER O WITH GRAVE
/*0xF2*/ 0x00DA, // LATIN CAPITAL LETTER U WITH ACUTE
/*0xF3*/ 0x00DB, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
/*0xF4*/ 0x00D9, // LATIN CAPITAL LETTER U WITH GRAVE
/*0xF5*/ 0x0131, // LATIN SMALL LETTER DOTLESS I
/*0xF6*/ 0x02C6, // MODIFIER LETTER CIRCUMFLEX ACCENT
/*0xF7*/ 0x02DC, // SMALL TILDE
/*0xF8*/ 0x00AF, // MACRON
/*0xF9*/ 0x02D8, // BREVE
/*0xFA*/ 0x02D9, // DOT ABOVE
/*0xFB*/ 0x02DA, // RING ABOVE
/*0xFC*/ 0x00B8, // CEDILLA
/*0xFD*/ 0x02DD, // DOUBLE ACUTE ACCENT
/*0xFE*/ 0x02DB, // OGONEK
/*0xFF*/ 0x02C7 // CARON
};
/*
* Static table, populated on first use. Provides the inverse map.
*
* An entry with 0x00 indicates no conversion. That's incorrect for
* the entry for '\0', but since we're operating on null-terminated
* strings that's never valid anyway. (It's possible for a filename
* to contain 0x2400, but that would translate to 0x00, which we don't
* allow; so it makes more sense to treat it as illegal.)
*/
static uint8_t gUnicodeToMOR[65536] = { 0xff /*indicates not initialized*/ };
static void Nu_GenerateUnicodeToMOR(void)
{
memset(gUnicodeToMOR, 0, sizeof(gUnicodeToMOR));
int i;
for (i = 0; i < 256; i++) {
int codePoint = gMORToUnicode[i];
Assert(codePoint >= 0 && codePoint < 65536);
gUnicodeToMOR[codePoint] = i;
}
}
/*
* Converts stringMOR to Unicode, storing the output in bufUNI until it's
* full. Null termination is guaranteed. If the buffer size is zero or
* bufUNI is NULL, no string data is returned.
*
* Returns the number of bytes required to represent stringMOR in Unicode.
*/
size_t Nu_ConvertMORToUNI(const char* stringMOR, UNICHAR* bufUNI,
size_t bufSize)
{
Assert(stringMOR != 0);
#ifdef _WIN32
/* place-holder if we're not using UTF-16 yet */
Assert(sizeof(UNICHAR) == 1);
size_t morLen = strlen(stringMOR) + 1;
if (bufUNI != NULL && bufSize != 0) {
size_t copyLen = morLen < bufSize ? morLen : bufSize;
memcpy(bufUNI, stringMOR, copyLen);
bufUNI[bufSize-1] = '\0';
}
return morLen;
#else
/*
* Convert Mac OS Roman to UTF-8. We only output full code points,
* so if only the first byte of a UTF-8 sequence will fit we just
* stop early.
*/
size_t uniLen = 0;
Boolean doOutput = (bufUNI != NULL);
while (*stringMOR != '\0') {
// ASCII values just "convert" to themselves in this table
uint16_t us = gMORToUnicode[(uint8_t)*stringMOR];
if (us < 0x80) {
// single byte, no conversion
if (uniLen+1 >= bufSize) {
doOutput = false;
}
if (doOutput) {
bufUNI[uniLen] = (char) us;
}
uniLen++;
} else if (us < 0x7ff) {
// two bytes
if (uniLen+2 >= bufSize) {
doOutput = false;
}
if (doOutput) {
bufUNI[uniLen] = (us >> 6) | 0xc0;
bufUNI[uniLen+1] = (us & 0x3f) | 0x80;
}
uniLen += 2;
} else {
// three bytes
if (uniLen+3 >= bufSize) {
doOutput = false;
}
if (doOutput) {
bufUNI[uniLen] = (us >> 12) | 0xe0;
bufUNI[uniLen+1] = ((us >> 6) & 0x3f) | 0x80;
bufUNI[uniLen+2] = (us & 0x3f) | 0x80;
}
uniLen += 3;
}
stringMOR++;
}
// null-terminate
if (doOutput && uniLen < bufSize) {
bufUNI[uniLen] = '\0';
}
uniLen++;
return uniLen;
#endif
}
/*
* Decode a single Unicode code point from a UTF-8 string. This will
* consume 1 to 4 bytes. If an error is detected, only one byte is
* consumed, and the code point value will be 0xDCnn (invalid).
*
* cf. http://en.wikipedia.org/wiki/UTF-8#Sample_code
*/
static uint32_t Nu_DecodeUTF8(const char** pStr)
{
const uint8_t* str = (const uint8_t*) *pStr;
uint32_t codePoint;
uint32_t uc1, uc2, uc3, uc4;
uc1 = *str++;
if (uc1 < 0x80) {
// single byte
codePoint = uc1;
} else if (uc1 < 0xc2) {
// illegal: continuation or overlong 2-byte sequence
goto fail;
} else if (uc1 < 0xe0) {
// 2-byte sequence
uc2 = *str++;
if ((uc2 & 0xc0) != 0x80) {
goto fail; // not a continuation
}
codePoint = (uc1 << 6) + uc2 - 0x3080;
} else if (uc1 < 0xf0) {
// 3-byte sequence */
uc2 = *str++;
if ((uc2 & 0xc0) != 0x80) {
goto fail; // not a continuation
}
if (uc1 == 0xe0 && uc2 < 0xa0) {
goto fail; // overlong
}
uc3 = *str++;
if ((uc3 & 0xc0) != 0x80) {
goto fail; // not a continuation
}
codePoint = (uc1 << 12) + (uc2 << 6) + uc3 - 0xE2080;
} else if (uc1 < 0xf5) {
uc2 = *str++;
if ((uc2 & 0xc0) != 0x80) {
goto fail; // not a continuation
}
if (uc1 == 0xf0 && uc2 < 0x90) {
goto fail; // overlong
}
if (uc1 == 0xf4 && uc2 >= 0x90) {
goto fail; // U+10FFFF
}
uc3 = *str++;
if ((uc3 & 0xc0) != 0x80) {
goto fail; // not a continuation
}
uc4 = *str++;
if ((uc4 & 0xc0) != 0x80) {
goto fail; // not a continuation
}
codePoint = (uc1 << 18) + (uc2 << 12) + (uc3 << 6) + uc4 - 0x3C82080;
} else {
// illegal: > U+10FFFF
goto fail;
}
*pStr = (const UNICHAR*) str;
return codePoint;
fail:
(*pStr)++; // advance one char only
return 0xdc00 | uc1;
}
/*
* Converts stringUNI to Mac OS Roman, storing the output in bufMOR
* until it's full. Null termination is guaranteed. If the buffer
* size is zero or bufMOR is NULL, no string data is returned.
*
* Returns the number of bytes required to represent stringUNI in MOR.
*/
size_t Nu_ConvertUNIToMOR(const UNICHAR* stringUNI, char* bufMOR,
size_t bufSize)
{
Assert(stringUNI != 0);
#ifdef _WIN32
/*
* Place-holder if we're not using UTF-16 yet. This doesn't pass
* tests that check for behavior with non-MOR Unicode values.
*/
Assert(sizeof(UNICHAR) == 1);
size_t uniLen = strlen(stringUNI) + 1;
if (bufMOR != NULL && bufSize != 0) {
size_t copyLen = uniLen < bufSize ? uniLen : bufSize;
memcpy(bufMOR, stringUNI, copyLen);
bufMOR[bufSize-1] = '\0';
}
return uniLen;
#else
/*
* Convert UTF-8 to Mac OS Roman. If the code point doesn't have
* a valid conversion (either because it's not in the table, or the
* UTF-8 code is damaged) we just insert an ASCII '?'.
*/
if (gUnicodeToMOR[0] == 0xff) {
Nu_GenerateUnicodeToMOR();
Assert(gUnicodeToMOR[0] != 0xff);
}
uint32_t codePoint;
size_t morLen = 0;
Boolean doOutput = (bufMOR != NULL);
while (*stringUNI != '\0') {
codePoint = Nu_DecodeUTF8(&stringUNI);
char mc;
if (codePoint < 0x80) {
mc = (char) codePoint;
} else if (codePoint < 0xffff) {
// UTF-8 errors come back as 0xDCnn, which has no mapping in table
mc = gUnicodeToMOR[codePoint];
if (mc == 0x00) {
mc = '?';
}
} else {
// non-BMP code point
mc = '?';
}
if (morLen+1 >= bufSize) {
doOutput = false;
}
if (doOutput) {
bufMOR[morLen] = mc;
}
morLen++;
}
// null-terminate
if (doOutput && morLen < bufSize) {
bufMOR[morLen] = '\0';
}
morLen++;
return morLen;
#endif
}
/*
* Utility function that wraps NuConvertMORToUTF8, allocating a new
* buffer to hold the converted string. The caller must free the result.
*
* Returns NULL if stringMOR is NULL or the conversion fails.
*/
UNICHAR* Nu_CopyMORToUNI(const char* stringMOR)
{
size_t uniLen;
UNICHAR* uniBuf;
if (stringMOR == NULL) {
return NULL;
}
uniLen = Nu_ConvertMORToUNI(stringMOR, NULL, 0);
if (uniLen == (size_t) -1) {
return NULL;
}
uniBuf = (UNICHAR*) Nu_Malloc(NULL, uniLen);
Nu_ConvertMORToUNI(stringMOR, uniBuf, uniLen);
return uniBuf;
}

View File

@ -15,17 +15,16 @@
/*
* "Compress" an uncompressed thread.
*/
static NuError
Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
FILE* fp, ulong srcLen, ulong* pDstLen, ushort *pCrc)
static NuError Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
FILE* fp, uint32_t srcLen, uint32_t* pDstLen, uint16_t *pCrc)
{
NuError err = kNuErrNone;
/*uchar* buffer = nil;*/
ulong count, getsize;
/*uint8_t* buffer = NULL;*/
uint32_t count, getsize;
Assert(pArchive != nil);
Assert(pStraw != nil);
Assert(fp != nil);
Assert(pArchive != NULL);
Assert(pStraw != NULL);
Assert(fp != NULL);
Assert(srcLen > 0);
*pDstLen = srcLen; /* get this over with */
@ -33,7 +32,7 @@ Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
err = Nu_AllocCompressionBufferIFN(pArchive);
BailError(err);
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = kNuInitialThreadCRC;
count = srcLen;
@ -42,7 +41,7 @@ Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
err = Nu_StrawRead(pArchive, pStraw, pArchive->compBuf, getsize);
BailError(err);
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = Nu_CalcCRC16(*pCrc, pArchive->compBuf, getsize);
err = Nu_FWrite(fp, pArchive->compBuf, getsize);
BailError(err);
@ -87,24 +86,23 @@ bail:
* On exit, the output file will be positioned after the last byte of the
* output. (For a pre-sized buffer, this may not be the desired result.)
*/
NuError
Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
NuError Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
NuThreadID threadID, NuThreadFormat sourceFormat,
NuThreadFormat targetFormat, NuProgressData* pProgressData, FILE* dstFp,
NuThread* pThread)
{
NuError err;
long origOffset;
NuStraw* pStraw = nil;
NuDataSink* pDataSink = nil;
ulong srcLen = 0, dstLen = 0;
ushort threadCrc;
NuStraw* pStraw = NULL;
NuDataSink* pDataSink = NULL;
uint32_t srcLen = 0, dstLen = 0;
uint16_t threadCrc;
Assert(pArchive != nil);
Assert(pDataSource != nil);
/* okay if pProgressData is nil */
Assert(dstFp != nil);
Assert(pThread != nil);
Assert(pArchive != NULL);
Assert(pDataSource != NULL);
/* okay if pProgressData is NULL */
Assert(dstFp != NULL);
Assert(pThread != NULL);
/* remember file offset, so we can back up if compression fails */
err = Nu_FTell(dstFp, &origOffset);
@ -116,7 +114,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
pThread->thThreadClass = NuThreadIDGetClass(threadID);
pThread->thThreadKind = NuThreadIDGetKind(threadID);
pThread->actualThreadEOF = (ulong)-1;
pThread->actualThreadEOF = (uint32_t)-1;
/* nuThreadIdx and fileOffset should already be set */
/*
@ -168,7 +166,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
if (pArchive->valMimicSHK && srcLen < kNuSHKLZWThreshold)
targetFormat = kNuThreadFormatUncompressed;
if (pProgressData != nil) {
if (pProgressData != NULL) {
if (targetFormat != kNuThreadFormatUncompressed)
Nu_StrawSetProgressState(pStraw, kNuProgressCompressing);
else
@ -245,7 +243,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
BailError(err);
err = Nu_StrawRewind(pArchive, pStraw);
BailError(err);
if (pProgressData != nil)
if (pProgressData != NULL)
Nu_StrawSetProgressState(pStraw, kNuProgressStoring);
err = Nu_ProgressDataCompressPrep(pArchive, pStraw,
kNuThreadFormatUncompressed, srcLen);
@ -262,7 +260,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
* computed a CRC on the entire file (i.e. didn't stop early
* when it noticed the output was larger than the input). If
* this is always the case, then we can change "&threadCrc"
* a few lines back to "nil" and avoid re-computing the CRC.
* a few lines back to "NULL" and avoid re-computing the CRC.
* If this is not always the case, remove this assert.
*/
Assert(threadCrc == pThread->thThreadCRC);
@ -276,14 +274,14 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
/*
* Copy the already-compressed input.
*/
if (pProgressData != nil)
if (pProgressData != NULL)
Nu_StrawSetProgressState(pStraw, kNuProgressCopying);
err = Nu_ProgressDataCompressPrep(pArchive, pStraw,
kNuThreadFormatUncompressed, srcLen);
BailError(err);
err = Nu_CompressUncompressed(pArchive, pStraw, dstFp, srcLen,
&dstLen, nil);
&dstLen, NULL);
BailError(err);
pThread->thThreadEOF = Nu_DataSourceGetOtherLen(pDataSource);
@ -298,7 +296,7 @@ done:
srcLen, dstLen, pThread->actualThreadEOF));
/* make sure we send a final "success" progress message at 100% */
if (pProgressData != nil) {
if (pProgressData != NULL) {
(void) Nu_StrawSetProgressState(pStraw, kNuProgressDone);
err = Nu_StrawSendProgressUpdate(pArchive, pStraw);
BailError(err);
@ -322,14 +320,13 @@ bail:
* will copy the data, and then continue writing zeros to fill out the rest
* of the pre-sized buffer.
*/
NuError
Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
NuError Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
NuThreadID threadID, FILE* dstFp, NuThread* pThread, char** ppSavedCopy)
{
NuError err = kNuErrNone;
NuStraw* pStraw = nil;
ulong srcLen, bufferLen;
ulong count, getsize;
NuStraw* pStraw = NULL;
uint32_t srcLen, bufferLen;
uint32_t count, getsize;
srcLen = Nu_DataSourceGetDataLen(pDataSource);
bufferLen = Nu_DataSourceGetOtherLen(pDataSource);
@ -355,7 +352,7 @@ Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
* is a convenient way to deal with the dataSource, even though we
* don't have a progress updater.
*/
err = Nu_StrawNew(pArchive, pDataSource, nil, &pStraw);
err = Nu_StrawNew(pArchive, pDataSource, NULL, &pStraw);
BailError(err);
count = srcLen;
@ -370,7 +367,7 @@ Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
err = Nu_FWrite(dstFp, pArchive->compBuf, getsize);
BailError(err);
if (ppSavedCopy != nil && *ppSavedCopy == nil) {
if (ppSavedCopy != NULL && *ppSavedCopy == NULL) {
/*
* Grab a copy of the filename for our own use. This assumes
* that the filename fits in kNuGenCompBufSize, which is a

View File

@ -7,7 +7,6 @@
* Compute 16-bit CRCs. Depending on the hardware, the table version
* might be slower than the loop computation.
*/
#define __Crc16_c__ 1
#include "NufxLibPriv.h"
#define CRC_TAB
@ -30,7 +29,7 @@
/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
const ushort gNuCrc16Table[256] = {
const uint16_t gNuCrc16Table[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
@ -83,13 +82,11 @@ const ushort gNuCrc16Table[256] = {
* Depending on CPU architecture, one may be dramatically faster than
* the other.
*/
ushort
Nu_CalcCRC16(ushort seed, const uchar* ptr, int count)
uint16_t Nu_CalcCRC16(uint16_t seed, const uint8_t* ptr, int count)
{
ushort CRC = seed;
uint16_t CRC = seed;
#ifndef CRC_TAB
int x;
Assert(sizeof(ushort) == 2); /* I think this is assumed */
#endif
do {

View File

@ -65,8 +65,7 @@ static const char* gFileSysIDs[] = {
*
* Returns "buffer" for the benefit of printf() calls.
*/
static char*
Nu_DebugDumpDate(const NuDateTime* pDateTime, char* buffer)
static char* Nu_DebugDumpDate(const NuDateTime* pDateTime, char* buffer)
{
char* cp;
@ -118,8 +117,7 @@ bail:
*
* The result will be 2x the size of the original, +1 for a null byte.
*/
static void
ConvertToHexStr(const uchar* inBuf, int inLen, char* outBuf)
static void ConvertToHexStr(const uint8_t* inBuf, int inLen, char* outBuf)
{
while (inLen--) {
*outBuf++ = HexConv((*inBuf >> 4) & 0x0f);
@ -133,14 +131,13 @@ ConvertToHexStr(const uchar* inBuf, int inLen, char* outBuf)
/*
* Dump everything we know about pThread.
*/
void
Nu_DebugDumpThread(const NuThread* pThread)
void Nu_DebugDumpThread(const NuThread* pThread)
{
static const char* kInd = " ";
NuThreadID threadID;
const char* descr;
Assert(pThread != nil);
Assert(pThread != NULL);
printf("%sThreadClass: 0x%04x (%s)\n", kInd,
pThread->thThreadClass,
@ -164,9 +161,9 @@ Nu_DebugDumpThread(const NuThread* pThread)
printf("%sThreadKind: 0x%04x (%s)\n", kInd,
pThread->thThreadKind, descr);
printf("%sThreadCRC: 0x%04x ThreadEOF: %lu CompThreadEOF: %lu\n", kInd,
printf("%sThreadCRC: 0x%04x ThreadEOF: %u CompThreadEOF: %u\n", kInd,
pThread->thThreadCRC, pThread->thThreadEOF, pThread->thCompThreadEOF);
printf("%s*File data offset: %ld actualThreadEOF: %ld\n", kInd,
printf("%s*File data offset: %ld actualThreadEOF: %d\n", kInd,
pThread->fileOffset, pThread->actualThreadEOF);
}
@ -177,8 +174,7 @@ Nu_DebugDumpThread(const NuThread* pThread)
* set. Pass in the "orig" copy in "pRecord", and optionally pass in the
* "copy" set in "pXrefRecord" to glean data from both.
*/
static void
Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
static void Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
const NuRecord* pXrefRecord, Boolean isDeleted)
{
NuError err; /* dummy */
@ -186,22 +182,24 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
char dateBuf[kNuDateOutputLen];
const NuThreadMod* pThreadMod;
const NuThread* pThread;
ulong idx;
uint32_t idx;
Assert(pRecord != nil);
Assert(pRecord != NULL);
/*printf("PTR: pRecord=0x%08lx pXrefRecord=0x%08lx\n", (long) pRecord,
(long) pXrefRecord);*/
printf("%s%s%sFilename: '%s' (idx=%lu)\n", kInd,
UNICHAR* filenameUNI = Nu_CopyMORToUNI(pRecord->filenameMOR);
printf("%s%s%sFilename: '%s' (idx=%u)\n", kInd,
isDeleted ? "[DEL] " : "",
pXrefRecord != nil && pXrefRecord->pThreadMods != nil ? "[MOD] " : "",
pRecord->filename == nil ? "<not specified>" : pRecord->filename,
pXrefRecord != NULL && pXrefRecord->pThreadMods != NULL ? "[MOD] " : "",
filenameUNI == NULL ? "<not specified>" : filenameUNI,
pRecord->recordIdx);
free(filenameUNI);
printf("%sHeaderID: '%.4s' VersionNumber: 0x%04x HeaderCRC: 0x%04x\n",
kInd,
pRecord->recNufxID, pRecord->recVersionNumber, pRecord->recHeaderCRC);
printf("%sAttribCount: %u TotalThreads: %lu\n", kInd,
printf("%sAttribCount: %u TotalThreads: %u\n", kInd,
pRecord->recAttribCount, pRecord->recTotalThreads);
printf("%sFileSysID: %u (%s) FileSysInfo: 0x%04x ('%c')\n", kInd,
pRecord->recFileSysID,
@ -209,7 +207,7 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
pRecord->recFileSysInfo,
NuGetSepFromSysInfo(pRecord->recFileSysInfo));
/* do something fancy for ProDOS? */
printf("%sFileType: 0x%08lx ExtraType: 0x%08lx Access: 0x%08lx\n", kInd,
printf("%sFileType: 0x%08x ExtraType: 0x%08x Access: 0x%08x\n", kInd,
pRecord->recFileType, pRecord->recExtraType, pRecord->recAccess);
printf("%sCreateWhen: %s\n", kInd,
Nu_DebugDumpDate(&pRecord->recCreateWhen, dateBuf));
@ -223,13 +221,13 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
if (pRecord->recOptionSize) {
char* outBuf = Nu_Malloc(pArchive, pRecord->recOptionSize * 2 +1);
BailAlloc(outBuf);
Assert(pRecord->recOptionList != nil);
Assert(pRecord->recOptionList != NULL);
ConvertToHexStr(pRecord->recOptionList, pRecord->recOptionSize, outBuf);
printf("%sOptionList: [%s]\n", kInd, outBuf);
Nu_Free(pArchive, outBuf);
}
printf("%s*ExtraCount: %ld RecFileOffset: %ld RecHeaderLength: %ld\n",
printf("%s*ExtraCount: %d RecFileOffset: %ld RecHeaderLength: %d\n",
kInd,
pRecord->extraCount, pRecord->fileOffset, pRecord->recHeaderLength);
@ -238,34 +236,34 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
isFake = (idx >= pRecord->recTotalThreads - pRecord->fakeThreads);
pThread = Nu_GetThread(pRecord, idx);
Assert(pThread != nil);
Assert(pThread != NULL);
printf("%s--Thread #%lu (idx=%lu)%s\n", kInd, idx, pThread->threadIdx,
printf("%s--Thread #%u (idx=%u)%s\n", kInd, idx, pThread->threadIdx,
isFake ? " [FAKE]" : "");
Nu_DebugDumpThread(pThread);
}
if (pXrefRecord != nil)
if (pXrefRecord != NULL)
pThreadMod = pXrefRecord->pThreadMods;
else
pThreadMod = pRecord->pThreadMods; /* probably empty */
if (pThreadMod != nil)
if (pThreadMod != NULL)
printf("%s*ThreadMods -----\n", kInd);
while (pThreadMod != nil) {
while (pThreadMod != NULL) {
switch (pThreadMod->entry.kind) {
case kNuThreadModAdd:
printf("%s *-ThreadMod ADD 0x%08lx 0x%04x (sourceType=%d)\n", kInd,
printf("%s *-ThreadMod ADD 0x%08x 0x%04x (sourceType=%d)\n", kInd,
pThreadMod->entry.add.threadID,
pThreadMod->entry.add.threadFormat,
Nu_DataSourceGetType(pThreadMod->entry.add.pDataSource));
break;
case kNuThreadModUpdate:
printf("%s *-ThreadMod UPDATE %6ld\n", kInd,
printf("%s *-ThreadMod UPDATE %6d\n", kInd,
pThreadMod->entry.update.threadIdx);
break;
case kNuThreadModDelete:
printf("%s *-ThreadMod DELETE %6ld\n", kInd,
printf("%s *-ThreadMod DELETE %6d\n", kInd,
pThreadMod->entry.delete.threadIdx);
break;
case kNuThreadModUnknown:
@ -280,7 +278,7 @@ Nu_DebugDumpRecord(NuArchive* pArchive, const NuRecord* pRecord,
/*printf("%s*TotalLength: %ld TotalCompLength: %ld\n",
kInd, pRecord->totalLength, pRecord->totalCompLength);*/
printf("%s*TotalCompLength: %ld\n", kInd, pRecord->totalCompLength);
printf("%s*TotalCompLength: %u\n", kInd, pRecord->totalCompLength);
printf("\n");
bail:
@ -290,9 +288,8 @@ bail:
/*
* Dump the records in a RecordSet.
*/
static void
Nu_DebugDumpRecordSet(NuArchive* pArchive, const NuRecordSet* pRecordSet,
const NuRecordSet* pXrefSet)
static void Nu_DebugDumpRecordSet(NuArchive* pArchive,
const NuRecordSet* pRecordSet, const NuRecordSet* pXrefSet)
{
const NuRecord* pRecord;
const NuRecord* pXrefRecord;
@ -300,8 +297,8 @@ Nu_DebugDumpRecordSet(NuArchive* pArchive, const NuRecordSet* pRecordSet,
long count;
doXref = false;
pXrefRecord = nil;
if (pXrefSet != nil && Nu_RecordSet_GetLoaded(pXrefSet)) {
pXrefRecord = NULL;
if (pXrefSet != NULL && Nu_RecordSet_GetLoaded(pXrefSet)) {
pXrefRecord = Nu_RecordSet_GetListHead(pXrefSet);
doXref = true;
}
@ -309,18 +306,18 @@ Nu_DebugDumpRecordSet(NuArchive* pArchive, const NuRecordSet* pRecordSet,
/* dump every record, if we've loaded them */
count = Nu_RecordSet_GetNumRecords(pRecordSet);
pRecord = Nu_RecordSet_GetListHead(pRecordSet);
if (pRecord != nil) {
if (pRecord != NULL) {
Assert(count != 0);
while (count--) {
Assert(pRecord != nil);
Assert(pRecord != NULL);
if (pXrefRecord != nil &&
if (pXrefRecord != NULL &&
pRecord->recordIdx == pXrefRecord->recordIdx)
{
Nu_DebugDumpRecord(pArchive, pRecord, pXrefRecord, false);
pXrefRecord = pXrefRecord->pNext;
} else {
Nu_DebugDumpRecord(pArchive, pRecord, nil, doXref);
Nu_DebugDumpRecord(pArchive, pRecord, NULL, doXref);
}
pRecord = pRecord->pNext;
}
@ -332,22 +329,21 @@ Nu_DebugDumpRecordSet(NuArchive* pArchive, const NuRecordSet* pRecordSet,
/*
* Dump the master header block.
*/
static void
Nu_DebugDumpMH(const NuMasterHeader* pMasterHeader)
static void Nu_DebugDumpMH(const NuMasterHeader* pMasterHeader)
{
static const char* kInd = " ";
char dateBuf1[kNuDateOutputLen];
Assert(pMasterHeader != nil);
Assert(pMasterHeader != NULL);
printf("%sNufileID: '%.6s' MasterCRC: 0x%04x TotalRecords: %lu\n", kInd,
printf("%sNufileID: '%.6s' MasterCRC: 0x%04x TotalRecords: %u\n", kInd,
pMasterHeader->mhNufileID, pMasterHeader->mhMasterCRC,
pMasterHeader->mhTotalRecords);
printf("%sArchiveCreateWhen: %s\n", kInd,
Nu_DebugDumpDate(&pMasterHeader->mhArchiveCreateWhen, dateBuf1));
printf("%sArchiveModWhen: %s\n", kInd,
Nu_DebugDumpDate(&pMasterHeader->mhArchiveModWhen, dateBuf1));
printf("%sMasterVersion: %u MasterEOF: %lu\n", kInd,
printf("%sMasterVersion: %u MasterEOF: %u\n", kInd,
pMasterHeader->mhMasterVersion, pMasterHeader->mhMasterEOF);
}
@ -359,20 +355,19 @@ Nu_DebugDumpMH(const NuMasterHeader* pMasterHeader)
* the archive, then this won't be very interesting. This will never
* show any records for streaming-mode archives.
*/
void
Nu_DebugDumpAll(NuArchive* pArchive)
void Nu_DebugDumpAll(NuArchive* pArchive)
{
Assert(pArchive != nil);
Assert(pArchive != NULL);
printf("*Archive pathname: '%s'\n", pArchive->archivePathname);
printf("*Archive pathname: '%s'\n", pArchive->archivePathnameUNI);
printf("*Archive type: %d\n", pArchive->archiveType);
printf("*Header offset: %ld (junk offset=%ld)\n",
pArchive->headerOffset, pArchive->junkOffset);
printf("*Num records: %ld orig, %ld copy, %ld new\n",
printf("*Num records: %u orig, %u copy, %u new\n",
Nu_RecordSet_GetNumRecords(&pArchive->origRecordSet),
Nu_RecordSet_GetNumRecords(&pArchive->copyRecordSet),
Nu_RecordSet_GetNumRecords(&pArchive->newRecordSet));
printf("*NuRecordIdx seed: %lu NuRecordIdx next: %lu\n",
printf("*NuRecordIdx seed: %u NuRecordIdx next: %u\n",
pArchive->recordIdxSeed, pArchive->nextRecordIdx);
/* master header */
@ -382,7 +377,7 @@ Nu_DebugDumpAll(NuArchive* pArchive)
Nu_DebugDumpRecordSet(pArchive, &pArchive->origRecordSet,
&pArchive->copyRecordSet);
printf(" *NEW record set:\n");
Nu_DebugDumpRecordSet(pArchive, &pArchive->newRecordSet, nil);
Nu_DebugDumpRecordSet(pArchive, &pArchive->newRecordSet, NULL);
if (!Nu_RecordSet_GetLoaded(&pArchive->origRecordSet) &&
!Nu_RecordSet_GetLoaded(&pArchive->newRecordSet))

File diff suppressed because it is too large Load Diff

View File

@ -25,13 +25,11 @@
/*
* Alloc and free functions provided to zlib.
*/
static voidpf
Nu_zalloc(voidpf opaque, uInt items, uInt size)
static voidpf Nu_zalloc(voidpf opaque, uInt items, uInt size)
{
return Nu_Malloc(opaque, items * size);
}
static void
Nu_zfree(voidpf opaque, voidpf address)
static void Nu_zfree(voidpf opaque, voidpf address)
{
Nu_Free(opaque, address);
}
@ -46,21 +44,20 @@ Nu_zfree(voidpf opaque, voidpf address)
/*
* Compress "srcLen" bytes from "pStraw" to "fp".
*/
NuError
Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc)
NuError Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
{
NuError err = kNuErrNone;
z_stream zstream;
int zerr;
Bytef* outbuf = nil;
Bytef* outbuf = NULL;
Assert(pArchive != nil);
Assert(pStraw != nil);
Assert(fp != nil);
Assert(pArchive != NULL);
Assert(pStraw != NULL);
Assert(fp != NULL);
Assert(srcLen > 0);
Assert(pDstLen != nil);
Assert(pCrc != nil);
Assert(pDstLen != NULL);
Assert(pCrc != NULL);
err = Nu_AllocCompressionBufferIFN(pArchive);
if (err != kNuErrNone)
@ -76,7 +73,7 @@ Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
zstream.zalloc = Nu_zalloc;
zstream.zfree = Nu_zfree;
zstream.opaque = pArchive;
zstream.next_in = nil;
zstream.next_in = NULL;
zstream.avail_in = 0;
zstream.next_out = outbuf;
zstream.avail_out = kNuGenCompBufSize;
@ -100,7 +97,7 @@ Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
* Loop while we have data.
*/
do {
ulong getSize;
uint32_t getSize;
int flush;
/* should be able to read a full buffer every time */
@ -159,7 +156,7 @@ z_bail:
deflateEnd(&zstream); /* free up any allocated structures */
bail:
if (outbuf != nil)
if (outbuf != NULL)
free(outbuf);
return err;
}
@ -174,20 +171,19 @@ bail:
/*
* Expand from "infp" to "pFunnel".
*/
NuError
Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
NuError Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc)
{
NuError err = kNuErrNone;
z_stream zstream;
int zerr;
ulong compRemaining;
uint32_t compRemaining;
Bytef* outbuf;
Assert(pArchive != nil);
Assert(pThread != nil);
Assert(infp != nil);
Assert(pFunnel != nil);
Assert(pArchive != NULL);
Assert(pThread != NULL);
Assert(infp != NULL);
Assert(pFunnel != NULL);
err = Nu_AllocCompressionBufferIFN(pArchive);
if (err != kNuErrNone)
@ -205,7 +201,7 @@ Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
zstream.zalloc = Nu_zalloc;
zstream.zfree = Nu_zfree;
zstream.opaque = pArchive;
zstream.next_in = nil;
zstream.next_in = NULL;
zstream.avail_in = 0;
zstream.next_out = outbuf;
zstream.avail_out = kNuGenCompBufSize;
@ -229,7 +225,7 @@ Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
* Loop while we have data.
*/
do {
ulong getSize;
uint32_t getSize;
/* read as much as we can */
if (zstream.avail_in == 0) {
@ -269,7 +265,7 @@ Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
goto z_bail;
}
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = Nu_CalcCRC16(*pCrc, outbuf, zstream.next_out - outbuf);
zstream.next_out = outbuf;
@ -282,7 +278,7 @@ Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
if (zstream.total_out != pThread->actualThreadEOF) {
err = kNuErrBadData;
Nu_ReportError(NU_BLOB, err,
"size mismatch on inflated file (%ld vs %ld)",
"size mismatch on inflated file (%ld vs %u)",
zstream.total_out, pThread->actualThreadEOF);
goto z_bail;
}
@ -291,7 +287,7 @@ z_bail:
inflateEnd(&zstream); /* free up any allocated structures */
bail:
if (outbuf != nil)
if (outbuf != NULL)
free(outbuf);
return err;
}

View File

@ -24,8 +24,7 @@
* it does not follow all sorts of crazy semaphore semantics. If you
* have the need, go ahead and fix it.
*/
static inline void
Nu_SetBusy(NuArchive* pArchive)
static inline void Nu_SetBusy(NuArchive* pArchive)
{
pArchive->busy = true;
}
@ -33,8 +32,7 @@ Nu_SetBusy(NuArchive* pArchive)
/*
* Clear the busy flag.
*/
static inline void
Nu_ClearBusy(NuArchive* pArchive)
static inline void Nu_ClearBusy(NuArchive* pArchive)
{
pArchive->busy = false;
}
@ -45,13 +43,11 @@ Nu_ClearBusy(NuArchive* pArchive)
* can be made during callback functions when the archive isn't fully
* consistent.
*/
static NuError
Nu_PartiallyValidateNuArchive(const NuArchive* pArchive)
static NuError Nu_PartiallyValidateNuArchive(const NuArchive* pArchive)
{
if (pArchive == nil)
if (pArchive == NULL)
return kNuErrInvalidArg;
pArchive = pArchive;
if (pArchive->structMagic != kNuArchiveStructMagic)
return kNuErrBadStruct;
@ -61,8 +57,7 @@ Nu_PartiallyValidateNuArchive(const NuArchive* pArchive)
/*
* Validate the NuArchive* argument passed in to us.
*/
static NuError
Nu_ValidateNuArchive(const NuArchive* pArchive)
static NuError Nu_ValidateNuArchive(const NuArchive* pArchive)
{
NuError err;
@ -77,19 +72,19 @@ Nu_ValidateNuArchive(const NuArchive* pArchive)
/* make sure the TOC state is consistent */
if (pArchive->haveToc) {
if (pArchive->masterHeader.mhTotalRecords != 0)
Assert(Nu_RecordSet_GetListHead(&pArchive->origRecordSet) != nil);
Assert(Nu_RecordSet_GetListHead(&pArchive->origRecordSet) != NULL);
Assert(Nu_RecordSet_GetNumRecords(&pArchive->origRecordSet) ==
pArchive->masterHeader.mhTotalRecords);
} else {
Assert(Nu_RecordSet_GetListHead(&pArchive->origRecordSet) == nil);
Assert(Nu_RecordSet_GetListHead(&pArchive->origRecordSet) == NULL);
}
/* make sure we have open files to work with */
Assert(pArchive->archivePathname == nil || pArchive->archiveFp != nil);
if (pArchive->archivePathname != nil && pArchive->archiveFp == nil)
Assert(pArchive->archivePathnameUNI == NULL || pArchive->archiveFp != NULL);
if (pArchive->archivePathnameUNI != NULL && pArchive->archiveFp == NULL)
return kNuErrInternal;
Assert(pArchive->tmpPathname == nil || pArchive->tmpFp != nil);
if (pArchive->tmpPathname != nil && pArchive->tmpFp == nil)
Assert(pArchive->tmpPathnameUNI == NULL || pArchive->tmpFp != NULL);
if (pArchive->tmpPathnameUNI != NULL && pArchive->tmpFp == NULL)
return kNuErrInternal;
/* further validations */
@ -104,12 +99,11 @@ Nu_ValidateNuArchive(const NuArchive* pArchive)
* ===========================================================================
*/
NUFXLIB_API NuError
NuStreamOpenRO(FILE* infp, NuArchive** ppArchive)
NUFXLIB_API NuError NuStreamOpenRO(FILE* infp, NuArchive** ppArchive)
{
NuError err;
if (infp == nil || ppArchive == nil)
if (infp == NULL || ppArchive == NULL)
return kNuErrInvalidArg;
err = Nu_StreamOpenRO(infp, (NuArchive**) ppArchive);
@ -117,8 +111,7 @@ NuStreamOpenRO(FILE* infp, NuArchive** ppArchive)
return err;
}
NUFXLIB_API NuError
NuContents(NuArchive* pArchive, NuCallback contentFunc)
NUFXLIB_API NuError NuContents(NuArchive* pArchive, NuCallback contentFunc)
{
NuError err;
@ -134,8 +127,7 @@ NuContents(NuArchive* pArchive, NuCallback contentFunc)
return err;
}
NUFXLIB_API NuError
NuExtract(NuArchive* pArchive)
NUFXLIB_API NuError NuExtract(NuArchive* pArchive)
{
NuError err;
@ -151,8 +143,7 @@ NuExtract(NuArchive* pArchive)
return err;
}
NUFXLIB_API NuError
NuTest(NuArchive* pArchive)
NUFXLIB_API NuError NuTest(NuArchive* pArchive)
{
NuError err;
@ -168,8 +159,7 @@ NuTest(NuArchive* pArchive)
return err;
}
NUFXLIB_API NuError
NuTestRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
NUFXLIB_API NuError NuTestRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
{
NuError err;
@ -189,18 +179,17 @@ NuTestRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
* ===========================================================================
*/
NUFXLIB_API NuError
NuOpenRO(const char* filename, NuArchive** ppArchive)
NUFXLIB_API NuError NuOpenRO(const UNICHAR* archivePathnameUNI,
NuArchive** ppArchive)
{
NuError err;
err = Nu_OpenRO(filename, (NuArchive**) ppArchive);
err = Nu_OpenRO(archivePathnameUNI, (NuArchive**) ppArchive);
return err;
}
NUFXLIB_API NuError
NuExtractRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
NUFXLIB_API NuError NuExtractRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
{
NuError err;
@ -213,8 +202,7 @@ NuExtractRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
return err;
}
NUFXLIB_API NuError
NuExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
NUFXLIB_API NuError NuExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
NuDataSink* pDataSink)
{
NuError err;
@ -228,8 +216,7 @@ NuExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
return err;
}
NUFXLIB_API NuError
NuGetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
NUFXLIB_API NuError NuGetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
const NuRecord** ppRecord)
{
NuError err;
@ -243,23 +230,21 @@ NuGetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
return err;
}
NUFXLIB_API NuError
NuGetRecordIdxByName(NuArchive* pArchive, const char* name,
NuRecordIdx* pRecordIdx)
NUFXLIB_API NuError NuGetRecordIdxByName(NuArchive* pArchive,
const char* nameMOR, NuRecordIdx* pRecordIdx)
{
NuError err;
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
Nu_SetBusy(pArchive);
err = Nu_GetRecordIdxByName(pArchive, name, pRecordIdx);
err = Nu_GetRecordIdxByName(pArchive, nameMOR, pRecordIdx);
Nu_ClearBusy(pArchive);
}
return err;
}
NUFXLIB_API NuError
NuGetRecordIdxByPosition(NuArchive* pArchive, unsigned long position,
NUFXLIB_API NuError NuGetRecordIdxByPosition(NuArchive* pArchive, uint32_t position,
NuRecordIdx* pRecordIdx)
{
NuError err;
@ -280,20 +265,18 @@ NuGetRecordIdxByPosition(NuArchive* pArchive, unsigned long position,
* ===========================================================================
*/
NUFXLIB_API NuError
NuOpenRW(const char* archivePathname, const char* tmpPathname,
unsigned long flags, NuArchive** ppArchive)
NUFXLIB_API NuError NuOpenRW(const UNICHAR* archivePathnameUNI,
const UNICHAR* tmpPathnameUNI, uint32_t flags, NuArchive** ppArchive)
{
NuError err;
err = Nu_OpenRW(archivePathname, tmpPathname, flags,
err = Nu_OpenRW(archivePathnameUNI, tmpPathnameUNI, flags,
(NuArchive**) ppArchive);
return err;
}
NUFXLIB_API NuError
NuFlush(NuArchive* pArchive, long* pStatusFlags)
NUFXLIB_API NuError NuFlush(NuArchive* pArchive, uint32_t* pStatusFlags)
{
NuError err;
@ -306,8 +289,7 @@ NuFlush(NuArchive* pArchive, long* pStatusFlags)
return err;
}
NUFXLIB_API NuError
NuAbort(NuArchive* pArchive)
NUFXLIB_API NuError NuAbort(NuArchive* pArchive)
{
NuError err;
@ -320,24 +302,22 @@ NuAbort(NuArchive* pArchive)
return err;
}
NUFXLIB_API NuError
NuAddRecord(NuArchive* pArchive, const NuFileDetails* pFileDetails,
NuRecordIdx* pRecordIdx)
NUFXLIB_API NuError NuAddRecord(NuArchive* pArchive,
const NuFileDetails* pFileDetails, NuRecordIdx* pRecordIdx)
{
NuError err;
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
Nu_SetBusy(pArchive);
err = Nu_AddRecord(pArchive, pFileDetails, pRecordIdx, nil);
err = Nu_AddRecord(pArchive, pFileDetails, pRecordIdx, NULL);
Nu_ClearBusy(pArchive);
}
return err;
}
NUFXLIB_API NuError
NuAddThread(NuArchive* pArchive, NuRecordIdx recordIdx, NuThreadID threadID,
NuDataSource* pDataSource, NuThreadIdx* pThreadIdx)
NUFXLIB_API NuError NuAddThread(NuArchive* pArchive, NuRecordIdx recordIdx,
NuThreadID threadID, NuDataSource* pDataSource, NuThreadIdx* pThreadIdx)
{
NuError err;
@ -351,8 +331,7 @@ NuAddThread(NuArchive* pArchive, NuRecordIdx recordIdx, NuThreadID threadID,
return err;
}
NUFXLIB_API NuError
NuAddFile(NuArchive* pArchive, const char* pathname,
NUFXLIB_API NuError NuAddFile(NuArchive* pArchive, const UNICHAR* pathnameUNI,
const NuFileDetails* pFileDetails, short isFromRsrcFork,
NuRecordIdx* pRecordIdx)
{
@ -360,7 +339,7 @@ NuAddFile(NuArchive* pArchive, const char* pathname,
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
Nu_SetBusy(pArchive);
err = Nu_AddFile(pArchive, pathname, pFileDetails,
err = Nu_AddFile(pArchive, pathnameUNI, pFileDetails,
(Boolean)(isFromRsrcFork != 0), pRecordIdx);
Nu_ClearBusy(pArchive);
}
@ -368,15 +347,14 @@ NuAddFile(NuArchive* pArchive, const char* pathname,
return err;
}
NUFXLIB_API NuError
NuRename(NuArchive* pArchive, NuRecordIdx recordIdx, const char* pathname,
char fssep)
NUFXLIB_API NuError NuRename(NuArchive* pArchive, NuRecordIdx recordIdx,
const char* pathnameMOR, char fssep)
{
NuError err;
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
Nu_SetBusy(pArchive);
err = Nu_Rename(pArchive, recordIdx, pathname, fssep);
err = Nu_Rename(pArchive, recordIdx, pathnameMOR, fssep);
Nu_ClearBusy(pArchive);
}
@ -384,8 +362,7 @@ NuRename(NuArchive* pArchive, NuRecordIdx recordIdx, const char* pathname,
}
NUFXLIB_API NuError
NuSetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
NUFXLIB_API NuError NuSetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
const NuRecordAttr* pRecordAttr)
{
NuError err;
@ -399,9 +376,8 @@ NuSetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
return err;
}
NUFXLIB_API NuError
NuUpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
NuDataSource* pDataSource, long* pMaxLen)
NUFXLIB_API NuError NuUpdatePresizedThread(NuArchive* pArchive,
NuThreadIdx threadIdx, NuDataSource* pDataSource, int32_t* pMaxLen)
{
NuError err;
@ -415,8 +391,7 @@ NuUpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
return err;
}
NUFXLIB_API NuError
NuDelete(NuArchive* pArchive)
NUFXLIB_API NuError NuDelete(NuArchive* pArchive)
{
NuError err;
@ -429,8 +404,7 @@ NuDelete(NuArchive* pArchive)
return err;
}
NUFXLIB_API NuError
NuDeleteRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
NUFXLIB_API NuError NuDeleteRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
{
NuError err;
@ -443,8 +417,7 @@ NuDeleteRecord(NuArchive* pArchive, NuRecordIdx recordIdx)
return err;
}
NUFXLIB_API NuError
NuDeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
NUFXLIB_API NuError NuDeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
{
NuError err;
@ -464,8 +437,7 @@ NuDeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
* ===========================================================================
*/
NUFXLIB_API NuError
NuClose(NuArchive* pArchive)
NUFXLIB_API NuError NuClose(NuArchive* pArchive)
{
NuError err;
@ -480,8 +452,8 @@ NuClose(NuArchive* pArchive)
return err;
}
NUFXLIB_API NuError
NuGetMasterHeader(NuArchive* pArchive, const NuMasterHeader** ppMasterHeader)
NUFXLIB_API NuError NuGetMasterHeader(NuArchive* pArchive,
const NuMasterHeader** ppMasterHeader)
{
NuError err;
@ -491,12 +463,11 @@ NuGetMasterHeader(NuArchive* pArchive, const NuMasterHeader** ppMasterHeader)
return err;
}
NUFXLIB_API NuError
NuGetExtraData(NuArchive* pArchive, void** ppData)
NUFXLIB_API NuError NuGetExtraData(NuArchive* pArchive, void** ppData)
{
NuError err;
if (ppData == nil)
if (ppData == NULL)
return kNuErrInvalidArg;
if ((err = Nu_PartiallyValidateNuArchive(pArchive)) == kNuErrNone)
*ppData = pArchive->extraData;
@ -504,8 +475,7 @@ NuGetExtraData(NuArchive* pArchive, void** ppData)
return err;
}
NUFXLIB_API NuError
NuSetExtraData(NuArchive* pArchive, void* pData)
NUFXLIB_API NuError NuSetExtraData(NuArchive* pArchive, void* pData)
{
NuError err;
@ -515,8 +485,8 @@ NuSetExtraData(NuArchive* pArchive, void* pData)
return err;
}
NUFXLIB_API NuError
NuGetValue(NuArchive* pArchive, NuValueID ident, NuValue* pValue)
NUFXLIB_API NuError NuGetValue(NuArchive* pArchive, NuValueID ident,
NuValue* pValue)
{
NuError err;
@ -526,8 +496,8 @@ NuGetValue(NuArchive* pArchive, NuValueID ident, NuValue* pValue)
return err;
}
NUFXLIB_API NuError
NuSetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
NUFXLIB_API NuError NuSetValue(NuArchive* pArchive, NuValueID ident,
NuValue value)
{
NuError err;
@ -537,8 +507,8 @@ NuSetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
return err;
}
NUFXLIB_API NuError
NuGetAttr(NuArchive* pArchive, NuAttrID ident, NuAttr* pAttr)
NUFXLIB_API NuError NuGetAttr(NuArchive* pArchive, NuAttrID ident,
NuAttr* pAttr)
{
NuError err;
@ -548,8 +518,7 @@ NuGetAttr(NuArchive* pArchive, NuAttrID ident, NuAttr* pAttr)
return err;
}
NUFXLIB_API NuError
NuDebugDumpArchive(NuArchive* pArchive)
NUFXLIB_API NuError NuDebugDumpArchive(NuArchive* pArchive)
{
#if defined(DEBUG_MSGS)
/* skip validation checks for this one */
@ -568,82 +537,75 @@ NuDebugDumpArchive(NuArchive* pArchive)
* ===========================================================================
*/
NUFXLIB_API NuError
NuCreateDataSourceForFile(NuThreadFormat threadFormat,
unsigned long otherLen, const char* pathname, short isFromRsrcFork,
NUFXLIB_API NuError NuCreateDataSourceForFile(NuThreadFormat threadFormat,
uint32_t otherLen, const UNICHAR* pathnameUNI, short isFromRsrcFork,
NuDataSource** ppDataSource)
{
return Nu_DataSourceFile_New(threadFormat, otherLen,
pathname, (Boolean)(isFromRsrcFork != 0), ppDataSource);
pathnameUNI, (Boolean)(isFromRsrcFork != 0), ppDataSource);
}
NUFXLIB_API NuError
NuCreateDataSourceForFP(NuThreadFormat threadFormat,
unsigned long otherLen, FILE* fp, long offset, long length,
NUFXLIB_API NuError NuCreateDataSourceForFP(NuThreadFormat threadFormat,
uint32_t otherLen, FILE* fp, long offset, long length,
NuCallback fcloseFunc, NuDataSource** ppDataSource)
{
return Nu_DataSourceFP_New(threadFormat, otherLen,
fp, offset, length, fcloseFunc, ppDataSource);
}
NUFXLIB_API NuError
NuCreateDataSourceForBuffer(NuThreadFormat threadFormat,
unsigned long otherLen, const unsigned char* buffer, long offset,
NUFXLIB_API NuError NuCreateDataSourceForBuffer(NuThreadFormat threadFormat,
uint32_t otherLen, const uint8_t* buffer, long offset,
long length, NuCallback freeFunc, NuDataSource** ppDataSource)
{
return Nu_DataSourceBuffer_New(threadFormat, otherLen,
buffer, offset, length, freeFunc, ppDataSource);
}
NUFXLIB_API NuError
NuFreeDataSource(NuDataSource* pDataSource)
NUFXLIB_API NuError NuFreeDataSource(NuDataSource* pDataSource)
{
return Nu_DataSourceFree(pDataSource);
}
NUFXLIB_API NuError
NuDataSourceSetRawCrc(NuDataSource* pDataSource, unsigned short crc)
NUFXLIB_API NuError NuDataSourceSetRawCrc(NuDataSource* pDataSource,
uint16_t crc)
{
if (pDataSource == nil)
if (pDataSource == NULL)
return kNuErrInvalidArg;
Nu_DataSourceSetRawCrc(pDataSource, crc);
return kNuErrNone;
}
NUFXLIB_API NuError
NuCreateDataSinkForFile(short doExpand, NuValue convertEOL,
const char* pathname, char fssep, NuDataSink** ppDataSink)
NUFXLIB_API NuError NuCreateDataSinkForFile(short doExpand, NuValue convertEOL,
const UNICHAR* pathnameUNI, UNICHAR fssep, NuDataSink** ppDataSink)
{
return Nu_DataSinkFile_New((Boolean)(doExpand != 0), convertEOL, pathname,
fssep, ppDataSink);
return Nu_DataSinkFile_New((Boolean)(doExpand != 0), convertEOL,
pathnameUNI, fssep, ppDataSink);
}
NUFXLIB_API NuError
NuCreateDataSinkForFP(short doExpand, NuValue convertEOL, FILE* fp,
NuDataSink** ppDataSink)
NUFXLIB_API NuError NuCreateDataSinkForFP(short doExpand, NuValue convertEOL,
FILE* fp, NuDataSink** ppDataSink)
{
return Nu_DataSinkFP_New((Boolean)(doExpand != 0), convertEOL, fp,
ppDataSink);
}
NUFXLIB_API NuError
NuCreateDataSinkForBuffer(short doExpand, NuValue convertEOL,
unsigned char* buffer, unsigned long bufLen, NuDataSink** ppDataSink)
NUFXLIB_API NuError NuCreateDataSinkForBuffer(short doExpand,
NuValue convertEOL, uint8_t* buffer, uint32_t bufLen,
NuDataSink** ppDataSink)
{
return Nu_DataSinkBuffer_New((Boolean)(doExpand != 0), convertEOL, buffer,
bufLen, ppDataSink);
}
NUFXLIB_API NuError
NuFreeDataSink(NuDataSink* pDataSink)
NUFXLIB_API NuError NuFreeDataSink(NuDataSink* pDataSink)
{
return Nu_DataSinkFree(pDataSink);
}
NUFXLIB_API NuError
NuDataSinkGetOutCount(NuDataSink* pDataSink, ulong* pOutCount)
NUFXLIB_API NuError NuDataSinkGetOutCount(NuDataSink* pDataSink,
uint32_t* pOutCount)
{
if (pDataSink == nil || pOutCount == nil)
if (pDataSink == NULL || pOutCount == NULL)
return kNuErrInvalidArg;
*pOutCount = Nu_DataSinkGetOutCount(pDataSink);
@ -657,22 +619,19 @@ NuDataSinkGetOutCount(NuDataSink* pDataSink, ulong* pOutCount)
* ===========================================================================
*/
NUFXLIB_API const char*
NuStrError(NuError err)
NUFXLIB_API const char* NuStrError(NuError err)
{
return Nu_StrError(err);
}
NUFXLIB_API NuError
NuGetVersion(long* pMajorVersion, long* pMinorVersion, long* pBugVersion,
const char** ppBuildDate, const char** ppBuildFlags)
NUFXLIB_API NuError NuGetVersion(int32_t* pMajorVersion, int32_t* pMinorVersion,
int32_t* pBugVersion, const char** ppBuildDate, const char** ppBuildFlags)
{
return Nu_GetVersion(pMajorVersion, pMinorVersion, pBugVersion,
ppBuildDate, ppBuildFlags);
}
NUFXLIB_API NuError
NuTestFeature(NuFeature feature)
NUFXLIB_API NuError NuTestFeature(NuFeature feature)
{
NuError err = kNuErrUnsupFeature;
@ -710,8 +669,8 @@ NuTestFeature(NuFeature feature)
return err;
}
NUFXLIB_API void
NuRecordCopyAttr(NuRecordAttr* pRecordAttr, const NuRecord* pRecord)
NUFXLIB_API void NuRecordCopyAttr(NuRecordAttr* pRecordAttr,
const NuRecord* pRecord)
{
pRecordAttr->fileSysID = pRecord->recFileSysID;
/*pRecordAttr->fileSysInfo = pRecord->recFileSysInfo;*/
@ -723,16 +682,16 @@ NuRecordCopyAttr(NuRecordAttr* pRecordAttr, const NuRecord* pRecord)
pRecordAttr->archiveWhen = pRecord->recArchiveWhen;
}
NUFXLIB_API NuError
NuRecordCopyThreads(const NuRecord* pNuRecord, NuThread** ppThreads)
NUFXLIB_API NuError NuRecordCopyThreads(const NuRecord* pNuRecord,
NuThread** ppThreads)
{
if (pNuRecord == nil || ppThreads == nil)
if (pNuRecord == NULL || ppThreads == NULL)
return kNuErrInvalidArg;
Assert(pNuRecord->pThreads != nil);
Assert(pNuRecord->pThreads != NULL);
*ppThreads = Nu_Malloc(nil, pNuRecord->recTotalThreads * sizeof(NuThread));
if (*ppThreads == nil)
*ppThreads = Nu_Malloc(NULL, pNuRecord->recTotalThreads * sizeof(NuThread));
if (*ppThreads == NULL)
return kNuErrMalloc;
memcpy(*ppThreads, pNuRecord->pThreads,
@ -741,29 +700,39 @@ NuRecordCopyThreads(const NuRecord* pNuRecord, NuThread** ppThreads)
return kNuErrNone;
}
NUFXLIB_API unsigned long
NuRecordGetNumThreads(const NuRecord* pNuRecord)
NUFXLIB_API uint32_t NuRecordGetNumThreads(const NuRecord* pNuRecord)
{
if (pNuRecord == nil)
if (pNuRecord == NULL)
return -1;
return pNuRecord->recTotalThreads;
}
NUFXLIB_API const NuThread*
NuThreadGetByIdx(const NuThread* pNuThread, long idx)
NUFXLIB_API const NuThread* NuThreadGetByIdx(const NuThread* pNuThread,
int32_t idx)
{
if (pNuThread == nil)
return nil;
if (pNuThread == NULL)
return NULL;
return &pNuThread[idx]; /* can't range-check here */
}
NUFXLIB_API short
NuIsPresizedThreadID(NuThreadID threadID)
NUFXLIB_API short NuIsPresizedThreadID(NuThreadID threadID)
{
return Nu_IsPresizedThreadID(threadID);
}
NUFXLIB_API size_t NuConvertMORToUNI(const char* stringMOR,
UNICHAR* bufUNI, size_t bufSize)
{
return Nu_ConvertMORToUNI(stringMOR, bufUNI, bufSize);
}
NUFXLIB_API size_t NuConvertUNIToMOR(const UNICHAR* stringUNI,
char* bufMOR, size_t bufSize)
{
return Nu_ConvertUNIToMOR(stringUNI, bufMOR, bufSize);
}
/*
* ===========================================================================
@ -771,13 +740,13 @@ NuIsPresizedThreadID(NuThreadID threadID)
* ===========================================================================
*/
NUFXLIB_API NuCallback
NuSetSelectionFilter(NuArchive* pArchive, NuCallback filterFunc)
NUFXLIB_API NuCallback NuSetSelectionFilter(NuArchive* pArchive,
NuCallback filterFunc)
{
NuError err;
NuCallback oldFunc = kNuInvalidCallback;
/*Assert(!((ulong)filterFunc % 4));*/
/*Assert(!((uint32_t)filterFunc % 4));*/
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
oldFunc = pArchive->selectionFilterFunc;
@ -787,13 +756,13 @@ NuSetSelectionFilter(NuArchive* pArchive, NuCallback filterFunc)
return oldFunc;
}
NUFXLIB_API NuCallback
NuSetOutputPathnameFilter(NuArchive* pArchive, NuCallback filterFunc)
NUFXLIB_API NuCallback NuSetOutputPathnameFilter(NuArchive* pArchive,
NuCallback filterFunc)
{
NuError err;
NuCallback oldFunc = kNuInvalidCallback;
/*Assert(!((ulong)filterFunc % 4));*/
/*Assert(!((uint32_t)filterFunc % 4));*/
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
oldFunc = pArchive->outputPathnameFunc;
@ -803,13 +772,13 @@ NuSetOutputPathnameFilter(NuArchive* pArchive, NuCallback filterFunc)
return oldFunc;
}
NUFXLIB_API NuCallback
NuSetProgressUpdater(NuArchive* pArchive, NuCallback updateFunc)
NUFXLIB_API NuCallback NuSetProgressUpdater(NuArchive* pArchive,
NuCallback updateFunc)
{
NuError err;
NuCallback oldFunc = kNuInvalidCallback;
/*Assert(!((ulong)updateFunc % 4));*/
/*Assert(!((uint32_t)updateFunc % 4));*/
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
oldFunc = pArchive->progressUpdaterFunc;
@ -819,13 +788,13 @@ NuSetProgressUpdater(NuArchive* pArchive, NuCallback updateFunc)
return oldFunc;
}
NUFXLIB_API NuCallback
NuSetErrorHandler(NuArchive* pArchive, NuCallback errorFunc)
NUFXLIB_API NuCallback NuSetErrorHandler(NuArchive* pArchive,
NuCallback errorFunc)
{
NuError err;
NuCallback oldFunc = kNuInvalidCallback;
/*Assert(!((ulong)errorFunc % 4));*/
/*Assert(!((uint32_t)errorFunc % 4));*/
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
oldFunc = pArchive->errorHandlerFunc;
@ -835,13 +804,13 @@ NuSetErrorHandler(NuArchive* pArchive, NuCallback errorFunc)
return oldFunc;
}
NUFXLIB_API NuCallback
NuSetErrorMessageHandler(NuArchive* pArchive, NuCallback messageHandlerFunc)
NUFXLIB_API NuCallback NuSetErrorMessageHandler(NuArchive* pArchive,
NuCallback messageHandlerFunc)
{
NuError err;
NuCallback oldFunc = kNuInvalidCallback;
/*Assert(!((ulong)messageHandlerFunc % 4));*/
/*Assert(!((uint32_t)messageHandlerFunc % 4));*/
if ((err = Nu_ValidateNuArchive(pArchive)) == kNuErrNone) {
oldFunc = pArchive->messageHandlerFunc;
@ -851,11 +820,10 @@ NuSetErrorMessageHandler(NuArchive* pArchive, NuCallback messageHandlerFunc)
return oldFunc;
}
NUFXLIB_API NuCallback
NuSetGlobalErrorMessageHandler(NuCallback messageHandlerFunc)
NUFXLIB_API NuCallback NuSetGlobalErrorMessageHandler(NuCallback messageHandlerFunc)
{
NuCallback oldFunc = kNuInvalidCallback;
/*Assert(!((ulong)messageHandlerFunc % 4));*/
/*Assert(!((uint32_t)messageHandlerFunc % 4));*/
oldFunc = gNuGlobalErrorMessageHandler;
gNuGlobalErrorMessageHandler = messageHandlerFunc;

View File

@ -12,18 +12,18 @@
/*
* "Expand" an uncompressed thread.
*/
static NuError
Nu_ExpandUncompressed(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
static NuError Nu_ExpandUncompressed(NuArchive* pArchive,
const NuRecord* pRecord, const NuThread* pThread, FILE* infp,
NuFunnel* pFunnel, uint16_t* pCrc)
{
NuError err;
/*uchar* buffer = nil;*/
ulong count, getsize;
/*uint8_t* buffer = NULL;*/
uint32_t count, getsize;
Assert(pArchive != nil);
Assert(pThread != nil);
Assert(infp != nil);
Assert(pFunnel != nil);
Assert(pArchive != NULL);
Assert(pThread != NULL);
Assert(infp != NULL);
Assert(pFunnel != NULL);
/* doesn't have to be same size as funnel, but it's not a bad idea */
/*buffer = Nu_Malloc(pArchive, kNuFunnelBufSize);*/
@ -43,7 +43,7 @@ Nu_ExpandUncompressed(NuArchive* pArchive, const NuRecord* pRecord,
err = Nu_FRead(infp, pArchive->compBuf, getsize);
BailError(err);
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = Nu_CalcCRC16(*pCrc, pArchive->compBuf, getsize);
err = Nu_FunnelWrite(pArchive, pFunnel, pArchive->compBuf, getsize);
BailError(err);
@ -63,18 +63,17 @@ bail:
* Copy the "raw" data out of the thread. Unlike the preceeding function,
* this reads up to "thCompThreadEOF", and doesn't even try to compute a CRC.
*/
static NuError
Nu_ExpandRaw(NuArchive* pArchive, const NuThread* pThread, FILE* infp,
NuFunnel* pFunnel)
static NuError Nu_ExpandRaw(NuArchive* pArchive, const NuThread* pThread,
FILE* infp, NuFunnel* pFunnel)
{
NuError err;
/*uchar* buffer = nil;*/
ulong count, getsize;
/*uint8_t* buffer = NULL;*/
uint32_t count, getsize;
Assert(pArchive != nil);
Assert(pThread != nil);
Assert(infp != nil);
Assert(pFunnel != nil);
Assert(pArchive != NULL);
Assert(pThread != NULL);
Assert(infp != NULL);
Assert(pFunnel != NULL);
/* doesn't have to be same size as funnel, but it's not a bad idea */
/*buffer = Nu_Malloc(pArchive, kNuFunnelBufSize);*/
@ -108,13 +107,12 @@ bail:
* Expand a thread from "infp" to "pFunnel", using the compression
* and stream length specified by "pThread".
*/
NuError
Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
NuError Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel)
{
NuError err = kNuErrNone;
ushort calcCrc;
ushort* pCalcCrc;
uint16_t calcCrc;
uint16_t* pCalcCrc;
if (!pThread->thThreadEOF && !pThread->thCompThreadEOF) {
/* somebody stored an empty file! */
@ -134,7 +132,7 @@ Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
* unfortunately, unprotected before v3.
*/
calcCrc = kNuInitialThreadCRC;
pCalcCrc = nil;
pCalcCrc = NULL;
if (Nu_ThreadHasCRC(pRecord->recVersionNumber, NuGetThreadID(pThread)) &&
!pArchive->valIgnoreCRC)
{
@ -205,7 +203,7 @@ Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
/*
* If we have a CRC to check, check it.
*/
if (pCalcCrc != nil) {
if (pCalcCrc != NULL) {
if (calcCrc != pThread->thThreadCRC) {
if (!Nu_ShouldIgnoreBadCRC(pArchive, pRecord, kNuErrBadThreadCRC)) {
err = kNuErrBadDataCRC;

File diff suppressed because it is too large Load Diff

View File

@ -22,38 +22,36 @@
* The same structure will be used when expanding all threads in a given
* record.
*/
NuError
Nu_ProgressDataInit_Compress(NuArchive* pArchive, NuProgressData* pProgressData,
const NuRecord* pRecord, const char* origPathname)
NuError Nu_ProgressDataInit_Compress(NuArchive* pArchive,
NuProgressData* pProgressData, const NuRecord* pRecord,
const UNICHAR* origPathnameUNI, const UNICHAR* pathnameUNI)
{
const char* cp;
Assert(pProgressData != nil);
Assert(pArchive != nil);
Assert(pRecord != nil);
Assert(origPathname != nil);
Assert(pProgressData != NULL);
Assert(pArchive != NULL);
Assert(pRecord != NULL);
Assert(origPathnameUNI != NULL);
Assert(pathnameUNI != NULL);
pProgressData->pRecord = pRecord;
pProgressData->origPathname = origPathname;
pProgressData->pathname = pRecord->filename;
cp = strrchr(pRecord->filename,
NuGetSepFromSysInfo(pRecord->recFileSysInfo));
if (cp == nil || *(cp+1) == '\0')
pProgressData->filename = pProgressData->pathname;
pProgressData->origPathnameUNI = origPathnameUNI;
pProgressData->pathnameUNI = pathnameUNI;
cp = strrchr(pathnameUNI, NuGetSepFromSysInfo(pRecord->recFileSysInfo));
if (cp == NULL || *(cp+1) == '\0')
pProgressData->filenameUNI = pProgressData->pathnameUNI;
else
pProgressData->filename = cp+1;
pProgressData->filenameUNI = cp+1;
pProgressData->operation = kNuOpAdd;
pProgressData->state = kNuProgressPreparing;
/*pProgressData->compressedLength = 0;*/
/*pProgressData->compressedProgress = 0;*/
pProgressData->uncompressedLength = 0;
pProgressData->uncompressedProgress = 0;
pProgressData->compress.threadFormat = (NuThreadFormat)-1;
/* ya know... if this is nil, none of the above matters much */
/* ya know... if this is NULL, none of the above matters much */
pProgressData->progressFunc = pArchive->progressUpdaterFunc;
return kNuErrNone;
@ -67,31 +65,32 @@ Nu_ProgressDataInit_Compress(NuArchive* pArchive, NuProgressData* pProgressData,
* The same structure will be used when expanding all threads in a given
* record.
*/
NuError
Nu_ProgressDataInit_Expand(NuArchive* pArchive, NuProgressData* pProgressData,
const NuRecord* pRecord, const char* newPathname, char newFssep,
NuValue convertEOL)
NuError Nu_ProgressDataInit_Expand(NuArchive* pArchive,
NuProgressData* pProgressData, const NuRecord* pRecord,
const UNICHAR* newPathnameUNI, UNICHAR newFssep,
const UNICHAR* origPathnameUNI, NuValue convertEOL)
{
const NuThread* pThreadIter;
const char* cp;
int i;
Assert(pProgressData != nil);
Assert(pArchive != nil);
Assert(pRecord != nil);
Assert(newPathname != nil);
Assert(pProgressData != NULL);
Assert(pArchive != NULL);
Assert(pRecord != NULL);
Assert(newPathnameUNI != NULL);
Assert(origPathnameUNI != NULL);
Assert(newFssep != 0);
pProgressData->pRecord = pRecord;
pProgressData->expand.pThread = nil;
pProgressData->expand.pThread = NULL;
pProgressData->origPathname = pRecord->filename;
pProgressData->pathname = newPathname;
cp = strrchr(newPathname, newFssep);
if (cp == nil || *(cp+1) == '\0')
pProgressData->filename = newPathname;
pProgressData->origPathnameUNI = origPathnameUNI;
pProgressData->pathnameUNI = newPathnameUNI;
cp = strrchr(newPathnameUNI, newFssep);
if (cp == NULL || *(cp+1) == '\0')
pProgressData->filenameUNI = newPathnameUNI;
else
pProgressData->filename = cp+1;
pProgressData->filenameUNI = cp+1;
pProgressData->expand.convertEOL = convertEOL;
@ -111,12 +110,10 @@ Nu_ProgressDataInit_Expand(NuArchive* pArchive, NuProgressData* pProgressData,
if (pArchive->testMode)
pProgressData->operation = kNuOpTest;
pProgressData->state = kNuProgressPreparing;
/*pProgressData->expand.compressedLength = 0;*/
/*pProgressData->expand.compressedProgress = 0;*/
pProgressData->uncompressedLength = 0;
pProgressData->uncompressedProgress = 0;
/* ya know... if this is nil, none of the above matters much */
/* ya know... if this is NULL, none of the above matters much */
pProgressData->progressFunc = pArchive->progressUpdaterFunc;
return kNuErrNone;
@ -126,18 +123,17 @@ Nu_ProgressDataInit_Expand(NuArchive* pArchive, NuProgressData* pProgressData,
/*
* Do the setup on a ProgressData prior to compressing a thread.
*/
NuError
Nu_ProgressDataCompressPrep(NuArchive* pArchive, NuStraw* pStraw,
NuThreadFormat threadFormat, ulong sourceLen)
NuError Nu_ProgressDataCompressPrep(NuArchive* pArchive, NuStraw* pStraw,
NuThreadFormat threadFormat, uint32_t sourceLen)
{
NuProgressData* pProgressData;
Assert(pArchive != nil);
Assert(pStraw != nil);
Assert(pArchive != NULL);
Assert(pStraw != NULL);
Assert(sourceLen < 32767*65536);
pProgressData = pStraw->pProgress;
if (pProgressData == nil)
if (pProgressData == NULL)
return kNuErrNone;
pProgressData->uncompressedLength = sourceLen;
@ -151,18 +147,17 @@ Nu_ProgressDataCompressPrep(NuArchive* pArchive, NuStraw* pStraw,
*
* "pThread" is the thread being expanded.
*/
NuError
Nu_ProgressDataExpandPrep(NuArchive* pArchive, NuFunnel* pFunnel,
NuError Nu_ProgressDataExpandPrep(NuArchive* pArchive, NuFunnel* pFunnel,
const NuThread* pThread)
{
NuProgressData* pProgressData;
Assert(pArchive != nil);
Assert(pFunnel != nil);
Assert(pThread != nil);
Assert(pArchive != NULL);
Assert(pFunnel != NULL);
Assert(pThread != NULL);
pProgressData = pFunnel->pProgress;
if (pProgressData == nil)
if (pProgressData == NULL)
return kNuErrNone;
/*pProgressData->compressedLength = pThread->thCompThreadEOF;*/
@ -175,10 +170,9 @@ Nu_ProgressDataExpandPrep(NuArchive* pArchive, NuFunnel* pFunnel,
/*
* Compute a completion percentage.
*/
static int
Nu_ComputePercent(ulong total, ulong progress)
static int Nu_ComputePercent(uint32_t total, uint32_t progress)
{
ulong perc;
uint32_t perc;
if (!total)
return 0;
@ -200,15 +194,14 @@ Nu_ComputePercent(ulong total, ulong progress)
* Send the initial progress message, before the output file is opened
* (when extracting) or the input file is opened (when adding).
*/
NuError
Nu_SendInitialProgress(NuArchive* pArchive, NuProgressData* pProgress)
NuError Nu_SendInitialProgress(NuArchive* pArchive, NuProgressData* pProgress)
{
NuResult result;
Assert(pArchive != nil);
Assert(pProgress != nil);
Assert(pArchive != NULL);
Assert(pProgress != NULL);
if (pProgress->progressFunc == nil)
if (pProgress->progressFunc == NULL)
return kNuErrNone;
pProgress->percentComplete = Nu_ComputePercent(
@ -234,15 +227,15 @@ Nu_SendInitialProgress(NuArchive* pArchive, NuProgressData* pProgress)
/*
* Allocate and initialize a Funnel.
*/
NuError
Nu_FunnelNew(NuArchive* pArchive, NuDataSink* pDataSink, NuValue convertEOL,
NuValue convertEOLTo, NuProgressData* pProgress, NuFunnel** ppFunnel)
NuError Nu_FunnelNew(NuArchive* pArchive, NuDataSink* pDataSink,
NuValue convertEOL, NuValue convertEOLTo, NuProgressData* pProgress,
NuFunnel** ppFunnel)
{
NuError err = kNuErrNone;
NuFunnel* pFunnel = nil;
NuFunnel* pFunnel = NULL;
Assert(ppFunnel != nil);
Assert(pDataSink != nil);
Assert(ppFunnel != NULL);
Assert(pDataSink != NULL);
Assert(convertEOL == kNuConvertOff ||
convertEOL == kNuConvertOn ||
convertEOL == kNuConvertAuto);
@ -278,10 +271,9 @@ bail:
* The data should already have been written; it's not the duty of a
* "free" function to flush data out.
*/
NuError
Nu_FunnelFree(NuArchive* pArchive, NuFunnel* pFunnel)
NuError Nu_FunnelFree(NuArchive* pArchive, NuFunnel* pFunnel)
{
if (pFunnel == nil)
if (pFunnel == NULL)
return kNuErrNone;
#ifdef DEBUG_MSGS
@ -304,10 +296,9 @@ Nu_FunnelFree(NuArchive* pArchive, NuFunnel* pFunnel)
* allows us to bail out as soon as it's apparent that compression is
* failing and is actually resulting in a larger file.
*/
void
Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, ulong maxBytes)
void Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, uint32_t maxBytes)
{
Assert(pFunnel != nil);
Assert(pFunnel != NULL);
Assert(maxBytes > 0);
pFunnel->outMax = maxBytes;
@ -324,13 +315,12 @@ Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, ulong maxBytes)
* character must have its high bit set, except for spaces (0x20).
* (The exception is courtesy Glen Bredon's "Merlin".)
*/
static Boolean
Nu_CheckHighASCII(const NuFunnel* pFunnel, const unsigned char* buffer,
unsigned long count)
static Boolean Nu_CheckHighASCII(const NuFunnel* pFunnel, const uint8_t* buffer,
uint32_t count)
{
Boolean isHighASCII;
Assert(buffer != nil);
Assert(buffer != NULL);
Assert(count != 0);
Assert(pFunnel->checkStripHighASCII);
@ -405,12 +395,12 @@ static const char gNuIsBinary[256] = {
* Returns kConvEOLOff or kConvEOLOn, and sets pFunnel->doStripHighASCII
* if pFunnel->CheckStripHighASCII is set.
*/
static NuValue
Nu_DetermineConversion(NuFunnel* pFunnel, const uchar* buffer, ulong count)
static NuValue Nu_DetermineConversion(NuFunnel* pFunnel, const uint8_t* buffer,
uint32_t count)
{
ulong bufCount, numBinary, numLF, numCR;
uint32_t bufCount, numBinary, numLF, numCR;
Boolean isHighASCII;
uchar val;
uint8_t val;
if (count < kNuMinConvThreshold)
return kNuConvertOff;
@ -484,12 +474,12 @@ Nu_DetermineConversion(NuFunnel* pFunnel, const uchar* buffer, ulong count)
* This is either a Funnel function or a DataSink function, depending on
* your perspective.
*/
static inline void
Nu_FunnelPutBlock(NuFunnel* pFunnel, const uchar* buf, ulong len)
static inline void Nu_FunnelPutBlock(NuFunnel* pFunnel, const uint8_t* buf,
uint32_t len)
{
Assert(pFunnel != nil);
Assert(pFunnel->pDataSink != nil);
Assert(buf != nil);
Assert(pFunnel != NULL);
Assert(pFunnel->pDataSink != NULL);
Assert(buf != NULL);
Assert(len > 0);
#if 0
@ -511,10 +501,9 @@ Nu_FunnelPutBlock(NuFunnel* pFunnel, const uchar* buf, ulong len)
/*
* Output the EOL marker requested for this system.
*/
static inline void
Nu_PutEOL(NuFunnel* pFunnel)
static inline void Nu_PutEOL(NuFunnel* pFunnel)
{
uchar ch;
uint8_t ch;
if (pFunnel->convertEOLTo == kNuEOLCR) {
ch = kNuCharCR;
@ -540,11 +529,11 @@ Nu_PutEOL(NuFunnel* pFunnel)
* that looks like an EOL mark and convert it. Doesn't matter if it's
* CR, LF, or CRLF; all three get converted to whatever the system uses.
*/
static NuError
Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
static NuError Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uint8_t* buffer,
uint32_t count)
{
NuError err = kNuErrNone;
ulong progressCount = count;
uint32_t progressCount = count;
/*if (pFunnel->outMaxExceeded)
return kNuErrOutMax;*/
@ -566,7 +555,7 @@ Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
pFunnel->convertEOL = kNuConvertOff;
}
/* put it where the progress meter can see it */
if (pFunnel->pProgress != nil)
if (pFunnel->pProgress != NULL)
pFunnel->pProgress->expand.convertEOL = pFunnel->convertEOL;
} else if (pFunnel->convertEOL == kNuConvertOn) {
if (pFunnel->checkStripHighASCII) {
@ -589,7 +578,7 @@ Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
} else {
/* do the EOL conversion and optional high-bit stripping */
Boolean lastCR = pFunnel->lastCR; /* make local copy */
uchar uch;
uint8_t uch;
int mask;
if (pFunnel->doStripHighASCII)
@ -627,7 +616,7 @@ Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
err = Nu_DataSinkGetError(pFunnel->pDataSink);
/* update progress counter with pre-LFCR count */
if (err == kNuErrNone && pFunnel->pProgress != nil)
if (err == kNuErrNone && pFunnel->pProgress != NULL)
pFunnel->pProgress->uncompressedProgress += progressCount;
return err;
@ -637,8 +626,7 @@ Nu_FunnelWriteConvert(NuFunnel* pFunnel, const uchar* buffer, ulong count)
/*
* Flush any data currently in the funnel.
*/
NuError
Nu_FunnelFlush(NuArchive* pArchive, NuFunnel* pFunnel)
NuError Nu_FunnelFlush(NuArchive* pArchive, NuFunnel* pFunnel)
{
NuError err = kNuErrNone;
@ -661,9 +649,8 @@ bail:
* Write a bunch of bytes into a funnel. They will be held in the buffer
* if they fit, or flushed out the bottom if not.
*/
NuError
Nu_FunnelWrite(NuArchive* pArchive, NuFunnel* pFunnel, const uchar* buffer,
ulong count)
NuError Nu_FunnelWrite(NuArchive* pArchive, NuFunnel* pFunnel,
const uint8_t* buffer, uint32_t count)
{
NuError err = kNuErrNone;
@ -714,12 +701,11 @@ bail:
/*
* Set the Funnel's progress state.
*/
NuError
Nu_FunnelSetProgressState(NuFunnel* pFunnel, NuProgressState state)
NuError Nu_FunnelSetProgressState(NuFunnel* pFunnel, NuProgressState state)
{
Assert(pFunnel != nil);
Assert(pFunnel != NULL);
if (pFunnel->pProgress == nil)
if (pFunnel->pProgress == NULL)
return kNuErrNone;
pFunnel->pProgress->state = state;
@ -731,20 +717,19 @@ Nu_FunnelSetProgressState(NuFunnel* pFunnel, NuProgressState state)
/*
* Send a progress update to the application, if they're interested.
*/
NuError
Nu_FunnelSendProgressUpdate(NuArchive* pArchive, NuFunnel* pFunnel)
NuError Nu_FunnelSendProgressUpdate(NuArchive* pArchive, NuFunnel* pFunnel)
{
NuProgressData* pProgress;
Assert(pArchive != nil);
Assert(pFunnel != nil);
Assert(pArchive != NULL);
Assert(pFunnel != NULL);
pProgress = pFunnel->pProgress;
if (pProgress == nil)
if (pProgress == NULL)
return kNuErrNone; /* no progress meter attached */
/* don't continue if they're not accepting progress messages */
if (pProgress->progressFunc == nil)
if (pProgress->progressFunc == NULL)
return kNuErrNone;
/* other than the choice of arguments, it's pretty much the same story */
@ -755,11 +740,10 @@ Nu_FunnelSendProgressUpdate(NuArchive* pArchive, NuFunnel* pFunnel)
/*
* Pull the "doExpand" parameter out of the data source.
*/
Boolean
Nu_FunnelGetDoExpand(NuFunnel* pFunnel)
Boolean Nu_FunnelGetDoExpand(NuFunnel* pFunnel)
{
Assert(pFunnel != nil);
Assert(pFunnel->pDataSink != nil);
Assert(pFunnel != NULL);
Assert(pFunnel->pDataSink != NULL);
return Nu_DataSinkGetDoExpand(pFunnel->pDataSink);
}
@ -774,15 +758,14 @@ Nu_FunnelGetDoExpand(NuFunnel* pFunnel)
/*
* Allocate and initialize a Straw.
*/
NuError
Nu_StrawNew(NuArchive* pArchive, NuDataSource* pDataSource,
NuError Nu_StrawNew(NuArchive* pArchive, NuDataSource* pDataSource,
NuProgressData* pProgress, NuStraw** ppStraw)
{
NuError err = kNuErrNone;
NuStraw* pStraw = nil;
NuStraw* pStraw = NULL;
Assert(ppStraw != nil);
Assert(pDataSource != nil);
Assert(ppStraw != NULL);
Assert(pDataSource != NULL);
pStraw = Nu_Calloc(pArchive, sizeof(*pStraw));
BailAlloc(pStraw);
@ -802,10 +785,9 @@ bail:
/*
* Free a Straw.
*/
NuError
Nu_StrawFree(NuArchive* pArchive, NuStraw* pStraw)
NuError Nu_StrawFree(NuArchive* pArchive, NuStraw* pStraw)
{
if (pStraw == nil)
if (pStraw == NULL)
return kNuErrNone;
/* we don't own the data source or progress meter */
@ -818,11 +800,10 @@ Nu_StrawFree(NuArchive* pArchive, NuStraw* pStraw)
/*
* Set the Straw's progress state.
*/
NuError
Nu_StrawSetProgressState(NuStraw* pStraw, NuProgressState state)
NuError Nu_StrawSetProgressState(NuStraw* pStraw, NuProgressState state)
{
Assert(pStraw != nil);
Assert(pStraw->pProgress != nil);
Assert(pStraw != NULL);
Assert(pStraw->pProgress != NULL);
pStraw->pProgress->state = state;
@ -832,20 +813,19 @@ Nu_StrawSetProgressState(NuStraw* pStraw, NuProgressState state)
/*
* Send a progress update to the application, if they're interested.
*/
NuError
Nu_StrawSendProgressUpdate(NuArchive* pArchive, NuStraw* pStraw)
NuError Nu_StrawSendProgressUpdate(NuArchive* pArchive, NuStraw* pStraw)
{
NuProgressData* pProgress;
Assert(pArchive != nil);
Assert(pStraw != nil);
Assert(pArchive != NULL);
Assert(pStraw != NULL);
pProgress = pStraw->pProgress;
if (pProgress == nil)
if (pProgress == NULL)
return kNuErrNone; /* no progress meter attached */
/* don't continue if they're not accepting progress messages */
if (pProgress->progressFunc == nil)
if (pProgress->progressFunc == NULL)
return kNuErrNone;
/* other than the choice of arguments, it's pretty much the same story */
@ -856,14 +836,14 @@ Nu_StrawSendProgressUpdate(NuArchive* pArchive, NuStraw* pStraw)
/*
* Read data from a straw.
*/
NuError
Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uchar* buffer, long len)
NuError Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uint8_t* buffer,
long len)
{
NuError err;
Assert(pArchive != nil);
Assert(pStraw != nil);
Assert(buffer != nil);
Assert(pArchive != NULL);
Assert(pStraw != NULL);
Assert(buffer != NULL);
Assert(len > 0);
/*
@ -887,7 +867,7 @@ Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uchar* buffer, long len)
* on the previous call. (This assumes that whatever they asked for
* last time has already been fully processed.)
*/
if (pStraw->pProgress != nil) {
if (pStraw->pProgress != NULL) {
pStraw->pProgress->uncompressedProgress = pStraw->lastProgress;
pStraw->lastProgress += len;
@ -911,11 +891,10 @@ bail:
* Rewind a straw. This rewinds the underlying data source, and resets
* some progress counters.
*/
NuError
Nu_StrawRewind(NuArchive* pArchive, NuStraw* pStraw)
NuError Nu_StrawRewind(NuArchive* pArchive, NuStraw* pStraw)
{
Assert(pStraw != nil);
Assert(pStraw->pDataSource != nil);
Assert(pStraw != NULL);
Assert(pStraw->pDataSource != NULL);
pStraw->lastProgress = 0;
pStraw->lastDisplayed = 0;

View File

@ -25,10 +25,10 @@
/*
* Selected definitions from compress.h.
*/
typedef unsigned short CODE;
typedef unsigned char UCHAR;
typedef unsigned int INTCODE;
typedef unsigned int HASH;
typedef uint16_t CODE;
typedef uint8_t UCHAR;
typedef uint32_t INTCODE;
typedef uint32_t HASH;
typedef int FLAG;
#ifndef FALSE /* let's get some sense to this */
@ -80,7 +80,7 @@ static UCHAR gNu_magic_header[] = { 0x1F,0x9D };
* Normally in COMPUSI.UNI.
*/
static inline ALLOCTYPE FAR *
Nu_LZC_emalloc(NuArchive* pArchive, unsigned int x, int y)
Nu_LZC_emalloc(NuArchive* pArchive, uint32_t x, int y)
{
return Nu_Malloc(pArchive, x*y);
}
@ -153,7 +153,7 @@ Nu_LZC_efree(NuArchive* pArchive, ALLOCTYPE FAR * ptr)
typedef struct LZCState {
NuArchive* pArchive;
int doCalcCRC;
ushort crc;
uint16_t crc;
/* compression */
NuStraw* pStraw;
@ -163,7 +163,7 @@ typedef struct LZCState {
/* expansion */
FILE* infp;
NuFunnel* pFunnel;
ushort* pCrc;
uint16_t* pCrc;
long compRemaining;
@ -251,18 +251,18 @@ static CONST INTCODE gNu_mc[] = {
#ifdef __STDC__
#ifdef DEBUG_LZC
#define allocx(type, ptr, size) \
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (unsigned int)(size),sizeof(type))) == NULLPTR(type) \
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (uint32_t)(size),sizeof(type))) == NULLPTR(type) \
? (DBUG(("%s: "#ptr" -- ", "LZC")), NOMEM) : OK \
)
#else
#define allocx(type,ptr,size) \
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (unsigned int)(size),sizeof(type))) == NULLPTR(type) \
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (uint32_t)(size),sizeof(type))) == NULLPTR(type) \
? NOMEM : OK \
)
#endif
#else
#define allocx(type,ptr,size) \
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (unsigned int)(size),sizeof(type))) == NULLPTR(type) \
(((ptr) = (type FAR *) Nu_LZC_emalloc(pArchive, (uint32_t)(size),sizeof(type))) == NULLPTR(type) \
? NOMEM : OK \
)
#endif
@ -300,8 +300,8 @@ static CONST INTCODE gNu_mc[] = {
#endif
static int
Nu_LZC_alloc_tables(LZCState* pLzcState, INTCODE newmaxcode, HASH newhashsize)
static int Nu_LZC_alloc_tables(LZCState* pLzcState, INTCODE newmaxcode,
HASH newhashsize)
{
NuArchive* pArchive = pLzcState->pArchive;
/*static INTCODE oldmaxcode = 0;*/
@ -421,8 +421,7 @@ Nu_LZC_alloc_tables(LZCState* pLzcState, INTCODE newmaxcode, HASH newhashsize)
* ===========================================================================
*/
static void
Nu_prratio(long int num, long int den)
static void Nu_prratio(long int num, long int den)
{
register int q; /* Doesn't need to be long */
@ -443,8 +442,7 @@ Nu_prratio(long int num, long int den)
/* table clear for block compress */
/* this is for adaptive reset present in version 4.0 joe release */
/* DjG, sets it up and returns TRUE to compress and FALSE to not compress */
static int
Nu_LZC_cl_block(LZCState* pLzcState)
static int Nu_LZC_cl_block(LZCState* pLzcState)
{
register long int rat;
@ -486,8 +484,7 @@ Nu_LZC_cl_block(LZCState* pLzcState)
static CONST UCHAR gNu_rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
static void
Nu_LZC_putcode(LZCState* pLzcState, INTCODE code, register int bits)
static void Nu_LZC_putcode(LZCState* pLzcState, INTCODE code, register int bits)
{
/*static int oldbits = 0;*/
/*static UCHAR outbuf[MAXBITS];*/
@ -554,11 +551,10 @@ Nu_LZC_putcode(LZCState* pLzcState, INTCODE code, register int bits)
*
* Returns kNuLZCEOF as the value when we're out of data.
*/
static NuError
Nu_LZCGetcCRC(LZCState* pLzcState, int* pSym)
static NuError Nu_LZCGetcCRC(LZCState* pLzcState, int* pSym)
{
NuError err;
uchar c;
uint8_t c;
if (!pLzcState->uncompRemaining) {
*pSym = kNuLZCEOF;
@ -579,15 +575,14 @@ Nu_LZCGetcCRC(LZCState* pLzcState, int* pSym)
/*
* compress stdin to stdout
*/
static void
Nu_LZC_compress(LZCState* pLzcState, ulong* pDstLen)
static void Nu_LZC_compress(LZCState* pLzcState, uint32_t* pDstLen)
{
int c,adjbits;
register HASH hash;
register INTCODE code;
HASH hashf[256];
Assert(pLzcState->outfp != nil);
Assert(pLzcState->outfp != NULL);
pLzcState->maxcode = Maxcode(pLzcState->maxbits);
pLzcState->hashsize = Hashsize(pLzcState->maxbits);
@ -758,9 +753,8 @@ Nu_LZC_compress(LZCState* pLzcState, ulong* pDstLen)
/*
* NufxLib interface to LZC compression.
*/
static NuError
Nu_CompressLZC(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc, int maxbits)
static NuError Nu_CompressLZC(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc, int maxbits)
{
NuError err = kNuErrNone;
LZCState lzcState;
@ -771,7 +765,7 @@ Nu_CompressLZC(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
lzcState.outfp = fp;
lzcState.uncompRemaining = srcLen;
if (pCrc == nil) {
if (pCrc == NULL) {
lzcState.doCalcCRC = false;
} else {
lzcState.doCalcCRC = true;
@ -800,22 +794,20 @@ Nu_CompressLZC(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
#endif
free_array(char,lzcState.sfx, 256);
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = lzcState.crc;
return err;
}
NuError
Nu_CompressLZC12(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc)
NuError Nu_CompressLZC12(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
{
return Nu_CompressLZC(pArchive, pStraw, fp, srcLen, pDstLen, pCrc, 12);
}
NuError
Nu_CompressLZC16(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc)
NuError Nu_CompressLZC16(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
{
return Nu_CompressLZC(pArchive, pStraw, fp, srcLen, pDstLen, pCrc, 16);
}
@ -833,22 +825,20 @@ Nu_CompressLZC16(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
*
* Returns kNuLZCEOF as the value when we're out of data.
*/
static NuError
Nu_LZCPutcCRC(LZCState* pLzcState, char c)
static NuError Nu_LZCPutcCRC(LZCState* pLzcState, char c)
{
NuError err;
err = Nu_FunnelWrite(pLzcState->pArchive, pLzcState->pFunnel,
(uchar*) &c, 1);
(uint8_t*) &c, 1);
if (pLzcState->doCalcCRC)
pLzcState->crc = Nu_CalcCRC16(pLzcState->crc, (uchar*) &c, 1);
pLzcState->crc = Nu_CalcCRC16(pLzcState->crc, (uint8_t*) &c, 1);
return err;
}
static int
Nu_LZC_nextcode(LZCState* pLzcState, INTCODE* codeptr)
static int Nu_LZC_nextcode(LZCState* pLzcState, INTCODE* codeptr)
/* Get the next code from input and put it in *codeptr.
* Return (TRUE) on success, or return (FALSE) on end-of-file.
* Adapted from COMPRESS V4.0.
@ -898,8 +888,7 @@ Nu_LZC_nextcode(LZCState* pLzcState, INTCODE* codeptr)
return (TRUE);
}
static void
Nu_LZC_decompress(LZCState* pLzcState, ulong compressedLen)
static void Nu_LZC_decompress(LZCState* pLzcState, uint32_t compressedLen)
{
NuArchive* pArchive = pLzcState->pArchive;
register int i;
@ -911,7 +900,7 @@ Nu_LZC_decompress(LZCState* pLzcState, ulong compressedLen)
/*static*/ int maxtoklen = MAXTOKLEN;
int flags;
Assert(pLzcState->infp != nil);
Assert(pLzcState->infp != NULL);
pLzcState->exit_stat = OK;
@ -1060,9 +1049,8 @@ Nu_LZC_decompress(LZCState* pLzcState, ulong compressedLen)
/*
* NufxLib interface to LZC expansion.
*/
NuError
Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
NuError Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc)
{
NuError err = kNuErrNone;
LZCState lzcState;
@ -1072,7 +1060,7 @@ Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
lzcState.infp = infp;
lzcState.pFunnel = pFunnel;
if (pCrc == nil) {
if (pCrc == NULL) {
lzcState.doCalcCRC = false;
} else {
lzcState.doCalcCRC = true;
@ -1098,7 +1086,7 @@ Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
#endif
free_array(char,lzcState.sfx, 256);
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = lzcState.crc;
return err;
}

View File

@ -119,17 +119,17 @@ static const int gNuBitMask[] = {
typedef struct LZWCompressState {
NuArchive* pArchive;
ushort entry[kNuLZWHashSize]; /* uint or ushort */
ushort prefix[kNuLZWMaxCode+1]; /* uint or ushort */
uchar suffix[kNuLZWMaxCode+1];
uint16_t entry[kNuLZWHashSize]; /* uint or ushort */
uint16_t prefix[kNuLZWMaxCode+1]; /* uint or ushort */
uint8_t suffix[kNuLZWMaxCode+1];
ushort hashFunc[kNuLZWHashFuncTblSize]; /* uint or ushort */
uint16_t hashFunc[kNuLZWHashFuncTblSize]; /* uint or ushort */
uchar inputBuf[kNuLZWBlockSize]; /* 4K of raw input */
uchar rleBuf[kNuLZWBlockSize*2 + kNuSafetyPadding];
uchar lzwBuf[(kNuLZWBlockSize * 3) / 2 + kNuSafetyPadding];
uint8_t inputBuf[kNuLZWBlockSize]; /* 4K of raw input */
uint8_t rleBuf[kNuLZWBlockSize*2 + kNuSafetyPadding];
uint8_t lzwBuf[(kNuLZWBlockSize * 3) / 2 + kNuSafetyPadding];
ushort chunkCrc; /* CRC for LZW/1 */
uint16_t chunkCrc; /* CRC for LZW/1 */
/* LZW/2 state variables */
int nextFree;
@ -146,15 +146,14 @@ typedef struct LZWCompressState {
* the hash function. This way we don't have to re-create it for
* every file, or store it statically in the binary.
*/
static NuError
Nu_AllocLZWCompressState(NuArchive* pArchive)
static NuError Nu_AllocLZWCompressState(NuArchive* pArchive)
{
NuError err;
LZWCompressState* lzwState;
int ic;
Assert(pArchive != nil);
Assert(pArchive->lzwCompressState == nil);
Assert(pArchive != NULL);
Assert(pArchive->lzwCompressState == NULL);
/* allocate the general-purpose compression buffer, if needed */
err = Nu_AllocCompressionBufferIFN(pArchive);
@ -162,7 +161,7 @@ Nu_AllocLZWCompressState(NuArchive* pArchive)
return err;
pArchive->lzwCompressState = Nu_Malloc(pArchive, sizeof(LZWCompressState));
if (pArchive->lzwCompressState == nil)
if (pArchive->lzwCompressState == NULL)
return kNuErrMalloc;
/*
@ -191,13 +190,12 @@ Nu_AllocLZWCompressState(NuArchive* pArchive)
* The RLE format is "<delim> <char> <count>", where count is zero-based
* (i.e. for three bytes we encode "2", allowing us to express 1-256).
*/
static NuError
Nu_CompressBlockRLE(LZWCompressState* lzwState, int* pRLESize)
static NuError Nu_CompressBlockRLE(LZWCompressState* lzwState, int* pRLESize)
{
const uchar* inPtr = lzwState->inputBuf;
const uchar* endPtr = inPtr + kNuLZWBlockSize;
uchar* outPtr = lzwState->rleBuf;
uchar matchChar;
const uint8_t* inPtr = lzwState->inputBuf;
const uint8_t* endPtr = inPtr + kNuLZWBlockSize;
uint8_t* outPtr = lzwState->rleBuf;
uint8_t matchChar;
int matchCount;
while (inPtr < endPtr) {
@ -258,10 +256,9 @@ Nu_CompressBlockRLE(LZWCompressState* lzwState, int* pRLESize)
/*
* Clear the LZW table. Also resets the LZW/2 state.
*/
static void
Nu_ClearLZWTable(LZWCompressState* lzwState)
static void Nu_ClearLZWTable(LZWCompressState* lzwState)
{
Assert(lzwState != nil);
Assert(lzwState != NULL);
/*DBUG_LZW(("### clear table\n"));*/
@ -296,11 +293,11 @@ Nu_ClearLZWTable(LZWCompressState* lzwState)
*
* (Turning this into a macro might speed things up.)
*/
static inline void
Nu_LZWPutCode(uchar** pOutBuf, ulong prefixCode, int codeBits, int* pAtBit)
static inline void Nu_LZWPutCode(uint8_t** pOutBuf, uint32_t prefixCode,
int codeBits, int* pAtBit)
{
int atBit = *pAtBit;
uchar* outBuf = *pOutBuf;
uint8_t* outBuf = *pOutBuf;
/*DBUG_LZW(("### PUT: prefixCode=0x%04lx, codeBits=%d, atBit=%d\n",
prefixCode, codeBits, atBit));*/
@ -313,20 +310,20 @@ Nu_LZWPutCode(uchar** pOutBuf, ulong prefixCode, int codeBits, int* pAtBit)
/* merge it with the buffer contents (if necessary) and write lo bits */
outBuf--;
*outBuf = (uchar)((*outBuf & gNuBitMask[atBit]) | prefixCode);
*outBuf = (uint8_t)((*outBuf & gNuBitMask[atBit]) | prefixCode);
outBuf++;
} else {
/* nothing to merge with; write lo byte at next posn and advance */
*outBuf++ = (uchar)prefixCode;
*outBuf++ = (uint8_t)prefixCode;
}
/* codes are at least 9 bits, so we know we have to write one more */
*outBuf++ = (uchar)(prefixCode >> 8);
*outBuf++ = (uint8_t)(prefixCode >> 8);
/* in some cases, we may have to write yet another */
atBit += codeBits;
if (atBit > 16)
*outBuf++ = (uchar)(prefixCode >> 16);
*outBuf++ = (uint8_t)(prefixCode >> 16);
*pAtBit = atBit & 0x07;
*pOutBuf = outBuf;
@ -353,23 +350,22 @@ Nu_LZWPutCode(uchar** pOutBuf, ulong prefixCode, int codeBits, int* pAtBit)
* "resetFix" logic in the expansion functions. Code 0x0101 is essentially
* lost in this situation.
*/
static NuError
Nu_CompressLZWBlock(LZWCompressState* lzwState, const uchar* inputBuf,
int inputCount, int* pOutputCount)
static NuError Nu_CompressLZWBlock(LZWCompressState* lzwState,
const uint8_t* inputBuf, int inputCount, int* pOutputCount)
{
int nextFree, ic, atBit, codeBits;
int hash, hashDelta;
int prefixCode, code, highCode;
const uchar* inputEnd = inputBuf + inputCount;
const uint8_t* inputEnd = inputBuf + inputCount;
/* local copies of lzwState members, for speed */
const ushort* pHashFunc = lzwState->hashFunc;
ushort* pEntry = lzwState->entry;
ushort* pPrefix = lzwState->prefix;
uchar* pSuffix = lzwState->suffix;
uchar* outBuf = lzwState->lzwBuf;
const uint16_t* pHashFunc = lzwState->hashFunc;
uint16_t* pEntry = lzwState->entry;
uint16_t* pPrefix = lzwState->prefix;
uint8_t* pSuffix = lzwState->suffix;
uint8_t* outBuf = lzwState->lzwBuf;
Assert(lzwState != nil);
Assert(inputBuf != nil);
Assert(lzwState != NULL);
Assert(inputBuf != NULL);
Assert(inputCount > 0 && inputCount <= kNuLZWBlockSize);
/* make sure nobody has been messing with the types */
Assert(sizeof(pHashFunc[0]) == sizeof(lzwState->hashFunc[0]));
@ -555,35 +551,34 @@ Nu_CompressLZWBlock(LZWCompressState* lzwState, const uchar* inputBuf,
*
* On exit, the output file will be positioned past the last byte written.
*/
static NuError
Nu_CompressLZW(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pThreadCrc, Boolean isType2)
static NuError Nu_CompressLZW(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pThreadCrc, Boolean isType2)
{
NuError err = kNuErrNone;
LZWCompressState* lzwState;
long initialOffset;
const uchar* lzwInputBuf;
uint blockSize, rleSize, lzwSize;
const uint8_t* lzwInputBuf;
uint32_t blockSize, rleSize, lzwSize;
long compressedLen;
Boolean keepLzw;
Assert(pArchive != nil);
Assert(pStraw != nil);
Assert(fp != nil);
Assert(pArchive != NULL);
Assert(pStraw != NULL);
Assert(fp != NULL);
Assert(srcLen > 0);
Assert(pDstLen != nil);
Assert(pThreadCrc != nil);
Assert(pDstLen != NULL);
Assert(pThreadCrc != NULL);
Assert(isType2 == true || isType2 == false);
/*
* Do some initialization and set-up.
*/
if (pArchive->lzwCompressState == nil) {
if (pArchive->lzwCompressState == NULL) {
err = Nu_AllocLZWCompressState(pArchive);
BailError(err);
}
Assert(pArchive->lzwCompressState != nil);
Assert(pArchive->compBuf != nil);
Assert(pArchive->lzwCompressState != NULL);
Assert(pArchive->compBuf != NULL);
lzwState = pArchive->lzwCompressState;
lzwState->pArchive = pArchive;
@ -782,9 +777,8 @@ bail:
/*
* Compress ShrinkIt-style "LZW/1".
*/
NuError
Nu_CompressLZW1(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc)
NuError Nu_CompressLZW1(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
{
return Nu_CompressLZW(pArchive, pStraw, fp, srcLen, pDstLen, pCrc, false);
}
@ -792,9 +786,8 @@ Nu_CompressLZW1(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
/*
* Compress ShrinkIt-style "LZW/2".
*/
NuError
Nu_CompressLZW2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc)
NuError Nu_CompressLZW2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
{
return Nu_CompressLZW(pArchive, pStraw, fp, srcLen, pDstLen, pCrc, true);
}
@ -813,21 +806,21 @@ Nu_CompressLZW2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
/*
* Static tables useful for bit manipulation.
*/
static const uint gNuMaskTable[17] = {
static const uint32_t gNuMaskTable[17] = {
0x0000, 0x01ff, 0x03ff, 0x03ff, 0x07ff, 0x07ff, 0x07ff, 0x07ff,
0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
0x0fff
};
/* convert high byte of "entry" into a bit width */
static const uint gNuBitWidth[17] = {
static const uint32_t gNuBitWidth[17] = {
8,9,10,10,11,11,11,11,12,12,12,12,12,12,12,12,12
};
/* entry in the trie */
typedef struct TableEntry {
uchar ch;
uint prefix;
uint8_t ch;
uint32_t prefix;
} TableEntry;
/*
@ -839,38 +832,38 @@ typedef struct LZWExpandState {
NuArchive* pArchive;
TableEntry trie[4096-256]; /* holds from 9 bits to 12 bits */
uchar stack[kNuLZWBlockSize];
uint8_t stack[kNuLZWBlockSize];
uint entry; /* 16-bit index into table */
uint oldcode; /* carryover state for LZW/2 */
uint incode; /* carryover state for LZW/2 */
uint finalc; /* carryover state for LZW/2 */
// some of these don't need to be 32 bits; they were "uint" before
uint32_t entry; /* 16-bit index into table */
uint32_t oldcode; /* carryover state for LZW/2 */
uint32_t incode; /* carryover state for LZW/2 */
uint32_t finalc; /* carryover state for LZW/2 */
Boolean resetFix; /* work around an LZW/2 bug */
ushort chunkCrc; /* CRC we calculate for LZW/1 */
ushort fileCrc; /* CRC stored with file */
uint16_t chunkCrc; /* CRC we calculate for LZW/1 */
uint16_t fileCrc; /* CRC stored with file */
uchar diskVol; /* disk volume # */
uchar rleEscape; /* RLE escape char, usually 0xdb */
uint8_t diskVol; /* disk volume # */
uint8_t rleEscape; /* RLE escape char, usually 0xdb */
ulong dataInBuffer; /* #of bytes in compBuf */
uchar* dataPtr; /* current data offset */
uint32_t dataInBuffer; /* #of bytes in compBuf */
uint8_t* dataPtr; /* current data offset */
uchar lzwOutBuf[kNuLZWBlockSize + kNuSafetyPadding];
uchar rleOutBuf[kNuLZWBlockSize + kNuSafetyPadding];
uint8_t lzwOutBuf[kNuLZWBlockSize + kNuSafetyPadding];
uint8_t rleOutBuf[kNuLZWBlockSize + kNuSafetyPadding];
} LZWExpandState;
/*
* Allocate some "reusable" state for LZW expansion.
*/
static NuError
Nu_AllocLZWExpandState(NuArchive* pArchive)
static NuError Nu_AllocLZWExpandState(NuArchive* pArchive)
{
NuError err;
Assert(pArchive != nil);
Assert(pArchive->lzwExpandState == nil);
Assert(pArchive != NULL);
Assert(pArchive->lzwExpandState == NULL);
/* allocate the general-purpose compression buffer, if needed */
err = Nu_AllocCompressionBufferIFN(pArchive);
@ -878,7 +871,7 @@ Nu_AllocLZWExpandState(NuArchive* pArchive)
return err;
pArchive->lzwExpandState = Nu_Malloc(pArchive, sizeof(LZWExpandState));
if (pArchive->lzwExpandState == nil)
if (pArchive->lzwExpandState == NULL)
return kNuErrMalloc;
return kNuErrNone;
}
@ -896,8 +889,8 @@ Nu_AllocLZWExpandState(NuArchive* pArchive)
( Nu_LZWPopCheck(lzwState, stackPtr), *(--stackPtr) )
# define Nu_LZWStackEmpty() ( stackPtr == lzwState->stack )
static inline void
Nu_LZWPushCheck(uchar uch, const LZWExpandState* lzwState,const uchar* stackPtr)
static inline void Nu_LZWPushCheck(uint8_t uch, const LZWExpandState* lzwState,
const uint8_t* stackPtr)
{
if (stackPtr >= lzwState->stack + sizeof(lzwState->stack)) {
Nu_ReportError(lzwState->NU_BLOB, kNuErrBadData, "stack overflow");
@ -905,8 +898,8 @@ Nu_LZWPushCheck(uchar uch, const LZWExpandState* lzwState,const uchar* stackPtr)
}
}
static inline void
Nu_LZWPopCheck(const LZWExpandState* lzwState, const uchar* stackPtr)
static inline void Nu_LZWPopCheck(const LZWExpandState* lzwState,
const uint8_t* stackPtr)
{
if (stackPtr == lzwState->stack) {
Nu_ReportError(lzwState->NU_BLOB, kNuErrBadData, "stack underflow");
@ -927,13 +920,11 @@ Nu_LZWPopCheck(const LZWExpandState* lzwState, const uchar* stackPtr)
*
* (Turning this into a macro might speed things up.)
*/
static inline uint
Nu_LZWGetCode(const uchar** pInBuf, uint entry, int* pAtBit, uint* pLastByte)
static inline uint32_t Nu_LZWGetCode(const uint8_t** pInBuf, uint32_t entry,
int* pAtBit, uint32_t* pLastByte)
{
uint numBits, startBit, lastBit;
ulong value;
Assert(sizeof(uint) >= 2);
uint32_t numBits, startBit, lastBit;
uint32_t value;
numBits = (entry +1) >> 8; /* bit-width of next code */
startBit = *pAtBit;
@ -952,7 +943,7 @@ Nu_LZWGetCode(const uchar** pInBuf, uint entry, int* pAtBit, uint* pLastByte)
/* need two more bytes */
value |= *(*pInBuf)++ << 8;
*pLastByte = *(*pInBuf)++;
value |= (ulong) *pLastByte << 16;
value |= (uint32_t) *pLastByte << 16;
} else {
/* only need one more byte */
*pLastByte = *(*pInBuf)++;
@ -977,20 +968,19 @@ Nu_LZWGetCode(const uchar** pInBuf, uint entry, int* pAtBit, uint* pLastByte)
*
* Reads from lzwState->dataPtr, writes to lzwState->lzwOutBuf.
*/
static NuError
Nu_ExpandLZW1(LZWExpandState* lzwState, uint expectedLen)
static NuError Nu_ExpandLZW1(LZWExpandState* lzwState, uint32_t expectedLen)
{
NuError err = kNuErrNone;
TableEntry* tablePtr;
int atBit;
uint entry, oldcode, incode, ptr;
uint lastByte, finalc;
const uchar* inbuf;
uchar* outbuf;
uchar* outbufend;
uchar* stackPtr;
uint32_t entry, oldcode, incode, ptr;
uint32_t lastByte, finalc;
const uint8_t* inbuf;
uint8_t* outbuf;
uint8_t* outbufend;
uint8_t* stackPtr;
Assert(lzwState != nil);
Assert(lzwState != NULL);
Assert(expectedLen > 0 && expectedLen <= kNuLZWBlockSize);
inbuf = lzwState->dataPtr;
@ -1024,7 +1014,7 @@ Nu_ExpandLZW1(LZWExpandState* lzwState, uint expectedLen)
err = kNuErrBadData;
return err;
}
Nu_LZWPush((uchar)finalc);
Nu_LZWPush((uint8_t)finalc);
ptr = oldcode;
}
@ -1062,7 +1052,7 @@ bail:
/* adjust input buffer */
lzwState->dataInBuffer -= (inbuf - lzwState->dataPtr);
Assert(lzwState->dataInBuffer < 32767*65536);
lzwState->dataPtr = (uchar*)inbuf;
lzwState->dataPtr = (uint8_t*)inbuf;
return err;
}
@ -1077,24 +1067,23 @@ bail:
* In some cases, "expectedInputUsed" will be -1 to indicate that the
* value is not known.
*/
static NuError
Nu_ExpandLZW2(LZWExpandState* lzwState, uint expectedLen,
uint expectedInputUsed)
static NuError Nu_ExpandLZW2(LZWExpandState* lzwState, uint32_t expectedLen,
uint32_t expectedInputUsed)
{
NuError err = kNuErrNone;
TableEntry* tablePtr;
int atBit;
uint entry, oldcode, incode, ptr;
uint lastByte, finalc;
const uchar* inbuf;
const uchar* inbufend;
uchar* outbuf;
uchar* outbufend;
uchar* stackPtr;
uint32_t entry, oldcode, incode, ptr;
uint32_t lastByte, finalc;
const uint8_t* inbuf;
const uint8_t* inbufend;
uint8_t* outbuf;
uint8_t* outbufend;
uint8_t* stackPtr;
/*DBUG_LZW(("### LZW/2 block start (compIn=%d, rleOut=%d, entry=0x%04x)\n",
expectedInputUsed, expectedLen, lzwState->entry));*/
Assert(lzwState != nil);
Assert(lzwState != NULL);
Assert(expectedLen > 0 && expectedLen <= kNuLZWBlockSize);
inbuf = lzwState->dataPtr;
@ -1171,7 +1160,7 @@ main_loop:
err = kNuErrBadData;
return err;
}
Nu_LZWPush((uchar)finalc);
Nu_LZWPush((uint8_t)finalc);
ptr = oldcode;
}
@ -1203,7 +1192,7 @@ main_loop:
bail:
/*DBUG_LZW(("### end of block\n"));*/
if (expectedInputUsed != (unsigned int) -1 && inbuf != inbufend) {
if (expectedInputUsed != (uint32_t) -1 && inbuf != inbufend) {
/* data was corrupted; if we keep going this will get worse */
DBUG(("--- inbuf != inbufend in ExpandLZW2 (diff=%d)\n",
inbufend - inbuf));
@ -1215,7 +1204,7 @@ bail:
/* adjust input buffer */
lzwState->dataInBuffer -= (inbuf - lzwState->dataPtr);
Assert(lzwState->dataInBuffer < 32767*65536);
lzwState->dataPtr = (uchar*)inbuf;
lzwState->dataPtr = (uint8_t*)inbuf;
/* save off local copies of stuff */
lzwState->entry = entry;
@ -1230,15 +1219,14 @@ bail:
/*
* Expands a chunk of RLEd data into 4K of output.
*/
static NuError
Nu_ExpandRLE(LZWExpandState* lzwState, const uchar* inbuf,
uint expectedInputUsed)
static NuError Nu_ExpandRLE(LZWExpandState* lzwState, const uint8_t* inbuf,
uint32_t expectedInputUsed)
{
NuError err = kNuErrNone;
uchar *outbuf;
uchar *outbufend;
const uchar *inbufend;
uchar uch, rleEscape;
uint8_t *outbuf;
uint8_t *outbufend;
const uint8_t *inbufend;
uint8_t uch, rleEscape;
int count;
outbuf = lzwState->rleOutBuf;
@ -1284,8 +1272,7 @@ bail:
/*
* Utility function to get a byte from the input buffer.
*/
static inline uchar
Nu_GetHeaderByte(LZWExpandState* lzwState)
static inline uint8_t Nu_GetHeaderByte(LZWExpandState* lzwState)
{
lzwState->dataInBuffer--;
Assert(lzwState->dataInBuffer > 0);
@ -1298,33 +1285,33 @@ Nu_GetHeaderByte(LZWExpandState* lzwState)
* This manages the input data buffer, passing chunks of compressed data
* into the appropriate expansion function.
*
* Pass in nil for "pThreadCrc" if no thread CRC is desired. Otherwise,
* Pass in NULL for "pThreadCrc" if no thread CRC is desired. Otherwise,
* "*pThreadCrc" should already be set to its initial value. On exit it
* will contain the CRC of the uncompressed data.
*/
NuError
Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pThreadCrc)
NuError Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel,
uint16_t* pThreadCrc)
{
NuError err = kNuErrNone;
Boolean isType2;
LZWExpandState* lzwState;
ulong compRemaining, uncompRemaining, minSize;
uint32_t compRemaining, uncompRemaining, minSize;
Assert(pArchive != nil);
Assert(pThread != nil);
Assert(infp != nil);
Assert(pFunnel != nil);
Assert(pArchive != NULL);
Assert(pThread != NULL);
Assert(infp != NULL);
Assert(pFunnel != NULL);
/*
* Do some initialization and set-up.
*/
if (pArchive->lzwExpandState == nil) {
if (pArchive->lzwExpandState == NULL) {
err = Nu_AllocLZWExpandState(pArchive);
BailError(err);
}
Assert(pArchive->lzwExpandState != nil);
Assert(pArchive->compBuf != nil);
Assert(pArchive->lzwExpandState != NULL);
Assert(pArchive->compBuf != NULL);
lzwState = pArchive->lzwExpandState;
lzwState->pArchive = pArchive;
@ -1368,7 +1355,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
compRemaining -= 2;
lzwState->dataInBuffer = 0;
lzwState->dataPtr = nil;
lzwState->dataPtr = NULL;
/* reset pointers */
lzwState->entry = kNuLZWFirstCode; /* 0x0101 */
@ -1396,11 +1383,11 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
while (uncompRemaining) {
Boolean rleUsed;
Boolean lzwUsed;
ulong getSize;
uint rleLen; /* length after RLE; 4096 if no RLE */
uint lzwLen = 0; /* type 2 only */
uint writeLen, inCount;
const uchar* writeBuf;
uint32_t getSize;
uint32_t rleLen; /* length after RLE; 4096 if no RLE */
uint32_t lzwLen = 0; /* type 2 only */
uint32_t writeLen, inCount;
const uint8_t* writeBuf;
/* if we're low, and there's more data available, read more */
if (lzwState->dataInBuffer < kNuLZWDesiredChunk && compRemaining) {
@ -1409,7 +1396,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
* the buffer.
*/
if (lzwState->dataInBuffer) {
Assert(lzwState->dataPtr != nil);
Assert(lzwState->dataPtr != NULL);
Assert(pArchive->compBuf != lzwState->dataPtr);
memmove(pArchive->compBuf, lzwState->dataPtr,
lzwState->dataInBuffer);
@ -1429,7 +1416,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
getSize);
if (err != kNuErrNone) {
Nu_ReportError(NU_BLOB, err,
"failed reading compressed data (%ld bytes)", getSize);
"failed reading compressed data (%u bytes)", getSize);
goto bail;
}
lzwState->dataInBuffer += getSize;
@ -1476,7 +1463,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
writeLen = kNuLZWBlockSize;
#ifndef NDEBUG
writeBuf = nil;
writeBuf = NULL;
#endif
/*
@ -1491,7 +1478,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
} else {
if (pRecord->isBadMac || pArchive->valIgnoreLZW2Len) {
/* might be big-endian, might be okay; just ignore it */
lzwLen = (unsigned int) -1;
lzwLen = (uint32_t) -1;
} else if (lzwState->dataInBuffer < lzwLen) {
/* rare -- GSHK will do this if you don't let it finish */
err = kNuErrBufferUnderrun;
@ -1537,7 +1524,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
lzwState->resetFix = false;
}
Assert(writeBuf != nil);
Assert(writeBuf != NULL);
/*
* Compute the CRC of the uncompressed data, and write it. For
@ -1547,7 +1534,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
* See commentary in the compression code for why we have to
* compute two CRCs for LZW/1.
*/
if (pThreadCrc != nil) {
if (pThreadCrc != NULL) {
*pThreadCrc = Nu_CalcCRC16(*pThreadCrc, writeBuf, writeLen);
}
if (!isType2) {
@ -1590,7 +1577,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
DBUG(("--- Found %ld bytes following compressed data (compRem=%ld)\n",
lzwState->dataInBuffer, compRemaining));
if (lzwState->dataInBuffer > 32) {
Nu_ReportError(NU_BLOB, kNuErrNone, "(Warning) lots of fluff (%ld)",
Nu_ReportError(NU_BLOB, kNuErrNone, "(Warning) lots of fluff (%u)",
lzwState->dataInBuffer);
}
}
@ -1602,7 +1589,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
if (compRemaining) {
err = kNuErrBadData;
Nu_ReportError(NU_BLOB, err,
"not all compressed data was used (%ld/%ld)",
"not all compressed data was used (%u/%u)",
compRemaining, lzwState->dataInBuffer);
goto bail;
}

View File

@ -12,6 +12,9 @@
#
# The shared library support currently leaves much to be desired.
#
# If you build with -DDEBUG_MSGS, nulib2 will be able to use the hidden
# 'g' command, which generates a verbose archive dump for debugging.
#
# NufxLib install location.
prefix = @prefix@
@ -31,14 +34,14 @@ OPT = @CFLAGS@
#OPT = @CFLAGS@ -DDEBUG_MSGS
#OPT = @CFLAGS@ -DDEBUG_VERBOSE
GCC_FLAGS = -Wall -Wwrite-strings -Wstrict-prototypes -Wpointer-arith -Wshadow
CFLAGS = @BUILD_FLAGS@ -I. @DEFS@ -DOPTFLAGSTR="\"$(OPT)\""
CFLAGS = @BUILD_FLAGS@ -I. @DEFS@ -fPIC -DOPTFLAGSTR="\"$(OPT)\""
SRCS = Archive.c ArchiveIO.c Bzip2.c Compress.c Crc16.c Debug.c \
Deferred.c Deflate.c Entry.c Expand.c FileIO.c Funnel.c \
SRCS = Archive.c ArchiveIO.c Bzip2.c Charset.c Compress.c Crc16.c \
Debug.c Deferred.c Deflate.c Entry.c Expand.c FileIO.c Funnel.c \
Lzc.c Lzw.c MiscStuff.c MiscUtils.c Record.c SourceSink.c \
Squeeze.c Thread.c Value.c Version.c
OBJS = Archive.o ArchiveIO.o Bzip2.o Compress.o Crc16.o Debug.o \
Deferred.o Deflate.o Entry.o Expand.o FileIO.o Funnel.o \
OBJS = Archive.o ArchiveIO.o Bzip2.o Charset.o Compress.o Crc16.o \
Debug.o Deferred.o Deflate.o Entry.o Expand.o FileIO.o Funnel.o \
Lzc.o Lzw.o MiscStuff.o MiscUtils.o Record.o SourceSink.o \
Squeeze.o Thread.o Value.o Version.o
@ -57,16 +60,18 @@ all: $(PRODUCT) samples
install: $(STATIC_PRODUCT)
$(srcdir)/mkinstalldirs $(libdir)
$(INSTALL_DATA) $(STATIC_PRODUCT) $(libdir)
$(srcdir)/mkinstalldirs $(includedir)
$(srcdir)/mkinstalldirs $(includedir) $(libdir)/pkgconfig
$(INSTALL_DATA) NufxLib.h $(includedir)
$(INSTALL_DATA) nufxlib.pc $(libdir)/pkgconfig
install-shared: $(SHARED_PRODUCT)
$(srcdir)/mkinstalldirs $(libdir)
$(INSTALL_DATA) $(SHARED_PRODUCT) $(libdir)
$(srcdir)/mkinstalldirs $(includedir)
$(srcdir)/mkinstalldirs $(includedir) $(libdir)/pkgconfig
$(INSTALL_DATA) NufxLib.h $(includedir)
$(INSTALL_DATA) nufxlib.pc $(libdir)/pkgconfig
samples::
samples:: $(STATIC_PRODUCT)
@echo "Building samples..."
@(cd samples; set +e; unset CFLAGS OBJS; set -e; \
@SET_MAKE@ LIB_PRODUCT="../$(PRODUCT)" $(MAKE))
@ -79,7 +84,7 @@ $(STATIC_PRODUCT): $(OBJS)
$(AR) $@ $(OBJS)
@RANLIB@ $@
# BUG: we probably want -fPIC -D_REENTRANT on the compile lines for this.
# BUG: we need -fPIC, maybe -D_REENTRANT when compiling for this.
# BUG: for Linux we may want -Wl,-soname,libnufx.so.1 on the link line.
$(SHARED_PRODUCT): $(OBJS)
-rm -f $(STATIC_PRODUCT) $(SHARED_PRODUCT)
@ -97,7 +102,6 @@ tags::
distclean: clean
(cd samples; make distclean)
-rm -f Version.c
-rm -f Makefile Makefile.bak
-rm -f config.log config.cache config.status config.h
-rm -f tags
@ -111,12 +115,29 @@ baktar:
@gzip -9 nufxlib.tar
@mv -i nufxlib.tar.gz /home/fadden/BAK/
depend:
makedepend -- $(CFLAGS) -I/usr/local/include -- $(SRCS)
@(cd samples; unset CFLAGS OBJS; @SET_MAKE@ $(MAKE) depend)
# catch OPTFLAGSTR updates
Version.o: Makefile
# DO NOT DELETE THIS LINE -- make depend depends on it.
# dependency info
COMMON_HDRS = NufxLibPriv.h NufxLib.h MiscStuff.h SysDefs.h
Archive.o: Archive.c $(COMMON_HDRS)
ArchiveIO.o: ArchiveIO.c $(COMMON_HDRS)
Bzip2.o: Bzip2.c $(COMMON_HDRS)
Charset.o: Charset.c $(COMMON_HDRS)
Compress.o: Compress.c $(COMMON_HDRS)
Crc16.o: Crc16.c $(COMMON_HDRS)
Debug.o: Debug.c $(COMMON_HDRS)
Deferred.o: Deferred.c $(COMMON_HDRS)
Deflate.o: Deflate.c $(COMMON_HDRS)
Entry.o: Entry.c $(COMMON_HDRS)
Expand.o: Expand.c $(COMMON_HDRS)
FileIO.o: FileIO.c $(COMMON_HDRS)
Funnel.o: Funnel.c $(COMMON_HDRS)
Lzc.o: Lzc.c $(COMMON_HDRS)
Lzw.o: Lzw.c $(COMMON_HDRS)
MiscStuff.o: MiscStuff.c $(COMMON_HDRS)
MiscUtils.o: MiscUtils.c $(COMMON_HDRS)
Record.o: Record.c $(COMMON_HDRS)
SourceSink.o: SourceSink.c $(COMMON_HDRS)
Squeeze.o: Squeeze.c $(COMMON_HDRS)
Thread.o: Thread.c $(COMMON_HDRS)
Value.o: Value.c $(COMMON_HDRS)
Version.o: Version.c $(COMMON_HDRS) Makefile

View File

@ -65,16 +65,16 @@ LDFLAGS = $(LDFLAGS) zlib.lib
# object files
OBJS = Archive.obj ArchiveIO.obj Bzip2.obj Compress.obj Crc16.obj Debug.obj \
Deferred.obj Deflate.obj Entry.obj Expand.obj FileIO.obj Funnel.obj \
Lzc.obj Lzw.obj MiscStuff.obj MiscUtils.obj Record.obj SourceSink.obj \
Squeeze.obj Thread.obj Value.obj Version.obj
OBJS = Archive.obj ArchiveIO.obj Bzip2.obj Charset.obj Compress.obj \
Crc16.obj Debug.obj Deferred.obj Deflate.obj Entry.obj Expand.obj \
FileIO.obj Funnel.obj Lzc.obj Lzw.obj MiscStuff.obj MiscUtils.obj \
Record.obj SourceSink.obj Squeeze.obj Thread.obj Value.obj Version.obj
# build targets -- static library, dynamic library, and test programs
all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
exerciser.exe imgconv.exe launder.exe test-basic.exe \
test-basic-d.exe test-extract.exe test-simple.exe test-twirl.exe
exerciser.exe imgconv.exe launder.exe test-basic.exe test-basic-d.exe \
test-extract.exe test-names.exe test-simple.exe test-twirl.exe
clean:
-del *.obj *.pdb *.exp
@ -107,6 +107,9 @@ test-basic-d.exe: TestBasic.obj $(IMPLIB)
test-extract.exe: TestExtract.obj $(STATICLIB)
$(LD) $(LDFLAGS) -out:$@ TestExtract.obj $(STATICLIB)
test-names.exe: TestNames.obj $(STATICLIB)
$(LD) $(LDFLAGS) -out:$@ TestNames.obj $(STATICLIB)
test-simple.exe: TestSimple.obj $(STATICLIB)
$(LD) $(LDFLAGS) -out:$@ TestSimple.obj $(STATICLIB)
@ -125,6 +128,7 @@ COMMON_HDRS = NufxLibPriv.h NufxLib.h MiscStuff.h SysDefs.h
Archive.obj: Archive.c $(COMMON_HDRS)
ArchiveIO.obj: ArchiveIO.c $(COMMON_HDRS)
Bzip2.obj: Bzip2.c $(COMMON_HDRS)
Charset.obj: Charset.c $(COMMON_HDRS)
Compress.obj: Compress.c $(COMMON_HDRS)
Crc16.obj: Crc16.c $(COMMON_HDRS)
Debug.obj: Debug.c $(COMMON_HDRS)
@ -150,6 +154,7 @@ ImgConv.obj: samples/ImgConv.c $(COMMON_HDRS)
Launder.obj: samples/Launder.c $(COMMON_HDRS)
TestBasic.obj: samples/TestBasic.c $(COMMON_HDRS)
TestExtract.obj: samples/TestExtract.c $(COMMON_HDRS)
TestNames.obj: samples/TestNames.c $(COMMON_HDRS)
TestSimple.obj: samples/TestSimple.c $(COMMON_HDRS)
TestTwirl.obj: samples/TestTwirl.c $(COMMON_HDRS)

View File

@ -16,8 +16,7 @@
* Return a pointer to the appropriate string in the system table, or NULL
* if the value is out of bounds.
*/
const char*
Nu_strerror(int errnum)
const char* Nu_strerror(int errnum)
{
extern int sys_nerr;
extern char *sys_errlist[];
@ -38,8 +37,7 @@ Nu_strerror(int errnum)
* from BSD, is available in the PGP 2.6.2 distribution, but this should
* suffice for those few systems that don't have memmove.
*/
void*
Nu_memmove(void* dst, const void* src, size_t n)
void* Nu_memmove(void* dst, const void* src, size_t n)
{
void* retval = dst;
char* srcp = (char*)src;
@ -80,8 +78,7 @@ Nu_memmove(void* dst, const void* src, size_t n)
* For our purposes here, strtol does all we need it to. Someday
* we should replace this with a "real" version.
*/
unsigned long
Nu_strtoul(const char *nptr, char **endptr, int base)
unsigned long Nu_strtoul(const char *nptr, char **endptr, int base)
{
return strtol(nptr, endptr, base);
}
@ -91,8 +88,7 @@ Nu_strtoul(const char *nptr, char **endptr, int base)
/*
* Compare two strings, case-insensitive.
*/
int
Nu_strcasecmp(const char *str1, const char *str2)
int Nu_strcasecmp(const char *str1, const char *str2)
{
while (*str1 && *str2 && toupper(*str1) == toupper(*str2))
str1++, str2++;
@ -105,8 +101,7 @@ Nu_strcasecmp(const char *str1, const char *str2)
/*
* Compare two strings, case-insensitive, stopping after "n" chars.
*/
int
Nu_strncasecmp(const char *str1, const char *str2, size_t n)
int Nu_strncasecmp(const char *str1, const char *str2, size_t n)
{
while (n && *str1 && *str2 && toupper(*str1) == toupper(*str2))
str1++, str2++, n--;

View File

@ -6,8 +6,8 @@
* Misc stuff (shared between nufxlib and nulib2). This is a collection
* of miscellaneous types and macros that I find generally useful.
*/
#ifndef __MiscStuff__
#define __MiscStuff__
#ifndef NUFXLIB_MISCSTUFF_H
#define NUFXLIB_MISCSTUFF_H
#define VALGRIND /* assume we're using it */
@ -42,11 +42,7 @@ int Nu_strncasecmp(const char *s1, const char *s2, size_t n);
* Misc types.
*/
#include <sys/types.h>
#define nil NULL /* I can't seem to stop typing 'nil' now */
typedef uchar Boolean;
typedef unsigned char Boolean;
#define false (0)
#define true (!false)
@ -63,7 +59,7 @@ typedef uchar Boolean;
(x) <= '9' ? (x) - '0' : toupper(x) +10 - 'A' )
/* convert number from 0-15 to hex digit */
#define HexConv(x) ( ((uint)(x)) <= 15 ? \
#define HexConv(x) ( ((unsigned int)(x)) <= 15 ? \
( (x) <= 9 ? (x) + '0' : (x) -10 + 'A') : -1 )
@ -106,4 +102,4 @@ typedef uchar Boolean;
#define kInvalidPtr ((void*)0xa3a3a3a3)
#endif /*__MiscStuff__*/
#endif /*NUFXLIB_MISCSTUFF_H*/

View File

@ -6,13 +6,12 @@
*
* Miscellaneous NufxLib utility functions.
*/
#define __MiscUtils_c__
#include "NufxLibPriv.h"
/*
* Big fat hairy global. Unfortunately this is unavoidable.
*/
NuCallback gNuGlobalErrorMessageHandler = nil;
NuCallback gNuGlobalErrorMessageHandler = NULL;
static const char* kNufxLibName = "nufxlib";
@ -21,8 +20,7 @@ static const char* kNufxLibName = "nufxlib";
/*
* strerror() equivalent for NufxLib errors.
*/
const char*
Nu_StrError(NuError err)
const char* Nu_StrError(NuError err)
{
/*
* BUG: this should be set up as per-thread storage in an MT environment.
@ -32,7 +30,7 @@ Nu_StrError(NuError err)
* to return this.
*
* An easier solution, should this present a problem for someone, would
* be to have the function return nil or "unknown error" when the
* be to have the function return NULL or "unknown error" when the
* error value isn't recognized. I'd recommend leaving it as-is for
* debug builds, though, as it's helpful to know *which* error is not
* recognized.
@ -200,15 +198,15 @@ Nu_StrError(NuError err)
* Similar to perror(), but takes the error as an argument, and knows
* about NufxLib errors as well as system errors.
*
* Depending on the compiler, "file", "line", and "function" may be nil/zero.
* Depending on the compiler, "file", "line", and "function" may be NULL/zero.
*
* Calling here with "pArchive"==nil is allowed, but should only be done
* Calling here with "pArchive"==NULL is allowed, but should only be done
* if the archive is inaccessible (perhaps because it failed to open). We
* can't invoke the error message callback if the pointer is nil.
* can't invoke the error message callback if the pointer is NULL.
*/
void
Nu_ReportError(NuArchive* pArchive, const char* file, int line,
const char* function, Boolean isDebug, NuError err, const char* format, ...)
void Nu_ReportError(NuArchive* pArchive, const char* file, int line,
const char* function, Boolean isDebug, NuError err,
const UNICHAR* format, ...)
{
NuErrorMessage errorMessage;
const char* msg;
@ -219,7 +217,7 @@ Nu_ReportError(NuArchive* pArchive, const char* file, int line,
int cc;
#endif
Assert(format != nil);
Assert(format != NULL);
va_start(args, format);
@ -247,28 +245,28 @@ Nu_ReportError(NuArchive* pArchive, const char* file, int line,
strcpy(buf+count, ": ");
count += 2;
msg = nil;
msg = NULL;
if (err >= 0)
msg = strerror(err);
if (msg == nil)
if (msg == NULL)
msg = Nu_StrError(err);
#if defined(HAVE_SNPRINTF) && defined(SNPRINTF_DECLARED)
if (msg == nil)
if (msg == NULL)
snprintf(buf+count, sizeof(buf) - count,
"(unknown err=%d)", err);
else
snprintf(buf+count, sizeof(buf) - count, "%s", msg);
#else
#ifdef SPRINTF_RETURNS_INT
if (msg == nil)
if (msg == NULL)
cc = sprintf(buf+count, "(unknown err=%d)", err);
else
cc = sprintf(buf+count, "%s", msg);
Assert(cc > 0);
count += cc;
#else
if (msg == nil)
if (msg == NULL)
sprintf(buf+count, "(unknown err=%d)", err);
else
sprintf(buf+count, "%s", msg);
@ -284,8 +282,8 @@ Nu_ReportError(NuArchive* pArchive, const char* file, int line,
Assert(count <= kNuHeftyBufSize);
#endif
if ((pArchive != nil && pArchive->messageHandlerFunc == nil) ||
(pArchive == nil && gNuGlobalErrorMessageHandler == nil))
if ((pArchive != NULL && pArchive->messageHandlerFunc == NULL) ||
(pArchive == NULL && gNuGlobalErrorMessageHandler == NULL))
{
if (isDebug) {
fprintf(stderr, "%s: [%s:%d %s] %s\n", kNufxLibName,
@ -301,7 +299,7 @@ Nu_ReportError(NuArchive* pArchive, const char* file, int line,
errorMessage.line = line;
errorMessage.function = function;
if (pArchive == nil)
if (pArchive == NULL)
(void) (*gNuGlobalErrorMessageHandler)(pArchive, &errorMessage);
else
(void) (*pArchive->messageHandlerFunc)(pArchive, &errorMessage);
@ -322,48 +320,46 @@ bail:
*/
#ifndef USE_DMALLOC
void*
Nu_Malloc(NuArchive* pArchive, size_t size)
void* Nu_Malloc(NuArchive* pArchive, size_t size)
{
void* _result;
Assert(size > 0);
_result = malloc(size);
if (_result == nil) {
Nu_ReportError(NU_BLOB, kNuErrMalloc, "malloc(%u) failed", (uint) size);
if (_result == NULL) {
Nu_ReportError(NU_BLOB, kNuErrMalloc,
"malloc(%u) failed", (unsigned int) size);
DebugAbort(); /* leave a core dump if we're built for it */
}
DebugFill(_result, size);
return _result;
}
void*
Nu_Calloc(NuArchive* pArchive, size_t size)
void* Nu_Calloc(NuArchive* pArchive, size_t size)
{
void* _cresult = Nu_Malloc(pArchive, size);
memset(_cresult, 0, size);
return _cresult;
}
void*
Nu_Realloc(NuArchive* pArchive, void* ptr, size_t size)
void* Nu_Realloc(NuArchive* pArchive, void* ptr, size_t size)
{
void* _result;
Assert(ptr != nil); /* disallow this usage */
Assert(ptr != NULL); /* disallow this usage */
Assert(size > 0); /* disallow this usage */
_result = realloc(ptr, size);
if (_result == nil) {
Nu_ReportError(NU_BLOB, kNuErrMalloc, "realloc(%u) failed",(uint) size);
if (_result == NULL) {
Nu_ReportError(NU_BLOB, kNuErrMalloc,
"realloc(%u) failed", (unsigned int) size);
DebugAbort(); /* leave a core dump if we're built for it */
}
return _result;
}
void
Nu_Free(NuArchive* pArchive, void* ptr)
void Nu_Free(NuArchive* pArchive, void* ptr)
{
if (ptr != nil)
if (ptr != NULL)
free(ptr);
}
#endif
@ -372,11 +368,10 @@ Nu_Free(NuArchive* pArchive, void* ptr)
* If somebody internal wants to set doClose on a buffer DataSource
* (looks like "Rename" does), we need to supply a "free" callback.
*/
NuResult
Nu_InternalFreeCallback(NuArchive* pArchive, void* args)
NuResult Nu_InternalFreeCallback(NuArchive* pArchive, void* args)
{
DBUG(("+++ internal free callback 0x%08lx\n", (long) args));
Nu_Free(nil, args);
Nu_Free(NULL, args);
return kNuOK;
}

View File

@ -1,16 +1,17 @@
NufxLib NOTES
Last revised: 2000/01/23
=============
Last revised: 2015/01/04
The interface is documented in "nufxlibapi.html", available from the
www.nulib.com web site. This discusses some of the internal design that
may be of interest.
http://www.nulib.com/ web site. This discusses some of the internal
design that may be of interest.
Some familiarity with the NuFX file format is assumed.
- - -
Read-Write Data Structures
==========================
### Read-Write Data Structures ###
For both read-only and read-write files (but not streaming read-only files),
the archive is represented internally as a linked list of Records, each
@ -64,15 +65,15 @@ threads are annotated in the "copy" list.)
One of the goals was to be able to execute a sequence of operations like:
- open original archive
- read original archive
- modify archive
- flush (success)
- modify archive
- flush (failure, rollback)
- modify archive
- flush (success)
- close archive
open original archive
read original archive
modify archive
flush (success)
modify archive
flush (failure, rollback)
modify archive
flush (success)
close archive
The archive is opened at the start and held open across many operations.
There is never a need to re-read the entire archive. We could avoid the
@ -92,11 +93,11 @@ extraction are minimal.
In summary:
"orig" list has original set of records, and is not disturbed until
- "orig" list has original set of records, and is not disturbed until
the changes are committed.
"copy" list is created on first add/update/delete operation, and
- "copy" list is created on first add/update/delete operation, and
initially contains a complete copy of "orig".
"new" list contains all new additions to the archive, including
- "new" list contains all new additions to the archive, including
new additions that replace existing entries (the existing entry
is deleted from "copy" and then added to "new").
@ -106,9 +107,9 @@ Any changes to the record header or additions to the thread mod list are
made in the "copy" set; the "original" set remains untouched. The thread
mod list can have the following items in it:
- delete thread (NuThreadIdx)
- add thread (type, otherSize, format, +contents)
- update pre-sized thread (NuThreadIdx, +contents)
- delete thread (NuThreadIdx)
- add thread (type, otherSize, format, +contents)
- update pre-sized thread (NuThreadIdx, +contents)
Contents are specified with a NuDataSource, which allows the application
to indicate that the data is already compressed. This is useful for
@ -179,9 +180,9 @@ is possible that the archive could be unrecoverably damaged. NufxLib
tries to identify such situations, and will leave the archive open in
read-only mode after rolling back any new file additions.
- - -
Updating Filenames
==================
### Updating Filenames ###
Updating filenames is a small nightmare, because the filename can be
either in the record header or in a filename thread. It's possible,
@ -191,16 +192,148 @@ header and two or more filenames in threads.
NufxLib will not automatically "fix" broken records, but it will prevent
applications from creating situations that should not exist.
When reading an archive, NufxLib will use the filename from the
- When reading an archive, NufxLib will use the filename from the
first filename thread found. If no filename threads are found, the
filename from the record header will be used.
If you add a filename thread to a record that has a filename in the
- If you add a filename thread to a record that has a filename in the
record header, the header name will be removed.
If you update a filename thread in a record that has a filename in
- If you update a filename thread in a record that has a filename in
the record header, the header name will be left untouched.
Adding a filename thread is only allowed if no filename thread exists,
- Adding a filename thread is only allowed if no filename thread exists,
or all existing filename threads have been deleted.
- - -
### Unicode Filenames ###
Modern operating systems support filenames with a broader range of
characters than the Apple II did. This presents problems and opportunities.
#### Background ####
The Apple IIgs and old Macintoshes use the Mac OS Roman ("MOR") character
set. This defines a set of characters outside the ASCII range, i.e.
byte values with the high bit set. In addition to the usual collection
of vowels with accents and umlauts, MOR has some less-common characters,
including the Apple logo.
On Windows, the high-ASCII values are generally interpreted according
to Windows Code Page 1252 ("CP-1252"), which defines a similar set
of vowels with accents and miscellaneous symbols. MOR and CP-1252
have some overlap, but you can't really translate one into the other.
The standards-approved equivalent of CP-1252 is ISO-8859-1, though
according to [wikipedia](http://en.wikipedia.org/wiki/Windows-1252)
there was some confusion between the two.
Modern operating systems support the Unicode Universal Character Set.
This system allows for a very large number of characters (over a million),
and includes definitions for all of the symbols in MOR and CP-1252.
Each character is assigned a "code point", which is a numeric value between
zero and 0x10FFFF. Most of the characters used in modern languages can
be found in the Basic Multilingual Plane (BMP), which uses code points
between zero and 0xFFFF (requiring only 16 bits).
There are different ways of encoding code points. Consider, for example,
Unicode LATIN SMALL LETTER A WITH ACUTE:
MOR: 0x87
CP-1252: 0xE1
Unicode: U+00E1
UTF-16: 0x00E1
UTF-8: 0xC3 0xA1
Or the humble TRADE MARK SIGN:
MOR: 0xAA
CP-1252: 0x99
Unicode: U+2122
UTF-16: 0x2122
UTF-8: 0xE2 0x84 0xA2
Modern Linux and Mac OS X use UTF-8 encoding in filenames. Because it's a
byte-oriented encoding, and 7-bit ASCII values are trivially represented
as 7-bit ASCII values, all of the existing system and library calls work
as they did before (i.e. if they took a `char*`, they still do).
Windows uses UTF-16, which requires at least 16 bits per code point.
Filenames are now "wide" strings, based on `wchar_t*`. Windows includes
an elaborate system of defines based around the `TCHAR` type, which can
be either `char` or `wchar_t` depending on whether a program is compiled
with `_MBCS` (Multi-Byte Character System) or `_UNICODE`. A set of
preprocessor definitions is provided that will map I/O function names,
so you can call `_tfopen(TCHAR* ...)`, and the compiler will turn it into
either `fopen(char* ...)` or `_wfopen(wchar_t* ...)`. MBCS is deprecated
in favor of Unicode, so any new code should be strictly UTF-16 based.
This means that, for code to work on both Linux and Windows, it has to
work with incompatible filename string types and different I/O functions.
#### Opening Archive Files ####
On Linux and Mac OS X, NuLib2 can open any file named on the command line.
On Windows, it's a bit trickier.
The problem is that NuLib2 provides a `main()` function that is passed a
vector of "narrow" strings. The filenames provided on the command line
will be converted from wide to narrow, so unless the filename is entirely
composed of ASCII or CP-1252 characters, some information will be lost
and it will be impossible to open the file.
NuLib2 must instead provide a `wmain()` function that takes wide strings.
The strings must be stored and passed around as wide throughout the
program, and passed into NufxLib this way (because NufxLib issues the
actual _wopen call). This means that NufxLib API must take narrow strings
when built for Linux, and wide strings when built for Windows.
#### Adding/Extracting Mac OS Roman Files ####
GS/ShrinkIt was designed to handle GS/OS files from HFS volumes, so NuFX
archive filenames use the MOR character set. To preserve the encoding
we could simply extract the values as-is and let them appear as whatever
values happen to line up in CP-1252, which is what pre-3.0 NuLib2 did.
It's much nicer to translate from MOR to Unicode when extracting, and
convert back from Unicode to MOR when adding files to an archive.
The key consideration is that the character set associated with a
filename must be tracked. The code can't simply extract a filename from
the archive and pass it to a 'creat()` call. Character set conversions
must take place at appropriate times.
With Windows it's a bit harder to confuse MOR and Unicode names, because
one uses 8-bit characters and the other uses UTF-16, but the compiler
doesn't catch everything.
#### Current State ####
NufxLib defines the UNICHAR type, which has a role very like TCHAR:
it can be `char*` or `wchar_t*`, and can be accompanied by a set of
preprocessor mappings that switch between I/O functions. The UNICHAR
type will be determined based on a define provided from the compiler
command line (perhaps `-DUSE_UTF16_FILENAMES`).
The current version of NufxLib (v3.0.0) takes the first step, defining
all filename strings as either UNICHAR or MOR, and converting between them
as necessary. This, plus a few minor tweaks to NuLib2, was enough to
get Unicode filename support working on Linux and Mac OS X.
None of the work needed to make Windows work properly has been done.
The string conversion functions are no-ops for Win32. As a result,
NuLib2 for Windows treats filenames the same way in 3.x as it did in 2.x.
There are some situations where things can go awry even with UNICHAR,
most notably printf-style arguments. These are checked by gcc, but
not by Visual Studio unless you run the static analyzer. A simple
`printf("filename=%s\n", filename)` would be correct for narrow strings
but wrong for wide strings. It will likely be necessary to define a
filename format string (similar to `PRI64d` for 64-bit values) and switch
between "%s" and "%ls".
This is a fair bit of work and requires some amount of uglification to
NuLib2 and NufxLib. Since Windows users can use CiderPress, and the
vast majority of NuFX archives use ASCII-only ProDOS file names, it's
not clear that the effort would be worthwhile.

View File

@ -6,10 +6,11 @@
*
* External interface (types, defines, and function prototypes).
*/
#ifndef __NufxLib__
#define __NufxLib__
#ifndef NUFXLIB_NUFXLIB_H
#define NUFXLIB_NUFXLIB_H
#include <stdio.h>
#include <stdint.h>
#ifdef __cplusplus
@ -31,9 +32,9 @@ extern "C" {
* The "bug" version can usually be ignored, since it represents minor
* fixes. Unless, of course, your code depends upon that fix.
*/
#define kNuVersionMajor 2
#define kNuVersionMinor 2
#define kNuVersionBug 2
#define kNuVersionMajor 3
#define kNuVersionMinor 1
#define kNuVersionBug 0
/*
@ -42,6 +43,33 @@ extern "C" {
* ===========================================================================
*/
/*
* Unicode character type. For Linux and Mac OS X, filenames use "narrow"
* characters and UTF-8 encoding, which allows them to use standard file I/O
* functions like fopen(). Windows uses UTF-16, which requires a different
* character type and an alternative set of I/O functions like _wfopen().
*
* The idea is that NufxLib API functions will operate on filenames with
* the OS dominant method, so on Windows the API accepts UTF-16. This
* definition is a bit like Windows TCHAR, but it's dependent on the OS, not
* on whether _MBCS or _UNICODE is defined.
*
* The app can include "Unichar.h" to get definitions for functions that
* switch between narrow and wide functions (e.g. "unistrlen()" becomes
* strlen() or wcslen() as appropriate).
*
* We switch based on _WIN32, because we're not really switching on
* filename-character size; the key issue is all the pesky wide I/O calls.
*/
#if defined(_WIN32)
// TODO: complete this
//# include <wchar.h>
//# define UNICHAR wchar_t
# define UNICHAR char
#else
# define UNICHAR char
#endif
/*
* Error values returned from functions.
*
@ -148,38 +176,41 @@ typedef enum NuResult {
* NuRecordIdxs are assigned to records in an archive. You may assume that
* the values are unique, but that is all.
*/
typedef unsigned long NuRecordIdx;
typedef uint32_t NuRecordIdx;
/*
* NuThreadIdxs are assigned to threads within a record. Again, you may
* assume that the values are unique within a record, but that is all.
*/
typedef unsigned long NuThreadIdx;
typedef uint32_t NuThreadIdx;
/*
* Thread ID, a combination of thread_class and thread_kind. Standard
* values have explicit identifiers.
*/
typedef unsigned long NuThreadID;
typedef uint32_t NuThreadID;
#define NuMakeThreadID(class, kind) /* construct a NuThreadID */ \
((unsigned long)(class) << 16 | (unsigned long)(kind))
((uint32_t)(class) << 16 | (uint32_t)(kind))
#define NuGetThreadID(pThread) /* pull NuThreadID out of NuThread */ \
(NuMakeThreadID((pThread)->thThreadClass, (pThread)->thThreadKind))
#define NuThreadIDGetClass(threadID) /* get threadClass from NuThreadID */ \
((unsigned short) ((unsigned long)(threadID) >> 16))
((uint16_t) ((uint32_t)(threadID) >> 16))
#define NuThreadIDGetKind(threadID) /* get threadKind from NuThreadID */ \
((unsigned short) ((threadID) & 0xffff))
((uint16_t) ((threadID) & 0xffff))
#define kNuThreadClassMessage 0x0000
#define kNuThreadClassControl 0x0001
#define kNuThreadClassData 0x0002
#define kNuThreadClassFilename 0x0003
#define kNuThreadKindDataFork 0x0000 /* when class=data */
#define kNuThreadKindDiskImage 0x0001 /* when class=data */
#define kNuThreadKindRsrcFork 0x0002 /* when class=data */
#define kNuThreadIDOldComment NuMakeThreadID(kNuThreadClassMessage, 0x0000)
#define kNuThreadIDComment NuMakeThreadID(kNuThreadClassMessage, 0x0001)
#define kNuThreadIDIcon NuMakeThreadID(kNuThreadClassMessage, 0x0002)
#define kNuThreadIDMkdir NuMakeThreadID(kNuThreadClassControl, 0x0000)
#define kNuThreadIDDataFork NuMakeThreadID(kNuThreadClassData, 0x0000)
#define kNuThreadIDDiskImage NuMakeThreadID(kNuThreadClassData, 0x0001)
#define kNuThreadIDRsrcFork NuMakeThreadID(kNuThreadClassData, 0x0002)
#define kNuThreadIDDataFork NuMakeThreadID(kNuThreadClassData, kNuThreadKindDataFork)
#define kNuThreadIDDiskImage NuMakeThreadID(kNuThreadClassData, kNuThreadKindDiskImage)
#define kNuThreadIDRsrcFork NuMakeThreadID(kNuThreadClassData, kNuThreadKindRsrcFork)
#define kNuThreadIDFilename NuMakeThreadID(kNuThreadClassFilename, 0x0000)
#define kNuThreadIDWildcard NuMakeThreadID(0xffff, 0xffff)
@ -198,10 +229,10 @@ typedef enum NuThreadFormat {
/* extract the filesystem separator char from the "file_sys_info" field */
#define NuGetSepFromSysInfo(sysInfo) \
((char) ((sysInfo) & 0xff))
((UNICHAR) ((sysInfo) & 0xff))
/* return a file_sys_info with a replaced filesystem separator */
#define NuSetSepInSysInfo(sysInfo, newSep) \
((unsigned short) (((sysInfo) & 0xff00) | ((newSep) & 0xff)) )
((uint16_t) (((sysInfo) & 0xff00) | ((newSep) & 0xff)) )
/* GS/OS-defined file system identifiers; sadly, UNIX is not among them */
typedef enum NuFileSysID {
@ -273,7 +304,7 @@ typedef enum NuValueID {
kNuValueIgnoreLZW2Len = 14,
kNuValueHandleBadMac = 15
} NuValueID;
typedef unsigned long NuValue;
typedef uint32_t NuValue;
/*
* Enumerated values for things you pass in a NuValue.
@ -322,7 +353,7 @@ typedef enum NuAttrID {
kNuAttrHeaderOffset = 3,
kNuAttrJunkOffset = 4,
} NuAttrID;
typedef unsigned long NuAttr;
typedef uint32_t NuAttr;
/*
* Archive types.
@ -381,14 +412,14 @@ typedef union NuDataSink NuDataSink; /* dummy def for internal struct */
* NuFX Date/Time structure; same as TimeRec from IIgs "misctool.h".
*/
typedef struct NuDateTime {
unsigned char second; /* 0-59 */
unsigned char minute; /* 0-59 */
unsigned char hour; /* 0-23 */
unsigned char year; /* year - 1900 */
unsigned char day; /* 0-30 */
unsigned char month; /* 0-11 */
unsigned char extra; /* (must be zero) */
unsigned char weekDay; /* 1-7 (1=sunday) */
uint8_t second; /* 0-59 */
uint8_t minute; /* 0-59 */
uint8_t hour; /* 0-23 */
uint8_t year; /* year - 1900 */
uint8_t day; /* 0-30 */
uint8_t month; /* 0-11 */
uint8_t extra; /* (must be zero) */
uint8_t weekDay; /* 1-7 (1=sunday) */
} NuDateTime;
/*
@ -399,26 +430,30 @@ typedef struct NuDateTime {
*/
typedef struct NuThread {
/* from the archive */
unsigned short thThreadClass;
NuThreadFormat thThreadFormat;
unsigned short thThreadKind;
unsigned short thThreadCRC; /* comp or uncomp data; see rec vers */
unsigned long thThreadEOF;
unsigned long thCompThreadEOF;
uint16_t thThreadClass;
NuThreadFormat thThreadFormat;
uint16_t thThreadKind;
uint16_t thThreadCRC; /* comp or uncomp data; see rec vers */
uint32_t thThreadEOF;
uint32_t thCompThreadEOF;
/* extra goodies */
NuThreadIdx threadIdx;
unsigned long actualThreadEOF; /* disk images might be off */
long fileOffset; /* fseek offset to data in shk */
NuThreadIdx threadIdx;
uint32_t actualThreadEOF; /* disk images might be off */
long fileOffset; /* fseek offset to data in shk */
/* internal use only */
unsigned short used; /* mark as uninteresting */
uint16_t used; /* mark as uninteresting */
} NuThread;
/*
* NuFX "record" definition.
*
* (Note to developers: update Nu_AddRecord if this changes.)
*
* The filenames are in Mac OS Roman format. It's arguable whether MOR
* strings should be part of the interface at all. However, the API
* pre-dates the inclusion of Unicode support, and I'm leaving it alone.
*/
#define kNufxIDLen 4 /* len of 'NuFX' with funky MSBs */
#define kNuReasonableAttribCount 256
@ -428,52 +463,52 @@ typedef struct NuThread {
#define kNuOurRecordVersion 3 /* what we write */
typedef struct NuRecord {
/* version 0+ */
unsigned char recNufxID[kNufxIDLen];
unsigned short recHeaderCRC;
unsigned short recAttribCount;
unsigned short recVersionNumber;
unsigned long recTotalThreads;
NuFileSysID recFileSysID;
unsigned short recFileSysInfo;
unsigned long recAccess;
unsigned long recFileType;
unsigned long recExtraType;
unsigned short recStorageType; /* NuStorage*,file_sys_block_size */
NuDateTime recCreateWhen;
NuDateTime recModWhen;
NuDateTime recArchiveWhen;
uint8_t recNufxID[kNufxIDLen];
uint16_t recHeaderCRC;
uint16_t recAttribCount;
uint16_t recVersionNumber;
uint32_t recTotalThreads;
NuFileSysID recFileSysID;
uint16_t recFileSysInfo;
uint32_t recAccess;
uint32_t recFileType;
uint32_t recExtraType;
uint16_t recStorageType; /* NuStorage*,file_sys_block_size */
NuDateTime recCreateWhen;
NuDateTime recModWhen;
NuDateTime recArchiveWhen;
/* option lists only in version 1+ */
unsigned short recOptionSize;
unsigned char* recOptionList; /* NULL if v0 or recOptionSize==0 */
uint16_t recOptionSize;
uint8_t* recOptionList; /* NULL if v0 or recOptionSize==0 */
/* data specified by recAttribCount, not accounted for by option list */
long extraCount;
unsigned char* extraBytes;
int32_t extraCount;
uint8_t* extraBytes;
unsigned short recFilenameLength; /* usually zero */
char* recFilename; /* doubles as disk volume_name */
uint16_t recFilenameLength; /* usually zero */
char* recFilenameMOR; /* doubles as disk volume_name */
/* extra goodies; "dirtyHeader" does not apply to anything below */
NuRecordIdx recordIdx; /* session-unique record index */
char* threadFilename; /* extracted from filename thread */
char* newFilename; /* memorized during "add file" call */
const char* filename; /* points at recFilen or threadFilen */
unsigned long recHeaderLength; /* size of rec hdr, incl thread hdrs */
unsigned long totalCompLength; /* total len of data in archive file */
long fakeThreads; /* used by "MaskDataless" */
int isBadMac; /* malformed "bad mac" header */
NuRecordIdx recordIdx; /* session-unique record index */
char* threadFilenameMOR; /* extracted from filename thread */
char* newFilenameMOR; /* memorized during "add file" call */
const char* filenameMOR; /* points at recFilen or threadFilen */
uint32_t recHeaderLength; /* size of rec hdr, incl thread hdrs */
uint32_t totalCompLength; /* total len of data in archive file */
uint32_t fakeThreads; /* used by "MaskDataless" */
int isBadMac; /* malformed "bad mac" header */
long fileOffset; /* file offset of record header */
long fileOffset; /* file offset of record header */
/* use provided interface to access this */
struct NuThread* pThreads; /* ptr to thread array */
struct NuThread* pThreads; /* ptr to thread array */
/* private -- things the application shouldn't look at */
struct NuRecord* pNext; /* used internally */
NuThreadMod* pThreadMods; /* used internally */
short dirtyHeader; /* set in "copy" when hdr fields uptd */
short dropRecFilename; /* if set, we're dropping this name */
struct NuRecord* pNext; /* used internally */
NuThreadMod* pThreadMods; /* used internally */
short dirtyHeader; /* set in "copy" when hdr fields uptd */
short dropRecFilename; /* if set, we're dropping this name */
} NuRecord;
/*
@ -488,18 +523,18 @@ typedef struct NuRecord {
#define kNuMaxMHVersion 2 /* max we can handle */
#define kNuOurMHVersion 2 /* what we write */
typedef struct NuMasterHeader {
unsigned char mhNufileID[kNufileIDLen];
unsigned short mhMasterCRC;
unsigned long mhTotalRecords;
NuDateTime mhArchiveCreateWhen;
NuDateTime mhArchiveModWhen;
unsigned short mhMasterVersion;
unsigned char mhReserved1[kNufileMasterReserved1Len];
unsigned long mhMasterEOF;
unsigned char mhReserved2[kNufileMasterReserved2Len];
uint8_t mhNufileID[kNufileIDLen];
uint16_t mhMasterCRC;
uint32_t mhTotalRecords;
NuDateTime mhArchiveCreateWhen;
NuDateTime mhArchiveModWhen;
uint16_t mhMasterVersion;
uint8_t mhReserved1[kNufileMasterReserved1Len];
uint32_t mhMasterEOF;
uint8_t mhReserved2[kNufileMasterReserved2Len];
/* private -- internal use only */
short isValid;
short isValid;
} NuMasterHeader;
@ -514,35 +549,40 @@ typedef struct NuMasterHeader {
* a small subset of the full record.
*/
typedef struct NuRecordAttr {
NuFileSysID fileSysID;
/*unsigned short fileSysInfo;*/
unsigned long access;
unsigned long fileType;
unsigned long extraType;
NuDateTime createWhen;
NuDateTime modWhen;
NuDateTime archiveWhen;
NuFileSysID fileSysID;
/*uint16_t fileSysInfo;*/
uint32_t access;
uint32_t fileType;
uint32_t extraType;
NuDateTime createWhen;
NuDateTime modWhen;
NuDateTime archiveWhen;
} NuRecordAttr;
/*
* Some additional details about a file.
*
* Ideally (from an API cleanliness perspective) the storage name would
* be passed around as UTF-8 and converted internally. Passing it as
* MOR required fewer changes to the library, and allows us to avoid
* having to deal with illegal characters.
*/
typedef struct NuFileDetails {
/* used during AddFile call */
NuThreadID threadID; /* data, rsrc, disk img? */
const char* origName;
NuThreadID threadID; /* data, rsrc, disk img? */
const void* origName; /* arbitrary pointer, usually a string */
/* these go straight into the NuRecord */
const char* storageName;
NuFileSysID fileSysID;
unsigned short fileSysInfo;
unsigned long access;
unsigned long fileType;
unsigned long extraType;
unsigned short storageType; /* use Unknown, or disk block size */
NuDateTime createWhen;
NuDateTime modWhen;
NuDateTime archiveWhen;
const char* storageNameMOR;
NuFileSysID fileSysID;
uint16_t fileSysInfo;
uint32_t access;
uint32_t fileType;
uint32_t extraType;
uint16_t storageType; /* use Unknown, or disk block size */
NuDateTime createWhen;
NuDateTime modWhen;
NuDateTime archiveWhen;
} NuFileDetails;
@ -550,23 +590,23 @@ typedef struct NuFileDetails {
* Passed into the SelectionFilter callback.
*/
typedef struct NuSelectionProposal {
const NuRecord* pRecord;
const NuThread* pThread;
const NuRecord* pRecord;
const NuThread* pThread;
} NuSelectionProposal;
/*
* Passed into the OutputPathnameFilter callback.
*/
typedef struct NuPathnameProposal {
const char* pathname;
char filenameSeparator;
const NuRecord* pRecord;
const NuThread* pThread;
const UNICHAR* pathnameUNI;
UNICHAR filenameSeparator;
const NuRecord* pRecord;
const NuThread* pThread;
const char* newPathname;
unsigned char newFilenameSeparator;
/*NuThreadID newStorage;*/
NuDataSink* newDataSink;
const UNICHAR* newPathnameUNI;
UNICHAR newFilenameSeparator;
/*NuThreadID newStorage;*/
NuDataSink* newDataSink;
} NuPathnameProposal;
@ -598,7 +638,8 @@ typedef enum NuProgressState {
} NuProgressState;
/*
* Passed into the ProgressUpdater callback.
* Passed into the ProgressUpdater callback. All pointers become
* invalid when the callback returns.
*
* [ Thought for the day: add an optional flag that causes us to only
* call the progressFunc when the "percentComplete" changes by more
@ -606,36 +647,36 @@ typedef enum NuProgressState {
*/
typedef struct NuProgressData {
/* what are we doing */
NuOperation operation;
NuOperation operation;
/* what specifically are we doing */
NuProgressState state;
NuProgressState state;
/* how far along are we */
short percentComplete; /* 0-100 */
short percentComplete; /* 0-100 */
/* original pathname (in archive for expand, on disk for compress) */
const char* origPathname;
const UNICHAR* origPathnameUNI;
/* processed pathname (PathnameFilter for expand, in-record for compress) */
const char* pathname;
/* basename of "pathname" */
const char* filename;
const UNICHAR* pathnameUNI;
/* basename of "pathname" (for convenience) */
const UNICHAR* filenameUNI;
/* pointer to the record we're expanding from */
const NuRecord* pRecord;
const NuRecord* pRecord;
unsigned long uncompressedLength; /* size of uncompressed data */
unsigned long uncompressedProgress; /* #of bytes in/out */
uint32_t uncompressedLength; /* size of uncompressed data */
uint32_t uncompressedProgress; /* #of bytes in/out */
struct {
NuThreadFormat threadFormat; /* compression being applied */
NuThreadFormat threadFormat; /* compression being applied */
} compress;
struct {
unsigned long totalCompressedLength; /* all "data" threads */
unsigned long totalUncompressedLength;
uint32_t totalCompressedLength; /* all "data" threads */
uint32_t totalUncompressedLength;
/*unsigned long compressedLength; * size of compressed data */
/*unsigned long compressedProgress; * #of compressed bytes in/out*/
const NuThread* pThread; /* thread we're working on */
NuValue convertEOL; /* set if LF/CR conv is on */
/*uint32_t compressedLength; * size of compressed data */
/*uint32_t compressedProgress; * #of compressed bytes in/out*/
const NuThread* pThread; /* thread we're working on */
NuValue convertEOL; /* set if LF/CR conv is on */
} expand;
/* pay no attention */
@ -649,11 +690,11 @@ typedef struct NuErrorStatus {
NuOperation operation; /* were we adding, extracting, ?? */
NuError err; /* library error code */
int sysErr; /* system error code, if applicable */
const char* message; /* (optional) message to user */
const UNICHAR* message; /* (optional) message to user */
const NuRecord* pRecord; /* relevant record, if any */
const char* pathname; /* problematic pathname, if any */
const char* origPathname; /* original pathname, if any */
char filenameSeparator; /* fssep for pathname, if any */
const UNICHAR* pathnameUNI; /* problematic pathname, if any */
const void* origPathname; /* original pathname ref, if any */
UNICHAR filenameSeparator; /* fssep for pathname, if any */
/*char origArchiveTouched;*/
char canAbort; /* give option to abort */
@ -669,14 +710,14 @@ typedef struct NuErrorStatus {
* Error message callback gets one of these.
*/
typedef struct NuErrorMessage {
const char* message; /* the message itself */
const char* message; /* the message itself (UTF-8) */
NuError err; /* relevant error code (may be none) */
short isDebug; /* set for debug-only messages */
/* these identify where the message originated if lib built w/debug set */
const char* file; /* source file */
const char* file; /* source file (UTF-8) */
int line; /* line number */
const char* function; /* function name (might be nil) */
const char* function; /* function name (might be NULL) */
} NuErrorMessage;
@ -727,37 +768,38 @@ NUFXLIB_API NuError NuExtract(NuArchive* pArchive);
NUFXLIB_API NuError NuTest(NuArchive* pArchive);
/* strictly non-streaming read-only interfaces */
NUFXLIB_API NuError NuOpenRO(const char* archivePathname,NuArchive** ppArchive);
NUFXLIB_API NuError NuOpenRO(const UNICHAR* archivePathnameUNI,
NuArchive** ppArchive);
NUFXLIB_API NuError NuExtractRecord(NuArchive* pArchive, NuRecordIdx recordIdx);
NUFXLIB_API NuError NuExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
NuDataSink* pDataSink);
NUFXLIB_API NuError NuTestRecord(NuArchive* pArchive, NuRecordIdx recordIdx);
NUFXLIB_API NuError NuGetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
const NuRecord** ppRecord);
NUFXLIB_API NuError NuGetRecordIdxByName(NuArchive* pArchive, const char* name,
NuRecordIdx* pRecordIdx);
NUFXLIB_API NuError NuGetRecordIdxByName(NuArchive* pArchive,
const char* nameMOR, NuRecordIdx* pRecordIdx);
NUFXLIB_API NuError NuGetRecordIdxByPosition(NuArchive* pArchive,
unsigned long position, NuRecordIdx* pRecordIdx);
uint32_t position, NuRecordIdx* pRecordIdx);
/* read/write interfaces */
NUFXLIB_API NuError NuOpenRW(const char* archivePathname,
const char* tempPathname, unsigned long flags,
NUFXLIB_API NuError NuOpenRW(const UNICHAR* archivePathnameUNI,
const UNICHAR* tempPathnameUNI, uint32_t flags,
NuArchive** ppArchive);
NUFXLIB_API NuError NuFlush(NuArchive* pArchive, long* pStatusFlags);
NUFXLIB_API NuError NuFlush(NuArchive* pArchive, uint32_t* pStatusFlags);
NUFXLIB_API NuError NuAddRecord(NuArchive* pArchive,
const NuFileDetails* pFileDetails, NuRecordIdx* pRecordIdx);
NUFXLIB_API NuError NuAddThread(NuArchive* pArchive, NuRecordIdx recordIdx,
NuThreadID threadID, NuDataSource* pDataSource,
NuThreadIdx* pThreadIdx);
NUFXLIB_API NuError NuAddFile(NuArchive* pArchive, const char* pathname,
NUFXLIB_API NuError NuAddFile(NuArchive* pArchive, const UNICHAR* pathnameUNI,
const NuFileDetails* pFileDetails, short fromRsrcFork,
NuRecordIdx* pRecordIdx);
NUFXLIB_API NuError NuRename(NuArchive* pArchive, NuRecordIdx recordIdx,
const char* pathname, char fssep);
const char* pathnameMOR, char fssep);
NUFXLIB_API NuError NuSetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
const NuRecordAttr* pRecordAttr);
NUFXLIB_API NuError NuUpdatePresizedThread(NuArchive* pArchive,
NuThreadIdx threadIdx, NuDataSource* pDataSource, long* pMaxLen);
NuThreadIdx threadIdx, NuDataSource* pDataSource, int32_t* pMaxLen);
NUFXLIB_API NuError NuDelete(NuArchive* pArchive);
NUFXLIB_API NuError NuDeleteRecord(NuArchive* pArchive, NuRecordIdx recordIdx);
NUFXLIB_API NuError NuDeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx);
@ -779,31 +821,31 @@ NUFXLIB_API NuError NuDebugDumpArchive(NuArchive* pArchive);
/* sources and sinks */
NUFXLIB_API NuError NuCreateDataSourceForFile(NuThreadFormat threadFormat,
unsigned long otherLen, const char* pathname,
uint32_t otherLen, const UNICHAR* pathnameUNI,
short isFromRsrcFork, NuDataSource** ppDataSource);
NUFXLIB_API NuError NuCreateDataSourceForFP(NuThreadFormat threadFormat,
unsigned long otherLen, FILE* fp, long offset, long length,
uint32_t otherLen, FILE* fp, long offset, long length,
NuCallback closeFunc, NuDataSource** ppDataSource);
NUFXLIB_API NuError NuCreateDataSourceForBuffer(NuThreadFormat threadFormat,
unsigned long otherLen, const unsigned char* buffer, long offset,
uint32_t otherLen, const uint8_t* buffer, long offset,
long length, NuCallback freeFunc, NuDataSource** ppDataSource);
NUFXLIB_API NuError NuFreeDataSource(NuDataSource* pDataSource);
NUFXLIB_API NuError NuDataSourceSetRawCrc(NuDataSource* pDataSource,
unsigned short crc);
uint16_t crc);
NUFXLIB_API NuError NuCreateDataSinkForFile(short doExpand, NuValue convertEOL,
const char* pathname, char fssep, NuDataSink** ppDataSink);
const UNICHAR* pathnameUNI, UNICHAR fssep, NuDataSink** ppDataSink);
NUFXLIB_API NuError NuCreateDataSinkForFP(short doExpand, NuValue convertEOL,
FILE* fp, NuDataSink** ppDataSink);
NUFXLIB_API NuError NuCreateDataSinkForBuffer(short doExpand,
NuValue convertEOL, unsigned char* buffer, unsigned long bufLen,
NuValue convertEOL, uint8_t* buffer, uint32_t bufLen,
NuDataSink** ppDataSink);
NUFXLIB_API NuError NuFreeDataSink(NuDataSink* pDataSink);
NUFXLIB_API NuError NuDataSinkGetOutCount(NuDataSink* pDataSink,
unsigned long* pOutCount);
uint32_t* pOutCount);
/* miscellaneous non-archive operations */
NUFXLIB_API NuError NuGetVersion(long* pMajorVersion, long* pMinorVersion,
long* pBugVersion, const char** ppBuildDate,
NUFXLIB_API NuError NuGetVersion(int32_t* pMajorVersion, int32_t* pMinorVersion,
int32_t* pBugVersion, const char** ppBuildDate,
const char** ppBuildFlags);
NUFXLIB_API const char* NuStrError(NuError err);
NUFXLIB_API NuError NuTestFeature(NuFeature feature);
@ -811,13 +853,18 @@ NUFXLIB_API void NuRecordCopyAttr(NuRecordAttr* pRecordAttr,
const NuRecord* pRecord);
NUFXLIB_API NuError NuRecordCopyThreads(const NuRecord* pRecord,
NuThread** ppThreads);
NUFXLIB_API unsigned long NuRecordGetNumThreads(const NuRecord* pRecord);
NUFXLIB_API const NuThread* NuThreadGetByIdx(const NuThread* pThread, long idx);
NUFXLIB_API uint32_t NuRecordGetNumThreads(const NuRecord* pRecord);
NUFXLIB_API const NuThread* NuThreadGetByIdx(const NuThread* pThread,
int32_t idx);
NUFXLIB_API short NuIsPresizedThreadID(NuThreadID threadID);
NUFXLIB_API size_t NuConvertMORToUNI(const char* stringMOR,
UNICHAR* bufUNI, size_t bufSize);
NUFXLIB_API size_t NuConvertUNIToMOR(const UNICHAR* stringUNI,
char* bufMOR, size_t bufSize);
#define NuGetThread(pRecord, idx) ( (const NuThread*) \
((unsigned long) (idx) < (unsigned long) (pRecord)->recTotalThreads ? \
&(pRecord)->pThreads[(idx)] : NULL) \
#define NuGetThread(pRecord, idx) ( (const NuThread*) \
((uint32_t) (idx) < (pRecord)->recTotalThreads ? \
&(pRecord)->pThreads[(idx)] : NULL) \
)
@ -840,4 +887,4 @@ NUFXLIB_API NuCallback NuSetGlobalErrorMessageHandler(NuCallback messageHandlerF
}
#endif
#endif /*__NufxLib__*/
#endif /*NUFXLIB_NUFXLIB_H*/

View File

@ -6,8 +6,8 @@
*
* Global internal declarations and definitions.
*/
#ifndef __NufxLibPriv__
#define __NufxLibPriv__
#ifndef NUFXLIB_NUFXLIBPRIV_H
#define NUFXLIB_NUFXLIBPRIV_H
/* include files that everybody needs */
#include "SysDefs.h"
@ -86,7 +86,7 @@ typedef enum NuOpenMode {
*/
typedef struct NuRecordSet {
Boolean loaded;
ulong numRecords;
uint32_t numRecords;
NuRecord* nuRecordHead;
NuRecord* nuRecordTail;
} NuRecordSet;
@ -95,12 +95,12 @@ typedef struct NuRecordSet {
* Archive state.
*/
struct NuArchive {
ulong structMagic;
uint32_t structMagic;
Boolean busy;
NuOpenMode openMode;
Boolean newlyCreated;
char* archivePathname; /* pathname or "(stream)" */
UNICHAR* archivePathnameUNI; /* pathname or "(stream)" */
FILE* archiveFp;
NuArchiveType archiveType;
@ -108,7 +108,7 @@ struct NuArchive {
long junkOffset; /* skip past leading junk */
long headerOffset; /* adjustment for BXY/SEA/BSE */
char* tmpPathname; /* temp file, for writes */
UNICHAR* tmpPathnameUNI; /* temp file, for writes */
FILE* tmpFp;
/* used during initial processing; helps avoid ftell() calls */
@ -118,9 +118,9 @@ struct NuArchive {
Boolean testMode;
/* clumsy way of remembering name used for other fork in forked file */
const char* lastFileCreated;
const UNICHAR* lastFileCreatedUNI;
/* clumsy way to avoid trying to create the same subdir several times */
const char* lastDirCreated;
const UNICHAR* lastDirCreatedUNI;
/* master header from the archive */
NuMasterHeader masterHeader; /* original */
@ -135,7 +135,7 @@ struct NuArchive {
NuRecordSet newRecordSet; /* newly-added records */
/* state for compression functions */
uchar* compBuf; /* large general-purpose buffer */
uint8_t* compBuf; /* large general-purpose buffer */
void* lzwCompressState; /* state for LZW/1 and LZW/2 */
void* lzwExpandState; /* state for LZW/1 and LZW/2 */
@ -169,7 +169,7 @@ struct NuArchive {
#define kNuArchiveStructMagic 0xc0edbabe
#define kNuDefaultRecordName "UNKNOWN"
#define kNuDefaultRecordName "UNKNOWN" /* use ASCII charset */
/*
@ -256,7 +256,7 @@ struct NuThreadMod {
*/
typedef struct NuFunnel {
/* data storage */
uchar* buffer; /* kNuFunnelBufSize worth of storage */
uint8_t* buffer; /* kNuFunnelBufSize worth of storage */
long bufCount; /* #of bytes in buffer */
/* text conversion; if "auto", on first flush we convert to "on" or "off" */
@ -270,10 +270,10 @@ typedef struct NuFunnel {
Boolean isFirstWrite; /* cleared on first write */
#if 0
ulong inCount; /* total #of bytes in the top */
ulong outCount; /* total #of bytes out the bottom */
uint32_t inCount; /* total #of bytes in the top */
uint32_t outCount; /* total #of bytes out the bottom */
ulong outMax; /* flag an err when outCount exceeds this */
uint32_t outMax; /* flag an err when outCount exceeds this */
Boolean outMaxExceeded; /* in fact, it's this flag */
#endif
@ -302,11 +302,11 @@ typedef struct NuStraw {
NuDataSource* pDataSource;
/* progress update fields */
ulong lastProgress;
ulong lastDisplayed;
uint32_t lastProgress;
uint32_t lastDisplayed;
} NuStraw;
/*NuError Nu_CopyStreamToStream(FILE* outfp, FILE* infp, ulong count);*/
/*NuError Nu_CopyStreamToStream(FILE* outfp, FILE* infp, uint32_t count);*/
/*
@ -329,10 +329,10 @@ typedef enum NuDataSourceType {
typedef struct NuDataSourceCommon {
NuDataSourceType sourceType;
NuThreadFormat threadFormat; /* is it already compressed? */
ushort rawCrc; /* crc for already-compressed data*/
uint16_t rawCrc; /* crc for already-compressed data*/
/*Boolean doClose; \* close on completion? */
ulong dataLen; /* length of data (var for buf) */
ulong otherLen; /* uncomp len or preset buf size */
uint32_t dataLen; /* length of data (var for buf) */
uint32_t otherLen; /* uncomp len or preset buf size */
int refCount; /* so we can copy structs */
} NuDataSourceCommon;
@ -343,7 +343,7 @@ union NuDataSource {
struct {
NuDataSourceCommon common;
char* pathname;
UNICHAR* pathnameUNI;
Boolean fromRsrcFork;
/* temp storage; only valid when processing in library */
@ -360,7 +360,7 @@ union NuDataSource {
struct {
NuDataSourceCommon common;
const uchar* buffer; /* non-const if doClose=true */
const uint8_t* buffer; /* non-const if doClose=true */
long offset; /* starting offset */
long curOffset; /* current offset */
@ -387,7 +387,7 @@ typedef struct NuDataSinkCommon {
NuDataSinkType sinkType;
Boolean doExpand; /* expand file? */
NuValue convertEOL; /* convert EOL? (req "expand") */
ulong outCount;
uint32_t outCount;
} NuDataSinkCommon;
union NuDataSink {
@ -397,10 +397,10 @@ union NuDataSink {
struct {
NuDataSinkCommon common;
char* pathname; /* file to open */
char fssep;
UNICHAR* pathnameUNI; /* file to open */
UNICHAR fssep;
/* temp storage; must be nil except when processing in library */
/* temp storage; must be NULL except when processing in library */
FILE* fp;
} toFile;
@ -411,8 +411,8 @@ union NuDataSink {
struct {
NuDataSinkCommon common;
uchar* buffer;
ulong bufLen; /* max amount of data "buffer" holds */
uint8_t* buffer;
uint32_t bufLen; /* max amount of data "buffer" holds */
NuError stickyErr;
} toBuffer;
};
@ -429,25 +429,25 @@ union NuDataSink {
* the first arguments to Nu_ReportError, so we don't have to type them
* in every time we use the function. It would've been much easier to
* use a gcc-style varargs macro, but not everybody uses gcc.
*
* TODO: Visual C++ has vararg macros now; time to replace this.
*/
#ifdef DEBUG_MSGS
#ifdef HAS__FUNCTION__
#define _FUNCTION_ __FUNCTION__
#else
#define _FUNCTION_ ""
#endif
#ifdef HAS__FUNCTION__
# define _FUNCTION_ __FUNCTION__
#else
# define _FUNCTION_ ""
#endif
#define NU_BLOB pArchive, __FILE__, __LINE__, _FUNCTION_, false
#define NU_BLOB_DEBUG pArchive, __FILE__, __LINE__, _FUNCTION_, true
#define NU_NILBLOB NULL, __FILE__, __LINE__, _FUNCTION_, false
#define DebugShowError(err) \
#define NU_BLOB pArchive, __FILE__, __LINE__, _FUNCTION_, false
#define NU_BLOB_DEBUG pArchive, __FILE__, __LINE__, _FUNCTION_, true
#define NU_NILBLOB NULL, __FILE__, __LINE__, _FUNCTION_, false
#ifdef DEBUG_MSGS
# define DebugShowError(err) \
Nu_ReportError(pArchive, __FILE__, __LINE__, _FUNCTION_, \
true, err, "(DEBUG)");
#else
#define NU_BLOB pArchive, "", 0, "", false
#define NU_BLOB_DEBUG pArchive, "", 0, "", true
#define NU_NILBLOB NULL, "", 0, "", false
#define DebugShowError(err) ((void)0)
# define DebugShowError(err) ((void)0)
#endif
/*
@ -469,13 +469,13 @@ union NuDataSink {
goto bail; \
}
#define BailNil(val) { \
if ((val) == nil) { \
if ((val) == NULL) { \
err = kNuErrUnexpectedNil; \
BailError(err); \
} \
}
#define BailAlloc(val) { \
if ((val) == nil) { \
if ((val) == NULL) { \
err = kNuErrMalloc; \
BailError(err); \
} \
@ -498,9 +498,9 @@ NuError Nu_UpdateWrapper(NuArchive* pArchive, FILE* fp);
NuError Nu_AdjustWrapperPadding(NuArchive* pArchive, FILE* fp);
NuError Nu_AllocCompressionBufferIFN(NuArchive* pArchive);
NuError Nu_StreamOpenRO(FILE* infp, NuArchive** ppArchive);
NuError Nu_OpenRO(const char* filename, NuArchive** ppArchive);
NuError Nu_OpenRW(const char* archivePathname, const char* tempPathname,
ulong flags, NuArchive** ppArchive);
NuError Nu_OpenRO(const UNICHAR* archivePathnameUNI, NuArchive** ppArchive);
NuError Nu_OpenRW(const UNICHAR* archivePathnameUNI,
const UNICHAR* tempPathnameUNI, uint32_t flags, NuArchive** ppArchive);
NuError Nu_WriteMasterHeader(NuArchive* pArchive, FILE* fp,
NuMasterHeader* pMasterHeader);
NuError Nu_Close(NuArchive* pArchive);
@ -509,28 +509,28 @@ NuError Nu_RenameTempToArchive(NuArchive* pArchive);
NuError Nu_DeleteArchiveFile(NuArchive* pArchive);
/* ArchiveIO.c */
uchar Nu_ReadOneC(NuArchive* pArchive, FILE* fp, ushort* pCrc);
uchar Nu_ReadOne(NuArchive* pArchive, FILE* fp);
void Nu_WriteOneC(NuArchive* pArchive, FILE* fp, uchar val, ushort* pCrc);
void Nu_WriteOne(NuArchive* pArchive, FILE* fp, uchar val);
ushort Nu_ReadTwoC(NuArchive* pArchive, FILE* fp, ushort* pCrc);
ushort Nu_ReadTwo(NuArchive* pArchive, FILE* fp);
void Nu_WriteTwoC(NuArchive* pArchive, FILE* fp, ushort val, ushort* pCrc);
void Nu_WriteTwo(NuArchive* pArchive, FILE* fp, ushort val);
ulong Nu_ReadFourC(NuArchive* pArchive, FILE* fp, ushort* pCrc);
ulong Nu_ReadFour(NuArchive* pArchive, FILE* fp);
void Nu_WriteFourC(NuArchive* pArchive, FILE* fp, ulong val, ushort* pCrc);
void Nu_WriteFour(NuArchive* pArchive, FILE* fp, ulong val);
NuDateTime Nu_ReadDateTimeC(NuArchive* pArchive, FILE* fp, ushort* pCrc);
NuDateTime Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, ushort* pCrc);
uint8_t Nu_ReadOneC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
uint8_t Nu_ReadOne(NuArchive* pArchive, FILE* fp);
void Nu_WriteOneC(NuArchive* pArchive, FILE* fp, uint8_t val, uint16_t* pCrc);
void Nu_WriteOne(NuArchive* pArchive, FILE* fp, uint8_t val);
uint16_t Nu_ReadTwoC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
uint16_t Nu_ReadTwo(NuArchive* pArchive, FILE* fp);
void Nu_WriteTwoC(NuArchive* pArchive, FILE* fp, uint16_t val, uint16_t* pCrc);
void Nu_WriteTwo(NuArchive* pArchive, FILE* fp, uint16_t val);
uint32_t Nu_ReadFourC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
uint32_t Nu_ReadFour(NuArchive* pArchive, FILE* fp);
void Nu_WriteFourC(NuArchive* pArchive, FILE* fp, uint32_t val, uint16_t* pCrc);
void Nu_WriteFour(NuArchive* pArchive, FILE* fp, uint32_t val);
NuDateTime Nu_ReadDateTimeC(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
NuDateTime Nu_ReadDateTime(NuArchive* pArchive, FILE* fp, uint16_t* pCrc);
void Nu_WriteDateTimeC(NuArchive* pArchive, FILE* fp, NuDateTime dateTime,
ushort* pCrc);
uint16_t* pCrc);
void Nu_WriteDateTime(NuArchive* pArchive, FILE* fp, NuDateTime dateTime);
void Nu_ReadBytesC(NuArchive* pArchive, FILE* fp, void* vbuffer, long count,
ushort* pCrc);
uint16_t* pCrc);
void Nu_ReadBytes(NuArchive* pArchive, FILE* fp, void* vbuffer, long count);
void Nu_WriteBytesC(NuArchive* pArchive, FILE* fp, const void* vbuffer,
long count, ushort* pCrc);
long count, uint16_t* pCrc);
void Nu_WriteBytes(NuArchive* pArchive, FILE* fp, const void* vbuffer,
long count);
NuError Nu_HeaderIOFailed(NuArchive* pArchive, FILE* fp);
@ -540,9 +540,16 @@ NuError Nu_RewindArchive(NuArchive* pArchive);
/* Bzip2.c */
NuError Nu_CompressBzip2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc);
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
NuError Nu_ExpandBzip2(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc);
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc);
/* Charset.c */
size_t Nu_ConvertMORToUNI(const char* stringMOR, UNICHAR* bufUNI,
size_t bufSize);
UNICHAR* Nu_CopyMORToUNI(const char* stringMOR);
size_t Nu_ConvertUNIToMOR(const UNICHAR* stringUNI, char* bufMOR,
size_t bufSize);
/* Compress.c */
NuError Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
@ -554,22 +561,17 @@ NuError Nu_CopyPresizedToArchive(NuArchive* pArchive,
NuThread* pThread, char** ppSavedCopy);
/* Crc16.c */
extern const ushort gNuCrc16Table[256];
ushort Nu_CalcCRC16(ushort seed, const uchar* ptr, int count);
#ifdef __Crc16_c__ /* just doing "static inline" warns def-but-not-used */
#define CRC_INLINE /**/
#else
#define CRC_INLINE extern inline
#endif
#if defined(inline) && !defined(__Crc16_c__) /* somebody ovrd inline def? */
ushort Nu_UpdateCRC16(uchar val, ushort crc);
#else
CRC_INLINE ushort
Nu_UpdateCRC16(uchar val, ushort crc)
{
return (gNuCrc16Table[((crc >> 8) & 0xFF) ^ val] ^ (crc << 8)) & 0xFFFF;
}
#endif
extern const uint16_t gNuCrc16Table[256];
uint16_t Nu_CalcCRC16(uint16_t seed, const uint8_t* ptr, int count);
/*
* Update the CRC-16.
*
* _val (uint8_t) is the byte to add to the CRC. It's evaluated once.
* _crc (uint16_t) is the previous CRC. It's evaluated twice.
* Returns the updated CRC as a uint16_t.
*/
#define Nu_UpdateCRC16(_val, _crc) \
(gNuCrc16Table[(((_crc) >> 8) & 0xff) ^ (_val)] ^ ((_crc) << 8))
/* Debug.c */
#if defined(DEBUG_MSGS) || !defined(NDEBUG)
@ -591,13 +593,13 @@ NuError Nu_ThreadModAdd_FindByThreadID(const NuRecord* pRecord,
void Nu_FreeThreadMods(NuArchive* pArchive, NuRecord* pRecord);
NuThreadMod* Nu_ThreadMod_FindByThreadIdx(const NuRecord* pRecord,
NuThreadIdx threadIdx);
NuError Nu_Flush(NuArchive* pArchive, long* pStatusFlags);
NuError Nu_Flush(NuArchive* pArchive, uint32_t* pStatusFlags);
/* Deflate.c */
NuError Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc);
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
NuError Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc);
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc);
/* Expand.c */
NuError Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
@ -607,14 +609,14 @@ NuError Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
void Nu_SetCurrentDateTime(NuDateTime* pDateTime);
Boolean Nu_IsOlder(const NuDateTime* pWhen1, const NuDateTime* pWhen2);
NuError Nu_OpenOutputFile(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, const char* newPathname, char newFssep,
const NuThread* pThread, const UNICHAR* newPathnameUNI, UNICHAR newFssep,
FILE** pFp);
NuError Nu_CloseOutputFile(NuArchive* pArchive, const NuRecord* pRecord,
FILE* fp, const char* pathname);
NuError Nu_OpenInputFile(NuArchive* pArchive, const char* pathname,
FILE* fp, const UNICHAR* pathnameUNI);
NuError Nu_OpenInputFile(NuArchive* pArchive, const UNICHAR* pathnameUNI,
Boolean openRsrc, FILE** pFp);
NuError Nu_DeleteFile(const char* pathname);
NuError Nu_RenameFile(const char* fromPath, const char* toPath);
NuError Nu_DeleteFile(const UNICHAR* pathnameUNI);
NuError Nu_RenameFile(const UNICHAR* fromPathUNI, const UNICHAR* toPathUNI);
NuError Nu_FTell(FILE* fp, long* pOffset);
NuError Nu_FSeek(FILE* fp, long offset, int ptrname);
NuError Nu_FRead(FILE* fp, void* buf, size_t nbyte);
@ -627,22 +629,23 @@ NuError Nu_TruncateOpenFile(FILE* fp, long length);
/* Funnel.c */
NuError Nu_ProgressDataInit_Compress(NuArchive* pArchive,
NuProgressData* pProgressData, const NuRecord* pRecord,
const char* origPathname);
const UNICHAR* origPathnameUNI, const UNICHAR* pathnameUNI);
NuError Nu_ProgressDataInit_Expand(NuArchive* pArchive,
NuProgressData* pProgressData, const NuRecord* pRecord,
const char* newPathname, char newFssep, NuValue convertEOL);
const UNICHAR* newPathnameUNI, UNICHAR newFssep,
const UNICHAR* origPathnameUNI, NuValue convertEOL);
NuError Nu_SendInitialProgress(NuArchive* pArchive, NuProgressData* pProgress);
NuError Nu_FunnelNew(NuArchive* pArchive, NuDataSink* pDataSink,
NuValue convertEOL, NuValue convertEOLTo, NuProgressData* pProgress,
NuFunnel** ppFunnel);
NuError Nu_FunnelFree(NuArchive* pArchive, NuFunnel* pFunnel);
/*void Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, ulong maxBytes);*/
/*void Nu_FunnelSetMaxOutput(NuFunnel* pFunnel, uint32_t maxBytes);*/
NuError Nu_FunnelWrite(NuArchive* pArchive, NuFunnel* pFunnel,
const uchar* buffer, ulong count);
const uint8_t* buffer, uint32_t count);
NuError Nu_FunnelFlush(NuArchive* pArchive, NuFunnel* pFunnel);
NuError Nu_ProgressDataCompressPrep(NuArchive* pArchive, NuStraw* pStraw,
NuThreadFormat threadFormat, ulong sourceLen);
NuThreadFormat threadFormat, uint32_t sourceLen);
NuError Nu_ProgressDataExpandPrep(NuArchive* pArchive, NuFunnel* pFunnel,
const NuThread* pThread);
NuError Nu_FunnelSetProgressState(NuFunnel* pFunnel, NuProgressState state);
@ -654,32 +657,34 @@ NuError Nu_StrawNew(NuArchive* pArchive, NuDataSource* pDataSource,
NuError Nu_StrawFree(NuArchive* pArchive, NuStraw* pStraw);
NuError Nu_StrawSetProgressState(NuStraw* pStraw, NuProgressState state);
NuError Nu_StrawSendProgressUpdate(NuArchive* pArchive, NuStraw* pStraw);
NuError Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uchar* buffer,
NuError Nu_StrawRead(NuArchive* pArchive, NuStraw* pStraw, uint8_t* buffer,
long len);
NuError Nu_StrawRewind(NuArchive* pArchive, NuStraw* pStraw);
/* Lzc.c */
NuError Nu_CompressLZC12(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc);
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
NuError Nu_CompressLZC16(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc);
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
NuError Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc);
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc);
/* Lzw.c */
NuError Nu_CompressLZW1(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc);
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
NuError Nu_CompressLZW2(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc);
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
NuError Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pThreadCrc);
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel,
uint16_t* pThreadCrc);
/* MiscUtils.c */
/*extern const char* kNufxLibName;*/
extern NuCallback gNuGlobalErrorMessageHandler;
const char* Nu_StrError(NuError err);
void Nu_ReportError(NuArchive* pArchive, const char* file, int line,
const char* function, Boolean isDebug, NuError err, const char* format, ...)
const char* function, Boolean isDebug, NuError err,
const UNICHAR* format, ...)
#if defined(__GNUC__)
__attribute__ ((format(printf, 7, 8)))
#endif
@ -688,7 +693,7 @@ void Nu_ReportError(NuArchive* pArchive, const char* file, int line,
# define Nu_Malloc(archive, size) malloc(size)
# define Nu_Calloc(archive, size) calloc(1, size)
# define Nu_Realloc(archive, ptr, size) realloc(ptr, size)
# define Nu_Free(archive, ptr) (ptr != nil ? free(ptr) : (void)0)
# define Nu_Free(archive, ptr) (ptr != NULL ? free(ptr) : (void)0)
#else
void* Nu_Malloc(NuArchive* pArchive, size_t size);
void* Nu_Calloc(NuArchive* pArchive, size_t size);
@ -701,8 +706,8 @@ NuResult Nu_InternalFreeCallback(NuArchive* pArchive, void* args);
void Nu_RecordAddThreadMod(NuRecord* pRecord, NuThreadMod* pThreadMod);
Boolean Nu_RecordIsEmpty(NuArchive* pArchive, const NuRecord* pRecord);
Boolean Nu_RecordSet_GetLoaded(const NuRecordSet* pRecordSet);
ulong Nu_RecordSet_GetNumRecords(const NuRecordSet* pRecordSet);
void Nu_RecordSet_SetNumRecords(NuRecordSet* pRecordSet, ulong val);
uint32_t Nu_RecordSet_GetNumRecords(const NuRecordSet* pRecordSet);
void Nu_RecordSet_SetNumRecords(NuRecordSet* pRecordSet, uint32_t val);
void Nu_RecordSet_IncNumRecords(NuRecordSet* pRecordSet);
NuRecord* Nu_RecordSet_GetListHead(const NuRecordSet* pRecordSet);
NuRecord** Nu_RecordSet_GetListHeadPtr(NuRecordSet* pRecordSet);
@ -738,19 +743,19 @@ NuError Nu_Test(NuArchive* pArchive);
NuError Nu_TestRecord(NuArchive* pArchive, NuRecordIdx recIdx);
NuError Nu_GetRecord(NuArchive* pArchive, NuRecordIdx recordIdx,
const NuRecord** ppRecord);
NuError Nu_GetRecordIdxByName(NuArchive* pArchive, const char* name,
NuError Nu_GetRecordIdxByName(NuArchive* pArchive, const char* nameMOR,
NuRecordIdx* pRecordIdx);
NuError Nu_GetRecordIdxByPosition(NuArchive* pArchive, ulong position,
NuError Nu_GetRecordIdxByPosition(NuArchive* pArchive, uint32_t position,
NuRecordIdx* pRecordIdx);
NuError Nu_FindRecordForWriteByIdx(NuArchive* pArchive, NuRecordIdx recIdx,
NuRecord** ppFoundRecord);
NuError Nu_AddFile(NuArchive* pArchive, const char* pathname,
NuError Nu_AddFile(NuArchive* pArchive, const UNICHAR* pathnameUNI,
const NuFileDetails* pFileDetails, Boolean fromRsrcFork,
NuRecordIdx* pRecordIdx);
NuError Nu_AddRecord(NuArchive* pArchive, const NuFileDetails* pFileDetails,
NuRecordIdx* pRecordIdx, NuRecord** ppRecord);
NuError Nu_Rename(NuArchive* pArchive, NuRecordIdx recIdx,
const char* pathname, char fssep);
const char* pathnameMOR, char fssepMOR);
NuError Nu_SetRecordAttr(NuArchive* pArchive, NuRecordIdx recordIdx,
const NuRecordAttr* pRecordAttr);
NuError Nu_Delete(NuArchive* pArchive);
@ -758,88 +763,74 @@ NuError Nu_DeleteRecord(NuArchive* pArchive, NuRecordIdx rec);
/* SourceSink.c */
NuError Nu_DataSourceFile_New(NuThreadFormat threadFormat,
ulong otherLen, const char* pathname, Boolean isFromRsrcFork,
uint32_t otherLen, const UNICHAR* pathnameUNI, Boolean isFromRsrcFork,
NuDataSource** ppDataSource);
NuError Nu_DataSourceFP_New(NuThreadFormat threadFormat,
ulong otherLen, FILE* fp, long offset, long length,
uint32_t otherLen, FILE* fp, long offset, long length,
NuCallback fcloseFunc, NuDataSource** ppDataSource);
NuError Nu_DataSourceBuffer_New(NuThreadFormat threadFormat,
ulong otherLen, const uchar* buffer, long offset, long length,
uint32_t otherLen, const uint8_t* buffer, long offset, long length,
NuCallback freeFunc, NuDataSource** ppDataSource);
NuDataSource* Nu_DataSourceCopy(NuDataSource* pDataSource);
NuError Nu_DataSourceFree(NuDataSource* pDataSource);
NuDataSourceType Nu_DataSourceGetType(const NuDataSource* pDataSource);
NuThreadFormat Nu_DataSourceGetThreadFormat(const NuDataSource* pDataSource);
ulong Nu_DataSourceGetDataLen(const NuDataSource* pDataSource);
ulong Nu_DataSourceGetOtherLen(const NuDataSource* pDataSource);
uint32_t Nu_DataSourceGetDataLen(const NuDataSource* pDataSource);
uint32_t Nu_DataSourceGetOtherLen(const NuDataSource* pDataSource);
void Nu_DataSourceSetOtherLen(NuDataSource* pDataSource, long otherLen);
ushort Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource);
void Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, ushort crc);
uint16_t Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource);
void Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, uint16_t crc);
NuError Nu_DataSourcePrepareInput(NuArchive* pArchive,
NuDataSource* pDataSource);
void Nu_DataSourceUnPrepareInput(NuArchive* pArchive,
NuDataSource* pDataSource);
const char* Nu_DataSourceFile_GetPathname(NuDataSource* pDataSource);
NuError Nu_DataSourceGetBlock(NuDataSource* pDataSource, uchar* buf, ulong len);
NuError Nu_DataSourceGetBlock(NuDataSource* pDataSource, uint8_t* buf,
uint32_t len);
NuError Nu_DataSourceRewind(NuDataSource* pDataSource);
NuError Nu_DataSinkFile_New(Boolean doExpand, NuValue convertEOL,
const char* pathname, char fssep, NuDataSink** ppDataSink);
const UNICHAR* pathnameUNI, UNICHAR fssep, NuDataSink** ppDataSink);
NuError Nu_DataSinkFP_New(Boolean doExpand, NuValue convertEOL, FILE* fp,
NuDataSink** ppDataSink);
NuError Nu_DataSinkBuffer_New(Boolean doExpand, NuValue convertEOL,
uchar* buffer, ulong bufLen, NuDataSink** ppDataSink);
uint8_t* buffer, uint32_t bufLen, NuDataSink** ppDataSink);
NuError Nu_DataSinkVoid_New(Boolean doExpand, NuValue convertEOL,
NuDataSink** ppDataSink);
NuError Nu_DataSinkFree(NuDataSink* pDataSink);
NuDataSinkType Nu_DataSinkGetType(const NuDataSink* pDataSink);
Boolean Nu_DataSinkGetDoExpand(const NuDataSink* pDataSink);
NuValue Nu_DataSinkGetConvertEOL(const NuDataSink* pDataSink);
ulong Nu_DataSinkGetOutCount(const NuDataSink* pDataSink);
uint32_t Nu_DataSinkGetOutCount(const NuDataSink* pDataSink);
const char* Nu_DataSinkFile_GetPathname(const NuDataSink* pDataSink);
char Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink);
UNICHAR Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink);
FILE* Nu_DataSinkFile_GetFP(const NuDataSink* pDataSink);
void Nu_DataSinkFile_SetFP(NuDataSink* pDataSink, FILE* fp);
void Nu_DataSinkFile_Close(NuDataSink* pDataSink);
NuError Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uchar* buf, ulong len);
NuError Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uint8_t* buf,
uint32_t len);
NuError Nu_DataSinkGetError(NuDataSink* pDataSink);
/* Squeeze.c */
NuError Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc);
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc);
NuError Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc);
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc);
/* Thread.c */
#ifdef __Thread_c__
#define THREAD_INLINE /**/
#else
#define THREAD_INLINE extern inline
#endif
#if defined(inline) && !defined(__Thread_c__) /* somebody ovrd inline def? */
NuThread* Nu_GetThread(const NuRecord* pRecord, int idx);
#else
THREAD_INLINE NuThread*
Nu_GetThread(const NuRecord* pRecord, int idx)
{
if (idx >= (int)pRecord->recTotalThreads)
return nil;
else
return &pRecord->pThreads[idx];
}
#endif
void Nu_StripHiIfAllSet(char* str);
Boolean Nu_IsPresizedThreadID(NuThreadID threadID);
Boolean Nu_IsCompressibleThreadID(NuThreadID threadID);
Boolean Nu_ThreadHasCRC(long recordVersion, NuThreadID threadID);
Boolean Nu_ThreadHasCRC(uint16_t recordVersion, NuThreadID threadID);
NuError Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
NuThread** ppThread);
NuError Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
NuThread** ppThread);
void Nu_CopyThreadContents(NuThread* pDstThread, const NuThread* pSrcThread);
NuError Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord,
ushort* pCrc);
uint16_t* pCrc);
NuError Nu_WriteThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, FILE* fp,
ushort* pCrc);
uint16_t* pCrc);
NuError Nu_ComputeThreadData(NuArchive* pArchive, NuRecord* pRecord);
NuError Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord,long numThreads);
NuError Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
@ -853,7 +844,7 @@ NuError Nu_OkayToAddThread(NuArchive* pArchive, const NuRecord* pRecord,
NuError Nu_AddThread(NuArchive* pArchive, NuRecordIdx rec, NuThreadID threadID,
NuDataSource* pDataSource, NuThreadIdx* pThreadIdx);
NuError Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
NuDataSource* pDataSource, long* pMaxLen);
NuDataSource* pDataSource, int32_t* pMaxLen);
NuError Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx);
/* Value.c */
@ -864,7 +855,7 @@ NuThreadFormat Nu_ConvertCompressValToFormat(NuArchive* pArchive,
NuValue compValue);
/* Version.c */
NuError Nu_GetVersion(long* pMajorVersion, long* pMinorVersion,
long* pBugVersion, const char** ppBuildDate, const char** ppBuildFlags);
NuError Nu_GetVersion(int32_t* pMajorVersion, int32_t* pMinorVersion,
int32_t* pBugVersion, const char** ppBuildDate, const char** ppBuildFlags);
#endif /*__NufxLibPriv__*/
#endif /*NUFXLIB_NUFXLIBPRIV_H*/

View File

@ -1,4 +1,4 @@
NufxLib README, updated 2004/03/18
NufxLib README, updated 2014/12/23
http://www.nulib.com/
See "COPYING-LIB" for distribution restrictions.
@ -42,11 +42,8 @@ for @CFLAGS@ is "-g -O2".
(Implicitly sets DEBUG_MSGS.) Spray lots of debugging output.
If you want to do benchmarks, use "-O2 -DNDEBUG". The recommended
configuration during testing is "-g -O2 -DDEBUG_MSGS", so that verbose
debug output is available when errors occur.
The flags are stuffed into Version.c, so the application program can
examine and display the flags that were used to build the library.
configuration is "-g -O2 -DDEBUG_MSGS", so that verbose debug output is
available when errors occur.
BeOS
@ -67,14 +64,10 @@ If you're using BeOS/PPC, it will also do:
Mac OS X
========
This works just like the UNIX version, with the exception that when you link
against nufxlib, your project must also link against the Carbon framework.
This can be done in ProjectBuilder by using the Add Framework option in the
Project menu, or by adding "-framework Carbon" to the gcc command line.
This works just like the UNIX version, but includes support for resource
forks and Finder file/aux types.
You'll see some warnings due to some namespace collisions between nufxlib and
Carbon, but everything will work fine. Carbon is used to provide support for
file types and resource forks.
Tested with Xcode v5.1.1 and Mac OS 10.8.5.
Win32
@ -83,29 +76,24 @@ Win32
If you're using an environment that supports "configure" scripts, such as
DJGPP, follow the UNIX instructions.
NufxLib has been tested with Microsoft Visual C++ 6.0. To build NufxLib,
start up a DOS shell and run vcvars32.bat to set your environment. Run:
NufxLib has been tested with Microsoft Visual C++ 12 (Visual Studio 2013).
To build NufxLib, run the "Visual Studio 2013 x86 Native Tools Command
Prompt" shortcut to get a shell. Change to the nufxlib directory, then:
nmake -f makefile.msc
to build with debugging info, or
nmake -f makefile.msc nodebug=1
to build optimized.
See the makefile for comments about including zlib or libbz2. These
need to be enabled at compile time and linked into the sample apps.
When the build finishes, run "test-basic.exe" to confirm things are working.
Once the library has been built, "cd samples" and run the same command there.
When it finishes, run "test-basic.exe".
If you want to have zlib support enabled, you will need to have zlib.h,
zconf.h, and zlib.lib copied into the directory. See "makefile.msc" for
more details.
If you want to build NufxLib as a DLL, use "makefile.dll" instead.
If you're using zlib or libbz2, these will need to be linked into the DLL.
The makefile currently assumes that you will want to use zlib.dll.
The makefile builds NufxLib as a static library and as a DLL.
Other Notes
===========
All of the source code is now formatted with spaces instead of tabs.
If you want to use the library in a multithreaded application, you should
define "USE_REENTRANT_CALLS" to tell it to use reentrant versions of
certain library calls. This defines _REENTRANT, which causes Solaris to
@ -113,12 +101,19 @@ add the appropriate goodies. (Seems to me you'd always want this on, but
for some reason Solaris makes you take an extra step, so I'm not going to
define it by default.)
Originally, NufxLib / NuLib2 were intended to be usable natively on the
Apple IIgs, so some of the design decisions were influenced by the need
to minimize memory usage (e.g. being able to get a directory listing
without holding the entire directory in memory) and interact with GS/OS
(forked files have a single filename, files have type/auxtype). The IIgs
port was never started.
Legalese
========
NufxLib, a NuFX archive manipulation library.
Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
Copyright (C) 2000-2014 by Andy McFadden, All Rights Reserved.
See COPYING for license.

File diff suppressed because it is too large Load Diff

View File

@ -19,13 +19,12 @@
/*
* Allocate a new DataSource structure.
*/
static NuError
Nu_DataSourceNew(NuDataSource** ppDataSource)
static NuError Nu_DataSourceNew(NuDataSource** ppDataSource)
{
Assert(ppDataSource != nil);
Assert(ppDataSource != NULL);
*ppDataSource = Nu_Malloc(nil, sizeof(**ppDataSource));
if (*ppDataSource == nil)
*ppDataSource = Nu_Malloc(NULL, sizeof(**ppDataSource));
if (*ppDataSource == NULL)
return kNuErrMalloc;
(*ppDataSource)->sourceType = kNuDataSourceUnknown;
@ -47,10 +46,9 @@ Nu_DataSourceNew(NuDataSource** ppDataSource)
* needed in the first place.) Buffer sources are a little scary since
* they include a "curOffset" value.
*
* Returns nil on error.
* Returns NULL on error.
*/
NuDataSource*
Nu_DataSourceCopy(NuDataSource* pDataSource)
NuDataSource* Nu_DataSourceCopy(NuDataSource* pDataSource)
{
Assert(pDataSource->common.refCount >= 1);
pDataSource->common.refCount++;
@ -59,18 +57,18 @@ Nu_DataSourceCopy(NuDataSource* pDataSource)
#if 0 /* we used to copy them -- very bad idea */
NuDataSource* pNewDataSource;
Assert(pDataSource != nil);
Assert(pDataSource != NULL);
if (Nu_DataSourceNew(&pNewDataSource) != kNuErrNone)
return nil;
Assert(pNewDataSource != nil);
return NULL;
Assert(pNewDataSource != NULL);
/* this gets most of it */
memcpy(pNewDataSource, pDataSource, sizeof(*pNewDataSource));
/* copy anything we're sure to free up */
if (pDataSource->sourceType == kNuDataSourceFromFile) {
Assert(pDataSource->fromFile.fp == nil); /* does this matter? */
Assert(pDataSource->fromFile.fp == NULL); /* does this matter? */
pNewDataSource->fromFile.pathname =
strdup(pDataSource->fromFile.pathname);
}
@ -89,10 +87,9 @@ Nu_DataSourceCopy(NuDataSource* pDataSource)
/*
* Free a data source structure, and any type-specific elements.
*/
NuError
Nu_DataSourceFree(NuDataSource* pDataSource)
NuError Nu_DataSourceFree(NuDataSource* pDataSource)
{
if (pDataSource == nil)
if (pDataSource == NULL)
return kNuErrNone;
Assert(pDataSource->common.refCount > 0);
@ -103,25 +100,25 @@ Nu_DataSourceFree(NuDataSource* pDataSource)
switch (pDataSource->sourceType) {
case kNuDataSourceFromFile:
Nu_Free(nil, pDataSource->fromFile.pathname);
if (pDataSource->fromFile.fp != nil) {
Nu_Free(NULL, pDataSource->fromFile.pathnameUNI);
if (pDataSource->fromFile.fp != NULL) {
fclose(pDataSource->fromFile.fp);
pDataSource->fromFile.fp = nil;
pDataSource->fromFile.fp = NULL;
}
break;
case kNuDataSourceFromFP:
if (pDataSource->fromFP.fcloseFunc != nil &&
pDataSource->fromFP.fp != nil)
if (pDataSource->fromFP.fcloseFunc != NULL &&
pDataSource->fromFP.fp != NULL)
{
(*pDataSource->fromFP.fcloseFunc)(nil, pDataSource->fromFP.fp);
pDataSource->fromFP.fp = nil;
(*pDataSource->fromFP.fcloseFunc)(NULL, pDataSource->fromFP.fp);
pDataSource->fromFP.fp = NULL;
}
break;
case kNuDataSourceFromBuffer:
if (pDataSource->fromBuffer.freeFunc != nil) {
(*pDataSource->fromBuffer.freeFunc)(nil,
if (pDataSource->fromBuffer.freeFunc != NULL) {
(*pDataSource->fromBuffer.freeFunc)(NULL,
(void*)pDataSource->fromBuffer.buffer);
pDataSource->fromBuffer.buffer = nil;
pDataSource->fromBuffer.buffer = NULL;
}
break;
case kNuDataSourceUnknown:
@ -131,7 +128,7 @@ Nu_DataSourceFree(NuDataSource* pDataSource)
return kNuErrInternal;
}
Nu_Free(nil, pDataSource);
Nu_Free(NULL, pDataSource);
return kNuErrNone;
}
@ -139,15 +136,15 @@ Nu_DataSourceFree(NuDataSource* pDataSource)
/*
* Create a data source for an unopened file.
*/
NuError
Nu_DataSourceFile_New(NuThreadFormat threadFormat, ulong otherLen,
const char* pathname, Boolean isFromRsrcFork, NuDataSource** ppDataSource)
NuError Nu_DataSourceFile_New(NuThreadFormat threadFormat, uint32_t otherLen,
const UNICHAR* pathnameUNI, Boolean isFromRsrcFork,
NuDataSource** ppDataSource)
{
NuError err;
if (pathname == nil ||
if (pathnameUNI == NULL ||
!(isFromRsrcFork == true || isFromRsrcFork == false) ||
ppDataSource == nil)
ppDataSource == NULL)
{
return kNuErrInvalidArg;
}
@ -162,9 +159,9 @@ Nu_DataSourceFile_New(NuThreadFormat threadFormat, ulong otherLen,
(*ppDataSource)->common.otherLen = otherLen;
(*ppDataSource)->common.refCount = 1;
(*ppDataSource)->fromFile.pathname = strdup(pathname);
(*ppDataSource)->fromFile.pathnameUNI = strdup(pathnameUNI);
(*ppDataSource)->fromFile.fromRsrcFork = isFromRsrcFork;
(*ppDataSource)->fromFile.fp = nil; /* to be filled in later */
(*ppDataSource)->fromFile.fp = NULL; /* to be filled in later */
bail:
return err;
@ -175,20 +172,19 @@ bail:
* Create a data source for an open file at a specific offset. The FILE*
* must be seekable.
*/
NuError
Nu_DataSourceFP_New(NuThreadFormat threadFormat, ulong otherLen,
NuError Nu_DataSourceFP_New(NuThreadFormat threadFormat, uint32_t otherLen,
FILE* fp, long offset, long length, NuCallback fcloseFunc,
NuDataSource** ppDataSource)
{
NuError err;
if (fp == nil || offset < 0 || length < 0 ||
ppDataSource == nil)
if (fp == NULL || offset < 0 || length < 0 ||
ppDataSource == NULL)
{
return kNuErrInvalidArg;
}
if (otherLen && otherLen < (ulong)length) {
if (otherLen && otherLen < (uint32_t)length) {
DBUG(("--- rejecting FP len=%ld other=%ld\n", length, otherLen));
err = kNuErrPreSizeOverflow;
goto bail;
@ -216,28 +212,27 @@ bail:
/*
* Create a data source for a buffer.
*
* We allow "buffer" to be nil so long as "offset" and "length" are also
* nil. This is useful for creating empty pre-sized buffers, such as
* We allow "buffer" to be NULL so long as "offset" and "length" are also
* NULL. This is useful for creating empty pre-sized buffers, such as
* blank comment fields.
*/
NuError
Nu_DataSourceBuffer_New(NuThreadFormat threadFormat, ulong otherLen,
const uchar* buffer, long offset, long length, NuCallback freeFunc,
NuError Nu_DataSourceBuffer_New(NuThreadFormat threadFormat, uint32_t otherLen,
const uint8_t* buffer, long offset, long length, NuCallback freeFunc,
NuDataSource** ppDataSource)
{
NuError err;
if (offset < 0 || length < 0 || ppDataSource == nil)
if (offset < 0 || length < 0 || ppDataSource == NULL)
return kNuErrInvalidArg;
if (buffer == nil && (offset != 0 || length != 0))
if (buffer == NULL && (offset != 0 || length != 0))
return kNuErrInvalidArg;
if (buffer == nil) {
if (buffer == NULL) {
DBUG(("+++ zeroing freeFunc for empty-buffer DataSource\n"));
freeFunc = nil;
freeFunc = NULL;
}
if (otherLen && otherLen < (ulong)length) {
if (otherLen && otherLen < (uint32_t)length) {
DBUG(("--- rejecting buffer len=%ld other=%ld\n", length, otherLen));
err = kNuErrPreSizeOverflow;
goto bail;
@ -267,34 +262,31 @@ bail:
/*
* Get the type of a NuDataSource.
*/
NuDataSourceType
Nu_DataSourceGetType(const NuDataSource* pDataSource)
NuDataSourceType Nu_DataSourceGetType(const NuDataSource* pDataSource)
{
Assert(pDataSource != nil);
Assert(pDataSource != NULL);
return pDataSource->sourceType;
}
/*
* Get the threadFormat for a data source.
*/
NuThreadFormat
Nu_DataSourceGetThreadFormat(const NuDataSource* pDataSource)
NuThreadFormat Nu_DataSourceGetThreadFormat(const NuDataSource* pDataSource)
{
Assert(pDataSource != nil);
Assert(pDataSource != NULL);
return pDataSource->common.threadFormat;
}
/*
* Get "dataLen" from a dataSource.
*/
ulong
Nu_DataSourceGetDataLen(const NuDataSource* pDataSource)
uint32_t Nu_DataSourceGetDataLen(const NuDataSource* pDataSource)
{
Assert(pDataSource != nil);
Assert(pDataSource != NULL);
if (pDataSource->sourceType == kNuDataSourceFromFile) {
/* dataLen can only be valid if file has been opened */
Assert(pDataSource->fromFile.fp != nil);
Assert(pDataSource->fromFile.fp != NULL);
}
return pDataSource->common.dataLen;
@ -303,20 +295,18 @@ Nu_DataSourceGetDataLen(const NuDataSource* pDataSource)
/*
* Get "otherLen" from a dataSource.
*/
ulong
Nu_DataSourceGetOtherLen(const NuDataSource* pDataSource)
uint32_t Nu_DataSourceGetOtherLen(const NuDataSource* pDataSource)
{
Assert(pDataSource != nil);
Assert(pDataSource != NULL);
return pDataSource->common.otherLen;
}
/*
* Change the "otherLen" value.
*/
void
Nu_DataSourceSetOtherLen(NuDataSource* pDataSource, long otherLen)
void Nu_DataSourceSetOtherLen(NuDataSource* pDataSource, long otherLen)
{
Assert(pDataSource != nil && otherLen > 0);
Assert(pDataSource != NULL && otherLen > 0);
pDataSource->common.otherLen = otherLen;
}
@ -324,10 +314,9 @@ Nu_DataSourceSetOtherLen(NuDataSource* pDataSource, long otherLen)
/*
* Get the "raw CRC" value.
*/
ushort
Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource)
uint16_t Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource)
{
Assert(pDataSource != nil);
Assert(pDataSource != NULL);
return pDataSource->common.rawCrc;
}
@ -335,10 +324,9 @@ Nu_DataSourceGetRawCrc(const NuDataSource* pDataSource)
* Set the "raw CRC" value. You would want to do this if the input was
* already-compressed data, and you wanted to propagate the thread CRC.
*/
void
Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, ushort crc)
void Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, uint16_t crc)
{
Assert(pDataSource != nil);
Assert(pDataSource != NULL);
pDataSource->common.rawCrc = crc;
}
@ -346,11 +334,11 @@ Nu_DataSourceSetRawCrc(NuDataSource* pDataSource, ushort crc)
/*
* Prepare a data source for action.
*/
NuError
Nu_DataSourcePrepareInput(NuArchive* pArchive, NuDataSource* pDataSource)
NuError Nu_DataSourcePrepareInput(NuArchive* pArchive,
NuDataSource* pDataSource)
{
NuError err = kNuErrNone;
FILE* fileFp = nil;
FILE* fileFp = NULL;
/*
* Doesn't apply to buffer sources.
@ -372,11 +360,11 @@ Nu_DataSourcePrepareInput(NuArchive* pArchive, NuDataSource* pDataSource)
* We're adding from a file on disk. Open it.
*/
err = Nu_OpenInputFile(pArchive,
pDataSource->fromFile.pathname, pDataSource->fromFile.fromRsrcFork,
&fileFp);
pDataSource->fromFile.pathnameUNI,
pDataSource->fromFile.fromRsrcFork, &fileFp);
BailError(err);
Assert(fileFp != nil);
Assert(fileFp != NULL);
pDataSource->fromFile.fp = fileFp;
err = Nu_GetFileLength(pArchive, fileFp,
(long*)&pDataSource->common.dataLen);
@ -403,49 +391,47 @@ bail:
* call will take care of this eventually -- but for normal operation on
* a large number of files, it's vital.
*/
void
Nu_DataSourceUnPrepareInput(NuArchive* pArchive, NuDataSource* pDataSource)
void Nu_DataSourceUnPrepareInput(NuArchive* pArchive, NuDataSource* pDataSource)
{
if (Nu_DataSourceGetType(pDataSource) != kNuDataSourceFromFile)
return;
if (pDataSource->fromFile.fp != nil) {
if (pDataSource->fromFile.fp != NULL) {
fclose(pDataSource->fromFile.fp);
pDataSource->fromFile.fp = nil;
pDataSource->fromFile.fp = NULL;
pDataSource->common.dataLen = 0;
}
}
/*
* Get the pathname from a "from-file" dataSource.
* Get the pathname from a "from-file" dataSource. Returned string is UTF-8.
*/
const char*
Nu_DataSourceFile_GetPathname(NuDataSource* pDataSource)
const char* Nu_DataSourceFile_GetPathname(NuDataSource* pDataSource)
{
Assert(pDataSource != nil);
Assert(pDataSource != NULL);
Assert(pDataSource->sourceType == kNuDataSourceFromFile);
Assert(pDataSource->fromFile.pathname != nil);
Assert(pDataSource->fromFile.pathnameUNI != NULL);
return pDataSource->fromFile.pathname;
return pDataSource->fromFile.pathnameUNI;
}
/*
* Read a block of data from a dataSource.
*/
NuError
Nu_DataSourceGetBlock(NuDataSource* pDataSource, uchar* buf, ulong len)
NuError Nu_DataSourceGetBlock(NuDataSource* pDataSource, uint8_t* buf,
uint32_t len)
{
NuError err;
Assert(pDataSource != nil);
Assert(buf != nil);
Assert(pDataSource != NULL);
Assert(buf != NULL);
Assert(len > 0);
switch (pDataSource->sourceType) {
case kNuDataSourceFromFile:
Assert(pDataSource->fromFile.fp != nil);
Assert(pDataSource->fromFile.fp != NULL);
err = Nu_FRead(pDataSource->fromFile.fp, buf, len);
if (feof(pDataSource->fromFile.fp))
Nu_ReportError(NU_NILBLOB, err, "EOF hit unexpectedly");
@ -479,16 +465,15 @@ Nu_DataSourceGetBlock(NuDataSource* pDataSource, uchar* buf, ulong len)
/*
* Rewind a data source to the start of its input.
*/
NuError
Nu_DataSourceRewind(NuDataSource* pDataSource)
NuError Nu_DataSourceRewind(NuDataSource* pDataSource)
{
NuError err;
Assert(pDataSource != nil);
Assert(pDataSource != NULL);
switch (pDataSource->sourceType) {
case kNuDataSourceFromFile:
Assert(pDataSource->fromFile.fp != nil);
Assert(pDataSource->fromFile.fp != NULL);
err = Nu_FSeek(pDataSource->fromFile.fp, 0, SEEK_SET);
break; /* fall through with error */
case kNuDataSourceFromFP:
@ -518,13 +503,12 @@ Nu_DataSourceRewind(NuDataSource* pDataSource)
/*
* Allocate a new DataSink structure.
*/
static NuError
Nu_DataSinkNew(NuDataSink** ppDataSink)
static NuError Nu_DataSinkNew(NuDataSink** ppDataSink)
{
Assert(ppDataSink != nil);
Assert(ppDataSink != NULL);
*ppDataSink = Nu_Malloc(nil, sizeof(**ppDataSink));
if (*ppDataSink == nil)
*ppDataSink = Nu_Malloc(NULL, sizeof(**ppDataSink));
if (*ppDataSink == NULL)
return kNuErrMalloc;
(*ppDataSink)->sinkType = kNuDataSinkUnknown;
@ -536,16 +520,15 @@ Nu_DataSinkNew(NuDataSink** ppDataSink)
/*
* Free a data sink structure, and any type-specific elements.
*/
NuError
Nu_DataSinkFree(NuDataSink* pDataSink)
NuError Nu_DataSinkFree(NuDataSink* pDataSink)
{
if (pDataSink == nil)
if (pDataSink == NULL)
return kNuErrNone;
switch (pDataSink->sinkType) {
case kNuDataSinkToFile:
Nu_DataSinkFile_Close(pDataSink);
Nu_Free(nil, pDataSink->toFile.pathname);
Nu_Free(NULL, pDataSink->toFile.pathnameUNI);
break;
case kNuDataSinkToFP:
break;
@ -560,7 +543,7 @@ Nu_DataSinkFree(NuDataSink* pDataSink)
return kNuErrInternal;
}
Nu_Free(nil, pDataSink);
Nu_Free(NULL, pDataSink);
return kNuErrNone;
}
@ -568,18 +551,17 @@ Nu_DataSinkFree(NuDataSink* pDataSink)
/*
* Create a data sink for an unopened file.
*/
NuError
Nu_DataSinkFile_New(Boolean doExpand, NuValue convertEOL, const char* pathname,
char fssep, NuDataSink** ppDataSink)
NuError Nu_DataSinkFile_New(Boolean doExpand, NuValue convertEOL,
const UNICHAR* pathnameUNI, UNICHAR fssep, NuDataSink** ppDataSink)
{
NuError err;
if ((doExpand != true && doExpand != false) ||
(convertEOL != kNuConvertOff && convertEOL != kNuConvertOn &&
convertEOL != kNuConvertAuto) ||
pathname == nil ||
pathnameUNI == NULL ||
fssep == 0 ||
ppDataSink == nil)
ppDataSink == NULL)
{
return kNuErrInvalidArg;
}
@ -594,10 +576,10 @@ Nu_DataSinkFile_New(Boolean doExpand, NuValue convertEOL, const char* pathname,
else
(*ppDataSink)->common.convertEOL = kNuConvertOff;
(*ppDataSink)->common.outCount = 0;
(*ppDataSink)->toFile.pathname = strdup(pathname);
(*ppDataSink)->toFile.pathnameUNI = strdup(pathnameUNI);
(*ppDataSink)->toFile.fssep = fssep;
(*ppDataSink)->toFile.fp = nil;
(*ppDataSink)->toFile.fp = NULL;
bail:
return err;
@ -607,8 +589,7 @@ bail:
/*
* Create a data sink based on a file pointer.
*/
NuError
Nu_DataSinkFP_New(Boolean doExpand, NuValue convertEOL, FILE* fp,
NuError Nu_DataSinkFP_New(Boolean doExpand, NuValue convertEOL, FILE* fp,
NuDataSink** ppDataSink)
{
NuError err;
@ -616,8 +597,8 @@ Nu_DataSinkFP_New(Boolean doExpand, NuValue convertEOL, FILE* fp,
if ((doExpand != true && doExpand != false) ||
(convertEOL != kNuConvertOff && convertEOL != kNuConvertOn &&
convertEOL != kNuConvertAuto) ||
fp == nil ||
ppDataSink == nil)
fp == NULL ||
ppDataSink == NULL)
{
return kNuErrInvalidArg;
}
@ -642,18 +623,17 @@ bail:
/*
* Create a data sink for a buffer in memory.
*/
NuError
Nu_DataSinkBuffer_New(Boolean doExpand, NuValue convertEOL, uchar* buffer,
ulong bufLen, NuDataSink** ppDataSink)
NuError Nu_DataSinkBuffer_New(Boolean doExpand, NuValue convertEOL,
uint8_t* buffer, uint32_t bufLen, NuDataSink** ppDataSink)
{
NuError err;
if ((doExpand != true && doExpand != false) ||
(convertEOL != kNuConvertOff && convertEOL != kNuConvertOn &&
convertEOL != kNuConvertAuto) ||
buffer == nil ||
buffer == NULL ||
bufLen == 0 ||
ppDataSink == nil)
ppDataSink == NULL)
{
return kNuErrInvalidArg;
}
@ -681,14 +661,13 @@ bail:
/*
* Create a data sink that goes nowhere.
*/
NuError
Nu_DataSinkVoid_New(Boolean doExpand, NuValue convertEOL,
NuError Nu_DataSinkVoid_New(Boolean doExpand, NuValue convertEOL,
NuDataSink** ppDataSink)
{
NuError err;
Assert(doExpand == true || doExpand == false);
Assert(ppDataSink != nil);
Assert(ppDataSink != NULL);
err = Nu_DataSinkNew(ppDataSink);
BailErrorQuiet(err);
@ -706,10 +685,9 @@ bail:
/*
* Get the type of a NuDataSink.
*/
NuDataSinkType
Nu_DataSinkGetType(const NuDataSink* pDataSink)
NuDataSinkType Nu_DataSinkGetType(const NuDataSink* pDataSink)
{
Assert(pDataSink != nil);
Assert(pDataSink != NULL);
return pDataSink->sinkType;
}
@ -717,8 +695,7 @@ Nu_DataSinkGetType(const NuDataSink* pDataSink)
/*
* Return the "doExpand" parameter from any kind of sink.
*/
Boolean
Nu_DataSinkGetDoExpand(const NuDataSink* pDataSink)
Boolean Nu_DataSinkGetDoExpand(const NuDataSink* pDataSink)
{
return pDataSink->common.doExpand;
}
@ -726,8 +703,7 @@ Nu_DataSinkGetDoExpand(const NuDataSink* pDataSink)
/*
* Return the "convertEOL" parameter from any kind of sink.
*/
NuValue
Nu_DataSinkGetConvertEOL(const NuDataSink* pDataSink)
NuValue Nu_DataSinkGetConvertEOL(const NuDataSink* pDataSink)
{
return pDataSink->common.convertEOL;
}
@ -735,32 +711,29 @@ Nu_DataSinkGetConvertEOL(const NuDataSink* pDataSink)
/*
* Return the #of bytes written to the sink.
*/
ulong
Nu_DataSinkGetOutCount(const NuDataSink* pDataSink)
uint32_t Nu_DataSinkGetOutCount(const NuDataSink* pDataSink)
{
return pDataSink->common.outCount;
}
/*
* Get "pathname" from a to-file sink.
* Get "pathname" from a to-file sink. Returned string is UTF-8.
*/
const char*
Nu_DataSinkFile_GetPathname(const NuDataSink* pDataSink)
const char* Nu_DataSinkFile_GetPathname(const NuDataSink* pDataSink)
{
Assert(pDataSink != nil);
Assert(pDataSink != NULL);
Assert(pDataSink->sinkType == kNuDataSinkToFile);
return pDataSink->toFile.pathname;
return pDataSink->toFile.pathnameUNI;
}
/*
* Get "fssep" from a to-file sink.
*/
char
Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink)
UNICHAR Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink)
{
Assert(pDataSink != nil);
Assert(pDataSink != NULL);
Assert(pDataSink->sinkType == kNuDataSinkToFile);
return pDataSink->toFile.fssep;
@ -769,10 +742,9 @@ Nu_DataSinkFile_GetFssep(const NuDataSink* pDataSink)
/*
* Get the "fp" for a file sink.
*/
FILE*
Nu_DataSinkFile_GetFP(const NuDataSink* pDataSink)
FILE* Nu_DataSinkFile_GetFP(const NuDataSink* pDataSink)
{
Assert(pDataSink != nil);
Assert(pDataSink != NULL);
Assert(pDataSink->sinkType == kNuDataSinkToFile);
return pDataSink->toFile.fp;
@ -781,10 +753,9 @@ Nu_DataSinkFile_GetFP(const NuDataSink* pDataSink)
/*
* Set the "fp" for a file sink.
*/
void
Nu_DataSinkFile_SetFP(NuDataSink* pDataSink, FILE* fp)
void Nu_DataSinkFile_SetFP(NuDataSink* pDataSink, FILE* fp)
{
Assert(pDataSink != nil);
Assert(pDataSink != NULL);
Assert(pDataSink->sinkType == kNuDataSinkToFile);
pDataSink->toFile.fp = fp;
@ -793,14 +764,13 @@ Nu_DataSinkFile_SetFP(NuDataSink* pDataSink, FILE* fp)
/*
* Close a to-file sink.
*/
void
Nu_DataSinkFile_Close(NuDataSink* pDataSink)
void Nu_DataSinkFile_Close(NuDataSink* pDataSink)
{
Assert(pDataSink != nil);
Assert(pDataSink != NULL);
if (pDataSink->toFile.fp != nil) {
if (pDataSink->toFile.fp != NULL) {
fclose(pDataSink->toFile.fp);
pDataSink->toFile.fp = nil;
pDataSink->toFile.fp = NULL;
}
}
@ -808,24 +778,24 @@ Nu_DataSinkFile_Close(NuDataSink* pDataSink)
/*
* Write a block of data to a DataSink.
*/
NuError
Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uchar* buf, ulong len)
NuError Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uint8_t* buf,
uint32_t len)
{
NuError err;
Assert(pDataSink != nil);
Assert(buf != nil);
Assert(pDataSink != NULL);
Assert(buf != NULL);
Assert(len > 0);
switch (pDataSink->sinkType) {
case kNuDataSinkToFile:
Assert(pDataSink->toFile.fp != nil);
Assert(pDataSink->toFile.fp != NULL);
err = Nu_FWrite(pDataSink->toFile.fp, buf, len);
if (err != kNuErrNone)
return err;
break;
case kNuDataSinkToFP:
Assert(pDataSink->toFP.fp != nil);
Assert(pDataSink->toFP.fp != NULL);
err = Nu_FWrite(pDataSink->toFP.fp, buf, len);
if (err != kNuErrNone)
return err;
@ -856,12 +826,11 @@ Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uchar* buf, ulong len)
/*
* Figure out if one of our earlier writes has failed.
*/
NuError
Nu_DataSinkGetError(NuDataSink* pDataSink)
NuError Nu_DataSinkGetError(NuDataSink* pDataSink)
{
NuError err = kNuErrNone;
Assert(pDataSink != nil);
Assert(pDataSink != NULL);
switch (pDataSink->sinkType) {
case kNuDataSinkToFile:

View File

@ -77,13 +77,13 @@ typedef struct EncTreeNode {
typedef struct SQState {
NuArchive* pArchive;
int doCalcCRC; /* boolean; if set, compute CRC on input */
ushort crc;
uint16_t crc;
NuStraw* pStraw;
long uncompRemaining;
#ifdef FULL_SQ_HEADER
ushort checksum;
uint16_t checksum;
#endif
/*
@ -98,12 +98,12 @@ typedef struct SQState {
*/
EncTreeNode node[kNuSQNumNodes];
int treeHead; /* index to head node of final tree */
int treeHead; /* index to head node of final tree */
/* encoding table */
int codeLen[kNuSQNumVals]; /* number of bits in code for symbol N */
ushort code[kNuSQNumVals]; /* bits for symbol N (first bit in lsb) */
ushort tmpCode; /* temporary code value */
uint16_t code[kNuSQNumVals]; /* bits for symbol N (first bit in lsb) */
uint16_t tmpCode; /* temporary code value */
} SQState;
@ -117,11 +117,10 @@ typedef struct SQState {
*
* Returns kNuSQEOFToken as the value when we're out of data.
*/
static NuError
Nu_SQGetcCRC(SQState* pSqState, int* pSym)
static NuError Nu_SQGetcCRC(SQState* pSqState, int* pSym)
{
NuError err;
uchar c;
uint8_t c;
if (!pSqState->uncompRemaining) {
*pSym = kNuSQEOFToken;
@ -148,8 +147,7 @@ Nu_SQGetcCRC(SQState* pSqState, int* pSym)
*
* Returns kNuSQEOFToken in "*pSum" when we reach the end of the input.
*/
static NuError
Nu_SQGetcRLE(SQState* pSqState, int* pSym)
static NuError Nu_SQGetcRLE(SQState* pSqState, int* pSym)
{
NuError err = kNuErrNone;
int likeCount, newSym;
@ -275,8 +273,7 @@ bail:
/*
* Return the greater of two integers.
*/
static int
Nu_SQMax(int a, int b)
static int Nu_SQMax(int a, int b)
{
if (a > b)
return a;
@ -289,8 +286,7 @@ Nu_SQMax(int a, int b)
* Priority is given to weight, then depth. "a" and "b" are heaps,
* so we only need to look at the root element.
*/
static int
Nu_SQCmpTrees(SQState* pSqState, int a, int b)
static int Nu_SQCmpTrees(SQState* pSqState, int a, int b)
{
if (pSqState->node[a].weight > pSqState->node[b].weight)
return true;
@ -312,8 +308,7 @@ Nu_SQCmpTrees(SQState* pSqState, int a, int b)
/*
* Recursively make a heap from a heap with a new top.
*/
static void
Nu_SQHeapAdjust(SQState* pSqState, int list[], int top, int bottom)
static void Nu_SQHeapAdjust(SQState* pSqState, int list[], int top, int bottom)
{
int k, temp;
@ -337,8 +332,7 @@ Nu_SQHeapAdjust(SQState* pSqState, int list[], int top, int bottom)
/*
* Create a heap.
*/
static void
Nu_SQHeap(SQState* pSqState, int list[], int length)
static void Nu_SQHeap(SQState* pSqState, int list[], int length)
{
int i;
@ -365,8 +359,7 @@ Nu_SQHeap(SQState* pSqState, int list[], int length)
* moving the last element over the top element and
* reheaping the shorter list.
*/
static void
Nu_SQBuildTree(SQState* pSqState, int list[], int len)
static void Nu_SQBuildTree(SQState* pSqState, int list[], int len)
{
int freenode; /* next free node in tree */
EncTreeNode* frnp; /* free node pointer */
@ -422,8 +415,7 @@ Nu_SQBuildTree(SQState* pSqState, int list[], int len)
*
* Returns zero on success, nonzero if codes are too long.
*/
static int
Nu_SQBuildEncTable(SQState* pSqState, int level, int root)
static int Nu_SQBuildEncTable(SQState* pSqState, int level, int root)
{
int l, r;
@ -437,7 +429,7 @@ Nu_SQBuildEncTable(SQState* pSqState, int level, int root)
*/
pSqState->codeLen[root] = level;
pSqState->code[root] =
pSqState->tmpCode & (((ushort)~0) >> (16 - level));
pSqState->tmpCode & (((uint16_t)~0) >> (16 - level));
return (level > 16) ? -1 : 0;
} else {
if (l != kNuSQNoChild) {
@ -470,12 +462,11 @@ Nu_SQBuildEncTable(SQState* pSqState, int level, int root)
* the codes will fit in an unsigned integer. Rescaling is
* used if necessary to limit the code length.
*/
static void
Nu_SQScale(SQState* pSqState, int ceiling)
static void Nu_SQScale(SQState* pSqState, int ceiling)
{
int i;
int wt, ovflw, divisor;
ushort sum;
uint16_t sum;
int increased; /* flag */
do {
@ -510,8 +501,7 @@ Nu_SQScale(SQState* pSqState, int ceiling)
* Build a frequency table from the post-RLE input stream, then generate
* an encoding tree from the results.
*/
static NuError
Nu_SQComputeHuffTree(SQState* pSqState)
static NuError Nu_SQComputeHuffTree(SQState* pSqState)
{
NuError err = kNuErrNone;
int btreeList[kNuSQNumVals]; /* list of intermediate binary trees */
@ -610,12 +600,12 @@ bail:
* Compress data from input to output, using the values in the "code"
* and "codeLen" arrays.
*/
static NuError
Nu_SQCompressInput(SQState* pSqState, FILE* fp, long* pCompressedLen)
static NuError Nu_SQCompressInput(SQState* pSqState, FILE* fp,
long* pCompressedLen)
{
NuError err = kNuErrNone;
int sym = kNuSQEOFToken-1;
unsigned long bits, code; /* must hold at least 23 bits */
uint32_t bits, code; /* must hold at least 23 bits */
int codeLen, gotbits;
long compressedLen;
@ -661,11 +651,10 @@ bail:
/*
* Write a 16-bit value in little-endian order.
*/
static NuError
Nu_SQWriteShort(FILE* outfp, short val)
static NuError Nu_SQWriteShort(FILE* outfp, short val)
{
NuError err;
uchar tmpc;
uint8_t tmpc;
tmpc = val & 0xff;
err = Nu_FWrite(outfp, &tmpc, 1);
@ -689,9 +678,8 @@ bail:
* it an empty file. "xsq" works fine, creating an empty tree that
* "xusq" unpacks.
*/
NuError
Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
ulong srcLen, ulong* pDstLen, ushort* pCrc)
NuError Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
uint32_t srcLen, uint32_t* pDstLen, uint16_t* pCrc)
{
NuError err = kNuErrNone;
SQState sqState;
@ -704,7 +692,7 @@ Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
sqState.pArchive = pArchive;
sqState.crc = 0;
if (pCrc == nil) {
if (pCrc == NULL) {
sqState.doCalcCRC = false;
} else {
sqState.doCalcCRC = true;
@ -727,7 +715,7 @@ Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
err = Nu_SQComputeHuffTree(&sqState);
BailError(err);
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = sqState.crc;
/*
@ -822,8 +810,8 @@ bail:
* State during uncompression.
*/
typedef struct USQState {
ulong dataInBuffer;
uchar* dataPtr;
uint32_t dataInBuffer;
uint8_t* dataPtr;
int bitPosn;
int bits;
@ -842,8 +830,7 @@ typedef struct USQState {
/*
* Decode the next symbol from the Huffman stream.
*/
static NuError
Nu_USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
static NuError Nu_USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
{
short val = 0;
int bits, bitPosn;
@ -879,8 +866,7 @@ Nu_USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
/*
* Read two bytes of signed data out of the buffer.
*/
static inline NuError
Nu_USQReadShort(USQState* pUsqState, short* pShort)
static inline NuError Nu_USQReadShort(USQState* pUsqState, short* pShort)
{
if (pUsqState->dataInBuffer < 2)
return kNuErrBufferUnderrun;
@ -898,24 +884,23 @@ Nu_USQReadShort(USQState* pUsqState, short* pShort)
* Because we have a stop symbol, knowing the uncompressed length of
* the file is not essential.
*/
NuError
Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc)
NuError Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, uint16_t* pCrc)
{
NuError err = kNuErrNone;
USQState usqState;
ulong compRemaining, getSize;
uint32_t compRemaining, getSize;
#ifdef FULL_SQ_HEADER
ushort magic, fileChecksum, checksum;
uint16_t magic, fileChecksum, checksum;
#endif
short nodeCount;
int i, inrep;
uchar lastc = 0;
uint8_t lastc = 0;
err = Nu_AllocCompressionBufferIFN(pArchive);
if (err != kNuErrNone)
return err;
Assert(pArchive->compBuf != nil);
Assert(pArchive->compBuf != NULL);
usqState.dataInBuffer = 0;
usqState.dataPtr = pArchive->compBuf;
@ -945,7 +930,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
err = Nu_FRead(infp, usqState.dataPtr, getSize);
if (err != kNuErrNone) {
Nu_ReportError(NU_BLOB, err,
"failed reading compressed data (%ld bytes)", getSize);
"failed reading compressed data (%u bytes)", getSize);
goto bail;
}
usqState.dataInBuffer += getSize;
@ -1046,7 +1031,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
getSize);
if (err != kNuErrNone) {
Nu_ReportError(NU_BLOB, err,
"failed reading compressed data (%ld bytes)", getSize);
"failed reading compressed data (%u bytes)", getSize);
goto bail;
}
usqState.dataInBuffer += getSize;
@ -1080,7 +1065,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
val = 2;
}
while (--val) {
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1);
err = Nu_FunnelWrite(pArchive, pFunnel, &lastc, 1);
#ifdef FULL_SQ_HEADER
@ -1095,7 +1080,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
inrep = true;
} else {
lastc = val;
if (pCrc != nil)
if (pCrc != NULL)
*pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1);
err = Nu_FunnelWrite(pArchive, pFunnel, &lastc, 1);
#ifdef FULL_SQ_HEADER
@ -1135,7 +1120,7 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
if (usqState.dataInBuffer > 1) {
DBUG(("--- Found %ld bytes following compressed data (compRem=%ld)\n",
usqState.dataInBuffer, compRemaining));
Nu_ReportError(NU_BLOB, kNuErrNone, "(Warning) unexpected fluff (%ld)",
Nu_ReportError(NU_BLOB, kNuErrNone, "(Warning) unexpected fluff (%u)",
usqState.dataInBuffer);
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING-LIB.
*
* This file was adapted from Devin Reade's "sunos4.h" in NuLib 3.2.5.
* It is provided for compilation under SunOS 4.x, when an ANSI compiler
* (such as gcc) is used. The system header files aren't quite sufficient
* to eliminate hordes of warnings.
*/
#ifndef __SunOS4__
#define __SunOS4__
#ifdef __GNUC__
extern int _flsbuf(int, FILE*);
extern int _filbuf(FILE*);
#endif
extern void bcopy(char*, char*, int);
extern int fclose(FILE*);
extern int fflush(FILE*);
extern int fprintf(FILE*, const char*, ...);
extern int fread(char*, int, int, FILE *);
extern int fseek(FILE*, long, int);
extern int ftruncate(int, off_t);
extern int fwrite(const char*, int, int, FILE*);
extern char* mktemp(char *template);
extern time_t mktime(struct tm*);
extern int perror(const char*);
extern int printf(const char*, ...);
extern int remove(const char*);
extern int rename(const char*, const char*);
extern int tolower(int);
extern int setvbuf(FILE*, char*, int, int);
extern int sscanf(char*, const char*, ...);
extern int strcasecmp(const char*, const char*);
extern int strncasecmp(const char*, const char*, size_t);
extern long strtol(const char *, char **, int);
extern int system(const char*);
extern time_t timelocal(struct tm*);
extern time_t time(time_t*);
extern int toupper(int);
extern int vfprintf(FILE*, const char *, va_list);
extern char* vsprintf(char *str, const char *format, va_list ap);
#endif /*__SunOS4__*/

View File

@ -6,8 +6,8 @@
*
* External type definitions and function prototypes.
*/
#ifndef __SysDefs__
#define __SysDefs__
#ifndef NUFXLIB_SYSDEFS_H
#define NUFXLIB_SYSDEFS_H
#ifdef HAVE_CONFIG_H
# include <config.h>
@ -18,7 +18,6 @@
#endif
/* these should exist everywhere */
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <memory.h>
@ -55,10 +54,6 @@
# define SNPRINTF_DECLARED
# define VSNPRINTF_DECLARED
# define SPRINTF_RETURNS_INT
# define uchar unsigned char
# define ushort unsigned short
# define uint unsigned int
# define ulong unsigned long
# define inline /*Visual C++6.0 can't inline ".c" files*/
# define mode_t int
# define ENABLE_SQ
@ -72,8 +67,11 @@
# include <direct.h>
# define FOPEN_WANTS_B
# define HAVE_CHSIZE
# define snprintf _snprintf
# define vsnprintf _vsnprintf
# if _MSC_VER < 1900 /* no snprintf until Visual Studio 2015 */
# define snprintf _snprintf
# define vsnprintf _vsnprintf
# endif
#endif
#ifdef HAVE_MALLOC_H
@ -123,26 +121,18 @@
# endif
#endif
/* resource forks on UFS filesystem under Mac OS X are a kluge */
/*#ifdef MAC*/
/*# define HAS_RESOURCE_FORKS*/
/*#endif*/
#if defined(__ORCAC__) || defined(MAC_LIKE)
# define HAS_RESOURCE_FORKS
#endif
/* not currently using filesystem resource forks */
//#if defined(__ORCAC__) || defined(MAC_LIKE)
//# define HAS_RESOURCE_FORKS
//#endif
/* __FUNCTION__ was missing from BeOS __MWERKS__, and might be gcc-only */
#ifdef __GNUC__
# define HAS__FUNCTION__
#endif
#if defined(__sun__) && !defined(__SVR4)
# include "SunOS4.h"
#endif
#if defined(__linux__)
# define HAS_MALLOC_CHECK_
#endif
#endif /*__SysDefs__*/
#endif /*NUFXLIB_SYSDEFS_H*/

View File

@ -6,7 +6,6 @@
*
* Thread-level operations.
*/
#define __Thread_c__ 1
#include "NufxLibPriv.h"
@ -16,6 +15,17 @@
* ===========================================================================
*/
/*
* Returns thread N, or NULL if the index is invalid.
*/
NuThread* Nu_GetThread(const NuRecord* pRecord, int idx)
{
if (idx >= (int)pRecord->recTotalThreads)
return NULL;
else
return &pRecord->pThreads[idx];
}
/*
* ShrinkIt v3.0.0 had a bug where the filename thread would get created
* with the high bits set. We want to undo that without stomping on
@ -26,16 +36,15 @@
* This high-bit-ism was also done for disk archives by most older versions
* of ShrinkIt.
*/
void
Nu_StripHiIfAllSet(char* str)
void Nu_StripHiIfAllSet(char* str)
{
uchar* cp;
uint8_t* cp;
for (cp = (uchar*)str; *cp != '\0'; cp++)
for (cp = (uint8_t*)str; *cp != '\0'; cp++)
if (!(*cp & 0x80))
return;
for (cp = (uchar*)str; *cp != '\0'; cp++)
for (cp = (uint8_t*)str; *cp != '\0'; cp++)
*cp &= 0x7f;
}
@ -44,8 +53,7 @@ Nu_StripHiIfAllSet(char* str)
* Decide if a thread is pre-sized (i.e. has a fixed maximum size with a
* lesser amount of uncompressed data within) based on the threadID.
*/
Boolean
Nu_IsPresizedThreadID(NuThreadID threadID)
Boolean Nu_IsPresizedThreadID(NuThreadID threadID)
{
if (threadID == kNuThreadIDFilename || threadID == kNuThreadIDComment)
return true;
@ -58,8 +66,7 @@ Nu_IsPresizedThreadID(NuThreadID threadID)
* Return an indication of whether the type of thread specified by ThreadID
* should ever be compressed. Right now, that's only data-class threads.
*/
Boolean
Nu_IsCompressibleThreadID(NuThreadID threadID)
Boolean Nu_IsCompressibleThreadID(NuThreadID threadID)
{
if (NuThreadIDGetClass(threadID) == kNuThreadClassData)
return true;
@ -72,8 +79,7 @@ Nu_IsCompressibleThreadID(NuThreadID threadID)
* Decide if the thread has a CRC, based on the record version and the
* threadID.
*/
Boolean
Nu_ThreadHasCRC(long recordVersion, NuThreadID threadID)
Boolean Nu_ThreadHasCRC(uint16_t recordVersion, NuThreadID threadID)
{
return recordVersion >= 3 &&
NuThreadIDGetClass(threadID) == kNuThreadClassData;
@ -83,8 +89,7 @@ Nu_ThreadHasCRC(long recordVersion, NuThreadID threadID)
/*
* Search through a given NuRecord for the specified thread.
*/
NuError
Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
NuError Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
NuThread** ppThread)
{
NuThread* pThread;
@ -92,7 +97,7 @@ Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
pThread = Nu_GetThread(pRecord, idx);
Assert(pThread != nil);
Assert(pThread != NULL);
if (pThread->threadIdx == thread) {
*ppThread = pThread;
@ -108,8 +113,7 @@ Nu_FindThreadByIdx(const NuRecord* pRecord, NuThreadIdx thread,
* Search through a given NuRecord for the first thread with a matching
* threadID.
*/
NuError
Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
NuError Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
NuThread** ppThread)
{
NuThread* pThread;
@ -117,7 +121,7 @@ Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
pThread = Nu_GetThread(pRecord, idx);
Assert(pThread != nil);
Assert(pThread != NULL);
if (NuGetThreadID(pThread) == threadID) {
*ppThread = pThread;
@ -132,11 +136,10 @@ Nu_FindThreadByID(const NuRecord* pRecord, NuThreadID threadID,
/*
* Copy the contents of a NuThread.
*/
void
Nu_CopyThreadContents(NuThread* pDstThread, const NuThread* pSrcThread)
void Nu_CopyThreadContents(NuThread* pDstThread, const NuThread* pSrcThread)
{
Assert(pDstThread != nil);
Assert(pSrcThread != nil);
Assert(pDstThread != NULL);
Assert(pSrcThread != NULL);
memcpy(pDstThread, pSrcThread, sizeof(*pDstThread));
}
@ -151,14 +154,14 @@ Nu_CopyThreadContents(NuThread* pDstThread, const NuThread* pSrcThread)
/*
* Read a single thread header from the archive.
*/
static NuError
Nu_ReadThreadHeader(NuArchive* pArchive, NuThread* pThread, ushort* pCrc)
static NuError Nu_ReadThreadHeader(NuArchive* pArchive, NuThread* pThread,
uint16_t* pCrc)
{
FILE* fp;
Assert(pArchive != nil);
Assert(pThread != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(pThread != NULL);
Assert(pCrc != NULL);
fp = pArchive->archiveFp;
@ -184,17 +187,20 @@ Nu_ReadThreadHeader(NuArchive* pArchive, NuThread* pThread, ushort* pCrc)
* have used a linked list like NuLib, but that doesn't really provide any
* benefit for us, and adds complexity.
*/
NuError
Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc)
NuError Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord,
uint16_t* pCrc)
{
NuError err = kNuErrNone;
NuThread* pThread;
long count;
Boolean hasData = false;
Boolean needFakeData, needFakeRsrc;
Assert(pArchive != nil);
Assert(pRecord != nil);
Assert(pCrc != nil);
needFakeData = true;
needFakeRsrc = (pRecord->recStorageType == kNuStorageExtended);
Assert(pArchive != NULL);
Assert(pRecord != NULL);
Assert(pCrc != NULL);
if (!pRecord->recTotalThreads) {
/* not sure if this is reasonable, but we can handle it */
@ -212,8 +218,16 @@ Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc)
err = Nu_ReadThreadHeader(pArchive, pThread, pCrc);
BailError(err);
if (pThread->thThreadClass == kNuThreadClassData)
hasData = true;
if (pThread->thThreadClass == kNuThreadClassData) {
if (pThread->thThreadKind == kNuThreadKindDataFork) {
needFakeData = false;
} else if (pThread->thThreadKind == kNuThreadKindRsrcFork) {
needFakeRsrc = false;
} else if (pThread->thThreadKind == kNuThreadKindDiskImage) {
/* needFakeRsrc shouldn't be set, but clear anyway */
needFakeData = needFakeRsrc = false;
}
}
/*
* Some versions of ShrinkIt write an invalid thThreadEOF for disks,
@ -255,13 +269,14 @@ Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc)
* If "mask threadless" is set, create "fake" threads with empty
* data and resource forks as needed.
*/
if (!hasData && pArchive->valMaskDataless) {
Boolean needRsrc = (pRecord->recStorageType == kNuStorageExtended);
if ((needFakeData || needFakeRsrc) && pArchive->valMaskDataless) {
int firstNewThread = pRecord->recTotalThreads;
pRecord->recTotalThreads++;
pRecord->fakeThreads++;
if (needRsrc) {
if (needFakeData) {
pRecord->recTotalThreads++;
pRecord->fakeThreads++;
}
if (needFakeRsrc) {
pRecord->recTotalThreads++;
pRecord->fakeThreads++;
}
@ -272,22 +287,23 @@ Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, ushort* pCrc)
pThread = pRecord->pThreads + firstNewThread;
pThread->thThreadClass = kNuThreadClassData;
pThread->thThreadFormat = kNuThreadFormatUncompressed;
pThread->thThreadKind = 0x0000; /* data fork */
pThread->thThreadCRC = kNuInitialThreadCRC;
pThread->thThreadEOF = 0;
pThread->thCompThreadEOF = 0;
pThread->threadIdx = Nu_GetNextThreadIdx(pArchive);
pThread->actualThreadEOF = 0;
pThread->fileOffset = -99999999;
pThread->used = false;
if (needRsrc) {
pThread++;
if (needFakeData) {
pThread->thThreadClass = kNuThreadClassData;
pThread->thThreadFormat = kNuThreadFormatUncompressed;
pThread->thThreadKind = 0x0002; /* rsrc fork */
pThread->thThreadKind = kNuThreadKindDataFork;
pThread->thThreadCRC = kNuInitialThreadCRC;
pThread->thThreadEOF = 0;
pThread->thCompThreadEOF = 0;
pThread->threadIdx = Nu_GetNextThreadIdx(pArchive);
pThread->actualThreadEOF = 0;
pThread->fileOffset = -99999999;
pThread->used = false;
pThread++;
}
if (needFakeRsrc) {
pThread->thThreadClass = kNuThreadClassData;
pThread->thThreadFormat = kNuThreadFormatUncompressed;
pThread->thThreadKind = kNuThreadKindRsrcFork;
pThread->thThreadCRC = kNuInitialThreadCRC;
pThread->thThreadEOF = 0;
pThread->thCompThreadEOF = 0;
@ -306,17 +322,16 @@ bail:
/*
* Write a single thread header to the archive.
*/
static NuError
Nu_WriteThreadHeader(NuArchive* pArchive, const NuThread* pThread, FILE* fp,
ushort* pCrc)
static NuError Nu_WriteThreadHeader(NuArchive* pArchive,
const NuThread* pThread, FILE* fp, uint16_t* pCrc)
{
Assert(pArchive != nil);
Assert(pThread != nil);
Assert(fp != nil);
Assert(pCrc != nil);
Assert(pArchive != NULL);
Assert(pThread != NULL);
Assert(fp != NULL);
Assert(pCrc != NULL);
Nu_WriteTwoC(pArchive, fp, pThread->thThreadClass, pCrc);
Nu_WriteTwoC(pArchive, fp, (ushort)pThread->thThreadFormat, pCrc);
Nu_WriteTwoC(pArchive, fp, (uint16_t)pThread->thThreadFormat, pCrc);
Nu_WriteTwoC(pArchive, fp, pThread->thThreadKind, pCrc);
Nu_WriteTwoC(pArchive, fp, pThread->thThreadCRC, pCrc);
Nu_WriteFourC(pArchive, fp, pThread->thThreadEOF, pCrc);
@ -332,9 +347,8 @@ Nu_WriteThreadHeader(NuArchive* pArchive, const NuThread* pThread, FILE* fp,
* effect, we promote all threads to "real" status. We update the
* "fake" count in pRecord accordingly.
*/
NuError
Nu_WriteThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, FILE* fp,
ushort* pCrc)
NuError Nu_WriteThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, FILE* fp,
uint16_t* pCrc)
{
NuError err = kNuErrNone;
NuThread* pThread;
@ -342,7 +356,7 @@ Nu_WriteThreadHeaders(NuArchive* pArchive, NuRecord* pRecord, FILE* fp,
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
pThread = Nu_GetThread(pRecord, idx);
Assert(pThread != nil);
Assert(pThread != NULL);
err = Nu_WriteThreadHeader(pArchive, pThread, fp, pCrc);
BailError(err);
@ -366,14 +380,13 @@ bail:
* Requires that the pArchive->currentOffset be set to the offset
* immediately after the last of the thread headers.
*/
NuError
Nu_ComputeThreadData(NuArchive* pArchive, NuRecord* pRecord)
NuError Nu_ComputeThreadData(NuArchive* pArchive, NuRecord* pRecord)
{
NuThread* pThread;
long fileOffset, count;
Assert(pArchive != nil);
Assert(pRecord != nil);
Assert(pArchive != NULL);
Assert(pRecord != NULL);
/*pRecord->totalLength = 0;*/
pRecord->totalCompLength = 0;
@ -407,15 +420,14 @@ Nu_ComputeThreadData(NuArchive* pArchive, NuRecord* pRecord)
* show to the application. (Someday I'll get AndyN for putting me
* through this...)
*/
NuError
Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
NuError Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
{
NuError err = kNuErrNone;
NuThread* pThread;
FILE* fp;
Assert(pArchive != nil);
Assert(pRecord != nil);
Assert(pArchive != NULL);
Assert(pRecord != NULL);
fp = pArchive->archiveFp;
@ -423,23 +435,23 @@ Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
pThread = pRecord->pThreads;
while (numThreads--) {
if (pRecord->threadFilename == nil &&
if (pRecord->threadFilenameMOR == NULL &&
NuMakeThreadID(pThread->thThreadClass, pThread->thThreadKind) ==
kNuThreadIDFilename)
{
/* it's the first filename thread, read the whole thing */
if (pThread->thCompThreadEOF > kNuReasonableFilenameLen) {
err = kNuErrBadRecord;
Nu_ReportError(NU_BLOB, err, "Bad thread filename len (%lu)",
Nu_ReportError(NU_BLOB, err, "Bad thread filename len (%u)",
pThread->thCompThreadEOF);
goto bail;
}
pRecord->threadFilename = Nu_Malloc(pArchive,
pRecord->threadFilenameMOR = Nu_Malloc(pArchive,
pThread->thCompThreadEOF +1);
BailAlloc(pRecord->threadFilename);
BailAlloc(pRecord->threadFilenameMOR);
/* note there is no CRC on a filename thread */
(void) Nu_ReadBytes(pArchive, fp, pRecord->threadFilename,
(void) Nu_ReadBytes(pArchive, fp, pRecord->threadFilenameMOR,
pThread->thCompThreadEOF);
if ((err = Nu_HeaderIOFailed(pArchive, fp)) != kNuErrNone) {
Nu_ReportError(NU_BLOB, err, "Failed reading filename thread");
@ -447,15 +459,15 @@ Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
}
/* null-terminate on the actual len, not the buffer len */
pRecord->threadFilename[pThread->thThreadEOF] = '\0';
pRecord->threadFilenameMOR[pThread->thThreadEOF] = '\0';
Nu_StripHiIfAllSet(pRecord->threadFilename);
Nu_StripHiIfAllSet(pRecord->threadFilenameMOR);
/* prefer this one over the record one, but only one should exist */
if (pRecord->filename != nil) {
if (pRecord->filenameMOR != NULL) {
DBUG(("--- HEY: got record filename and thread filename\n"));
}
pRecord->filename = pRecord->threadFilename;
pRecord->filenameMOR = pRecord->threadFilenameMOR;
} else {
/* not a filename (or not first filename), skip past it */
@ -473,9 +485,9 @@ Nu_ScanThreads(NuArchive* pArchive, NuRecord* pRecord, long numThreads)
* end up with a disk image that had no name attached. This will tend
* to confuse things, so we go ahead and give it a name.
*/
if (pRecord->filename == nil) {
if (pRecord->filenameMOR == NULL) {
DBUG(("+++ no filename found, using default record name\n"));
pRecord->filename = kNuDefaultRecordName;
pRecord->filenameMOR = kNuDefaultRecordName;
}
pArchive->currentOffset += pRecord->totalCompLength;
@ -494,8 +506,7 @@ bail:
* assumes that the file pointer is set to the start of the thread's data
* already.
*/
NuError
Nu_SkipThread(NuArchive* pArchive, const NuRecord* pRecord,
NuError Nu_SkipThread(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread)
{
NuError err;
@ -522,12 +533,12 @@ Nu_SkipThread(NuArchive* pArchive, const NuRecord* pRecord,
* If the archive is a stream, the stream must be positioned at the
* start of pThread's data. If not, it will be seeked first.
*/
static NuError
Nu_ExtractThreadToDataSink(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, NuProgressData* pProgress, NuDataSink* pDataSink)
static NuError Nu_ExtractThreadToDataSink(NuArchive* pArchive,
const NuRecord* pRecord, const NuThread* pThread,
NuProgressData* pProgress, NuDataSink* pDataSink)
{
NuError err;
NuFunnel* pFunnel = nil;
NuFunnel* pFunnel = NULL;
/* if it's not a stream, seek to the appropriate spot in the file */
if (!Nu_IsStreaming(pArchive)) {
@ -576,9 +587,8 @@ bail:
* filters for every thread, which means we can reject specific kinds
* of forks and/or give them different names. This is a good thing.
*/
static NuError
Nu_ExtractThreadCommon(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread, NuDataSink* pDataSink)
static NuError Nu_ExtractThreadCommon(NuArchive* pArchive,
const NuRecord* pRecord, const NuThread* pThread, NuDataSink* pDataSink)
{
NuError err = kNuErrNone;
NuSelectionProposal selProposal;
@ -586,18 +596,19 @@ Nu_ExtractThreadCommon(NuArchive* pArchive, const NuRecord* pRecord,
NuProgressData progressData;
NuProgressData* pProgressData;
NuDataSink* pOrigDataSink;
char* newPathStorage = nil;
const char* newPathname;
UNICHAR* newPathStorageUNI = NULL;
UNICHAR* recFilenameStorageUNI = NULL;
const UNICHAR* newPathnameUNI;
NuResult result;
uchar newFssep;
uint8_t newFssep;
Boolean doFreeSink = false;
Assert(pRecord != nil);
Assert(pThread != nil);
Assert(pDataSink != nil);
Assert(pRecord != NULL);
Assert(pThread != NULL);
Assert(pDataSink != NULL);
memset(&progressData, 0, sizeof(progressData));
pProgressData = nil;
pProgressData = NULL;
/*
* If we're just trying to verify the archive contents, create a
@ -619,7 +630,7 @@ Nu_ExtractThreadCommon(NuArchive* pArchive, const NuRecord* pRecord,
* use by the "bulk" extract, not the per-thread extract, but it
* still applies if they so desire.
*/
if (pArchive->selectionFilterFunc != nil) {
if (pArchive->selectionFilterFunc != NULL) {
selProposal.pRecord = pRecord;
selProposal.pThread = pThread;
result = (*pArchive->selectionFilterFunc)(pArchive, &selProposal);
@ -632,9 +643,11 @@ Nu_ExtractThreadCommon(NuArchive* pArchive, const NuRecord* pRecord,
}
}
newPathname = nil;
newPathnameUNI = NULL;
newFssep = 0;
recFilenameStorageUNI = Nu_CopyMORToUNI(pRecord->filenameMOR);
retry_name:
if (Nu_DataSinkGetType(pDataSink) == kNuDataSinkToFile) {
/*
@ -645,21 +658,21 @@ retry_name:
* Start by resetting everything to defaults, in case this isn't
* our first time through the "rename" loop.
*/
newPathname = Nu_DataSinkFile_GetPathname(pDataSink);
newPathnameUNI = Nu_DataSinkFile_GetPathname(pDataSink);
newFssep = Nu_DataSinkFile_GetFssep(pDataSink);
pDataSink = pOrigDataSink;
/* if they don't have a pathname func defined, we just use default */
if (pArchive->outputPathnameFunc != nil) {
pathProposal.pathname = pRecord->filename;
if (pArchive->outputPathnameFunc != NULL) {
pathProposal.pathnameUNI = recFilenameStorageUNI;
pathProposal.filenameSeparator =
NuGetSepFromSysInfo(pRecord->recFileSysInfo);
pathProposal.pRecord = pRecord;
pathProposal.pThread = pThread;
pathProposal.newPathname = nil;
pathProposal.newPathnameUNI = NULL;
pathProposal.newFilenameSeparator = '\0';
/*pathProposal.newStorage = (NuThreadID)-1;*/
pathProposal.newDataSink = nil;
pathProposal.newDataSink = NULL;
result = (*pArchive->outputPathnameFunc)(pArchive, &pathProposal);
@ -671,35 +684,38 @@ retry_name:
}
/* we don't own this string, so make a copy */
if (pathProposal.newPathname != nil) {
newPathStorage = strdup(pathProposal.newPathname);
newPathname = newPathStorage;
} else
newPathname = nil;
if (pathProposal.newPathnameUNI != NULL) {
Nu_Free(pArchive, newPathStorageUNI);
newPathStorageUNI = strdup(pathProposal.newPathnameUNI);
newPathnameUNI = newPathStorageUNI;
} else {
newPathnameUNI = NULL;
}
if (pathProposal.newFilenameSeparator != '\0')
newFssep = pathProposal.newFilenameSeparator;
/* if they want to send this somewhere else, let them */
if (pathProposal.newDataSink != nil)
if (pathProposal.newDataSink != NULL)
pDataSink = pathProposal.newDataSink;
}
/* at least one of these must be set */
Assert(!(newPathname == nil && pathProposal.newDataSink == nil));
Assert(!(newPathnameUNI == NULL && pathProposal.newDataSink == NULL));
}
/*
* Prepare the progress data if this is a data thread.
*/
if (newPathname == nil) {
if (newPathnameUNI == NULL) {
/* using a data sink; get the pathname out of the record */
newPathname = pRecord->filename;
newPathnameUNI = recFilenameStorageUNI;
newFssep = NuGetSepFromSysInfo(pRecord->recFileSysInfo);
}
if (pThread->thThreadClass == kNuThreadClassData) {
pProgressData = &progressData;
err = Nu_ProgressDataInit_Expand(pArchive, pProgressData, pRecord,
newPathname, newFssep, Nu_DataSinkGetConvertEOL(pOrigDataSink));
newPathnameUNI, newFssep, recFilenameStorageUNI,
Nu_DataSinkGetConvertEOL(pOrigDataSink));
BailError(err);
/* send initial progress so they see the right name if "open" fails */
@ -713,23 +729,23 @@ retry_name:
* We're extracting to a file. Open it, creating it if necessary and
* allowed.
*/
FILE* fileFp = nil;
FILE* fileFp = NULL;
err = Nu_OpenOutputFile(pArchive, pRecord, pThread, newPathname,
err = Nu_OpenOutputFile(pArchive, pRecord, pThread, newPathnameUNI,
newFssep, &fileFp);
if (err == kNuErrRename) {
/* they want to rename; the OutputPathname callback handles this */
Nu_Free(pArchive, newPathStorage);
newPathStorage = nil;
Nu_Free(pArchive, newPathStorageUNI);
newPathStorageUNI = NULL;
/* reset these just to be careful */
newPathname = nil;
fileFp = nil;
newPathnameUNI = NULL;
fileFp = NULL;
goto retry_name;
} else if (err != kNuErrNone) {
goto bail;
}
Assert(fileFp != nil);
Assert(fileFp != NULL);
(void) Nu_DataSinkFile_SetFP(pDataSink, fileFp);
DBUG(("+++ EXTRACTING 0x%08lx from '%s' at offset %0ld to '%s'\n",
@ -752,13 +768,13 @@ retry_name:
* permissions as appropriate.
*/
err = Nu_CloseOutputFile(pArchive, pRecord,
Nu_DataSinkFile_GetFP(pDataSink), newPathname);
Nu_DataSinkFile_SetFP(pDataSink, nil);
Nu_DataSinkFile_GetFP(pDataSink), newPathnameUNI);
Nu_DataSinkFile_SetFP(pDataSink, NULL);
BailError(err);
}
bail:
if (err != kNuErrNone && pProgressData != nil) {
if (err != kNuErrNone && pProgressData != NULL) {
/* send a final progress message, indicating failure */
if (err == kNuErrSkipped)
pProgressData->state = kNuProgressSkipped;
@ -773,7 +789,8 @@ bail:
if (Nu_DataSinkGetType(pDataSink) == kNuDataSinkToFile)
Nu_DataSinkFile_Close(pDataSink);
Nu_Free(pArchive, newPathStorage);
Nu_Free(pArchive, newPathStorageUNI);
Nu_Free(pArchive, recFilenameStorageUNI);
if (doFreeSink)
Nu_DataSinkFree(pDataSink);
@ -785,12 +802,12 @@ bail:
*
* Streaming archives must be properly positioned.
*/
NuError
Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
NuError Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread)
{
NuError err;
NuDataSink* pDataSink = nil;
NuDataSink* pDataSink = NULL;
UNICHAR* recFilenameStorageUNI = NULL;
NuValue eolConv;
/*
@ -806,7 +823,8 @@ Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
eolConv = pArchive->valConvertExtractedEOL;
if (NuGetThreadID(pThread) == kNuThreadIDDiskImage)
eolConv = kNuConvertOff;
err = Nu_DataSinkFile_New(true, eolConv, pRecord->filename,
recFilenameStorageUNI = Nu_CopyMORToUNI(pRecord->filenameMOR);
err = Nu_DataSinkFile_New(true, eolConv, recFilenameStorageUNI,
NuGetSepFromSysInfo(pRecord->recFileSysInfo), &pDataSink);
BailError(err);
@ -814,11 +832,12 @@ Nu_ExtractThreadBulk(NuArchive* pArchive, const NuRecord* pRecord,
BailError(err);
bail:
if (pDataSink != nil) {
if (pDataSink != NULL) {
NuError err2 = Nu_DataSinkFree(pDataSink);
if (err == kNuErrNone)
err = err2;
}
Nu_Free(pArchive, recFilenameStorageUNI);
return err;
}
@ -827,8 +846,7 @@ bail:
/*
* Extract a thread, given the IDs and a data sink.
*/
NuError
Nu_ExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
NuError Nu_ExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
NuDataSink* pDataSink)
{
NuError err;
@ -837,7 +855,7 @@ Nu_ExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
if (Nu_IsStreaming(pArchive))
return kNuErrUsage;
if (threadIdx == 0 || pDataSink == nil)
if (threadIdx == 0 || pDataSink == NULL)
return kNuErrInvalidArg;
err = Nu_GetTOCIfNeeded(pArchive);
BailError(err);
@ -846,7 +864,7 @@ Nu_ExtractThread(NuArchive* pArchive, NuThreadIdx threadIdx,
err = Nu_RecordSet_FindByThreadIdx(&pArchive->origRecordSet, threadIdx,
&pRecord, &pThread);
BailError(err);
Assert(pRecord != nil);
Assert(pRecord != NULL);
/* extract away */
err = Nu_ExtractThreadCommon(pArchive, pRecord, pThread, pDataSink);
@ -872,9 +890,8 @@ bail:
*
* If a matching threadID is found, this returns an error.
*/
static NuError
Nu_FindNoFutureThread(NuArchive* pArchive, const NuRecord* pRecord,
NuThreadID threadID)
static NuError Nu_FindNoFutureThread(NuArchive* pArchive,
const NuRecord* pRecord, NuThreadID threadID)
{
NuError err = kNuErrNone;
const NuThread* pThread;
@ -886,13 +903,13 @@ Nu_FindNoFutureThread(NuArchive* pArchive, const NuRecord* pRecord,
*/
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
pThread = Nu_GetThread(pRecord, idx);
Assert(pThread != nil);
Assert(pThread != NULL);
if (NuGetThreadID(pThread) == threadID) {
/* found a match, see if it has been deleted */
pThreadMod = Nu_ThreadMod_FindByThreadIdx(pRecord,
pThread->threadIdx);
if (pThreadMod != nil &&
if (pThreadMod != NULL &&
pThreadMod->entry.kind == kNuThreadModDelete)
{
/* it's deleted, ignore it */
@ -908,7 +925,7 @@ Nu_FindNoFutureThread(NuArchive* pArchive, const NuRecord* pRecord,
* Now look for "add" threadMods with a matching threadID.
*/
pThreadMod = pRecord->pThreadMods;
while (pThreadMod != nil) {
while (pThreadMod != NULL) {
if (pThreadMod->entry.kind == kNuThreadModAdd &&
pThreadMod->entry.add.threadID == threadID)
{
@ -927,9 +944,8 @@ bail:
/*
* Like Nu_FindNoFutureThread, but tests against a whole class.
*/
static NuError
Nu_FindNoFutureThreadClass(NuArchive* pArchive, const NuRecord* pRecord,
long threadClass)
static NuError Nu_FindNoFutureThreadClass(NuArchive* pArchive,
const NuRecord* pRecord, long threadClass)
{
NuError err = kNuErrNone;
const NuThread* pThread;
@ -941,13 +957,13 @@ Nu_FindNoFutureThreadClass(NuArchive* pArchive, const NuRecord* pRecord,
*/
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
pThread = Nu_GetThread(pRecord, idx);
Assert(pThread != nil);
Assert(pThread != NULL);
if (pThread->thThreadClass == threadClass) {
/* found a match, see if it has been deleted */
pThreadMod = Nu_ThreadMod_FindByThreadIdx(pRecord,
pThread->threadIdx);
if (pThreadMod != nil &&
if (pThreadMod != NULL &&
pThreadMod->entry.kind == kNuThreadModDelete)
{
/* it's deleted, ignore it */
@ -963,7 +979,7 @@ Nu_FindNoFutureThreadClass(NuArchive* pArchive, const NuRecord* pRecord,
* Now look for "add" threadMods with a matching threadClass.
*/
pThreadMod = pRecord->pThreadMods;
while (pThreadMod != nil) {
while (pThreadMod != NULL) {
if (pThreadMod->entry.kind == kNuThreadModAdd &&
NuThreadIDGetClass(pThreadMod->entry.add.threadID) == threadClass)
{
@ -988,9 +1004,8 @@ bail:
* The record and thread returned will always be from the "copy" set. An
* error result is returned if the record and thread aren't found.
*/
static NuError
Nu_FindThreadForWriteByIdx(NuArchive* pArchive, NuThreadIdx threadIdx,
NuRecord** ppFoundRecord, NuThread** ppFoundThread)
static NuError Nu_FindThreadForWriteByIdx(NuArchive* pArchive,
NuThreadIdx threadIdx, NuRecord** ppFoundRecord, NuThread** ppFoundThread)
{
NuError err;
@ -1001,7 +1016,7 @@ Nu_FindThreadForWriteByIdx(NuArchive* pArchive, NuThreadIdx threadIdx,
Assert(Nu_RecordSet_GetLoaded(&pArchive->origRecordSet));
err = Nu_RecordSet_FindByThreadIdx(&pArchive->origRecordSet, threadIdx,
ppFoundRecord, ppFoundThread);
*ppFoundThread = nil; /* can't delete from here, wipe ptr */
*ppFoundThread = NULL; /* can't delete from here, wipe ptr */
}
BailError(err);
@ -1009,13 +1024,13 @@ Nu_FindThreadForWriteByIdx(NuArchive* pArchive, NuThreadIdx threadIdx,
* The thread exists. If we were looking in the "orig" set, we have
* to create a "copy" set, and delete it from that.
*/
if (*ppFoundThread == nil) {
if (*ppFoundThread == NULL) {
err = Nu_RecordSet_Clone(pArchive, &pArchive->copyRecordSet,
&pArchive->origRecordSet);
BailError(err);
err = Nu_RecordSet_FindByThreadIdx(&pArchive->copyRecordSet, threadIdx,
ppFoundRecord, ppFoundThread);
Assert(err == kNuErrNone && *ppFoundThread != nil); /* must succeed */
Assert(err == kNuErrNone && *ppFoundThread != NULL); /* must succeed */
BailError(err);
}
@ -1029,8 +1044,7 @@ bail:
*
* Returns with an error (kNuErrThreadAdd) if it's not okay.
*/
NuError
Nu_OkayToAddThread(NuArchive* pArchive, const NuRecord* pRecord,
NuError Nu_OkayToAddThread(NuArchive* pArchive, const NuRecord* pRecord,
NuThreadID threadID)
{
NuError err = kNuErrNone;
@ -1094,17 +1108,16 @@ bail:
* On success, the NuThreadIdx of the newly-created record will be placed
* in "*pThreadIdx", and "pDataSource" will be owned by NufxLib.
*/
NuError
Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx, NuThreadID threadID,
NuDataSource* pDataSource, NuThreadIdx* pThreadIdx)
NuError Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx,
NuThreadID threadID, NuDataSource* pDataSource, NuThreadIdx* pThreadIdx)
{
NuError err;
NuRecord* pRecord;
NuThreadMod* pThreadMod = nil;
NuThreadMod* pThreadMod = NULL;
NuThreadFormat threadFormat;
/* okay for pThreadIdx to be nil */
if (recIdx == 0 || pDataSource == nil)
/* okay for pThreadIdx to be NULL */
if (recIdx == 0 || pDataSource == NULL)
return kNuErrInvalidArg;
if (Nu_IsReadOnly(pArchive))
@ -1123,7 +1136,7 @@ Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx, NuThreadID threadID,
err = Nu_RecordSet_FindByIdx(&pArchive->newRecordSet, recIdx, &pRecord);
}
BailError(err);
Assert(pRecord != nil);
Assert(pRecord != NULL);
/*
* Do some tests, looking for specific types of threads that conflict
@ -1153,13 +1166,13 @@ Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx, NuThreadID threadID,
err = Nu_ThreadModAdd_New(pArchive, threadID, threadFormat, pDataSource,
&pThreadMod);
BailError(err);
Assert(pThreadMod != nil);
Assert(pThreadMod != NULL);
/* add the thread mod to the record */
Nu_RecordAddThreadMod(pRecord, pThreadMod);
if (pThreadIdx != nil)
if (pThreadIdx != NULL)
*pThreadIdx = pThreadMod->entry.add.threadIdx;
pThreadMod = nil; /* successful, don't free */
pThreadMod = NULL; /* successful, don't free */
/*
* If we've got a header filename and we're adding a filename thread,
@ -1172,9 +1185,9 @@ Nu_AddThread(NuArchive* pArchive, NuRecordIdx recIdx, NuThreadID threadID,
}
bail:
if (pThreadMod != nil)
if (pThreadMod != NULL)
Nu_ThreadModFree(pArchive, pThreadMod);
if (err == kNuErrNone && pDataSource != nil) {
if (err == kNuErrNone && pDataSource != NULL) {
/* on success, we have ownership of the data source. ThreadMod
made its own copy, so get rid of this one */
Nu_DataSourceFree(pDataSource);
@ -1194,16 +1207,15 @@ bail:
* You aren't allowed to update threads that have been deleted. Updating
* newly-added threads isn't possible, since they aren't really threads yet.
*/
NuError
Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
NuDataSource* pDataSource, long* pMaxLen)
NuError Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
NuDataSource* pDataSource, int32_t* pMaxLen)
{
NuError err;
NuThreadMod* pThreadMod = nil;
NuThreadMod* pThreadMod = NULL;
NuRecord* pFoundRecord;
NuThread* pFoundThread;
if (pDataSource == nil) {
if (pDataSource == NULL) {
err = kNuErrInvalidArg;
goto bail;
}
@ -1239,14 +1251,14 @@ Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
goto bail;
}
if (pMaxLen != nil)
if (pMaxLen != NULL)
*pMaxLen = pFoundThread->thCompThreadEOF;
/*
* Check to see if somebody is trying to delete this, or has already
* updated it.
*/
if (Nu_ThreadMod_FindByThreadIdx(pFoundRecord, threadIdx) != nil) {
if (Nu_ThreadMod_FindByThreadIdx(pFoundRecord, threadIdx) != NULL) {
DBUG(("--- Tried to modify a deleted or modified thread\n"));
err = kNuErrModThreadChange;
goto bail;
@ -1269,7 +1281,7 @@ Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
Nu_DataSourceGetOtherLen(pDataSource))
{
err = kNuErrPreSizeOverflow;
Nu_ReportError(NU_BLOB, err, "can't put %ld bytes into %ld",
Nu_ReportError(NU_BLOB, err, "can't put %u bytes into %u",
Nu_DataSourceGetOtherLen(pDataSource),
pFoundThread->thCompThreadEOF);
goto bail;
@ -1281,7 +1293,7 @@ Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
Nu_DataSourceGetOtherLen(pDataSource) > kNuReasonableFilenameLen))
{
err = kNuErrInvalidFilename;
Nu_ReportError(NU_BLOB, err, "invalid filename (%ld bytes)",
Nu_ReportError(NU_BLOB, err, "invalid filename (%u bytes)",
Nu_DataSourceGetOtherLen(pDataSource));
goto bail;
}
@ -1294,7 +1306,7 @@ Nu_UpdatePresizedThread(NuArchive* pArchive, NuThreadIdx threadIdx,
Assert(pFoundThread->thThreadFormat == kNuThreadFormatUncompressed);
err = Nu_ThreadModUpdate_New(pArchive, threadIdx, pDataSource, &pThreadMod);
BailError(err);
Assert(pThreadMod != nil);
Assert(pThreadMod != NULL);
/* add the thread mod to the record */
Nu_RecordAddThreadMod(pFoundRecord, pThreadMod);
@ -1322,11 +1334,10 @@ bail:
* later on. Besides, it's sort of handy to hang on to the filename for
* as long as possible.
*/
NuError
Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
NuError Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
{
NuError err;
NuThreadMod* pThreadMod = nil;
NuThreadMod* pThreadMod = NULL;
NuRecord* pFoundRecord;
NuThread* pFoundThread;
@ -1348,7 +1359,7 @@ Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
* allowed. Deletion of threads from deleted records can't happen,
* because deleted records are completely removed from the "copy" set.
*/
if (Nu_ThreadMod_FindByThreadIdx(pFoundRecord, threadIdx) != nil) {
if (Nu_ThreadMod_FindByThreadIdx(pFoundRecord, threadIdx) != NULL) {
DBUG(("--- Tried to delete a deleted or modified thread\n"));
err = kNuErrModThreadChange;
goto bail;
@ -1361,7 +1372,7 @@ Nu_DeleteThread(NuArchive* pArchive, NuThreadIdx threadIdx)
NuGetThreadID(pFoundThread), &pThreadMod);
BailError(err);
Nu_RecordAddThreadMod(pFoundRecord, pThreadMod);
pThreadMod = nil; /* successful, don't free */
pThreadMod = NULL; /* successful, don't free */
bail:
Nu_ThreadModFree(pArchive, pThreadMod);

View File

@ -14,12 +14,11 @@
/*
* Get a configurable parameter.
*/
NuError
Nu_GetValue(NuArchive* pArchive, NuValueID ident, NuValue* pValue)
NuError Nu_GetValue(NuArchive* pArchive, NuValueID ident, NuValue* pValue)
{
NuError err = kNuErrNone;
if (pValue == nil)
if (pValue == NULL)
return kNuErrInvalidArg;
switch (ident) {
@ -82,8 +81,7 @@ bail:
/*
* Set a configurable parameter.
*/
NuError
Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
NuError Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
{
NuError err = kNuErrInvalidArg;
@ -91,7 +89,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueAllowDuplicates:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueAllowDuplicates value %ld", value);
"Invalid kNuValueAllowDuplicates value %u", value);
goto bail;
}
pArchive->valAllowDuplicates = value;
@ -99,7 +97,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueConvertExtractedEOL:
if (value < kNuConvertOff || value > kNuConvertAuto) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueConvertExtractedEOL value %ld", value);
"Invalid kNuValueConvertExtractedEOL value %u", value);
goto bail;
}
pArchive->valConvertExtractedEOL = value;
@ -107,7 +105,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueDataCompression:
if (value < kNuCompressNone || value > kNuCompressBzip2) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueDataCompression value %ld", value);
"Invalid kNuValueDataCompression value %u", value);
goto bail;
}
pArchive->valDataCompression = value;
@ -115,7 +113,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueDiscardWrapper:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueDiscardWrapper value %ld", value);
"Invalid kNuValueDiscardWrapper value %u", value);
goto bail;
}
pArchive->valDiscardWrapper = value;
@ -123,7 +121,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueEOL:
if (value < kNuEOLUnknown || value > kNuEOLCRLF) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueEOL value %ld", value);
"Invalid kNuValueEOL value %u", value);
goto bail;
}
pArchive->valEOL = value;
@ -131,7 +129,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueHandleExisting:
if (value < kNuMaybeOverwrite || value > kNuMustOverwrite) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueHandleExisting value %ld", value);
"Invalid kNuValueHandleExisting value %u", value);
goto bail;
}
pArchive->valHandleExisting = value;
@ -139,7 +137,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueIgnoreCRC:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueIgnoreCRC value %ld", value);
"Invalid kNuValueIgnoreCRC value %u", value);
goto bail;
}
pArchive->valIgnoreCRC = value;
@ -147,7 +145,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueMaskDataless:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueMaskDataless value %ld", value);
"Invalid kNuValueMaskDataless value %u", value);
goto bail;
}
pArchive->valMaskDataless = value;
@ -155,7 +153,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueMimicSHK:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueMimicSHK value %ld", value);
"Invalid kNuValueMimicSHK value %u", value);
goto bail;
}
pArchive->valMimicSHK = value;
@ -163,7 +161,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueModifyOrig:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueModifyOrig value %ld", value);
"Invalid kNuValueModifyOrig value %u", value);
goto bail;
}
pArchive->valModifyOrig = value;
@ -171,7 +169,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueOnlyUpdateOlder:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueOnlyUpdateOlder value %ld", value);
"Invalid kNuValueOnlyUpdateOlder value %u", value);
goto bail;
}
pArchive->valOnlyUpdateOlder = value;
@ -179,7 +177,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueStripHighASCII:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueStripHighASCII value %ld", value);
"Invalid kNuValueStripHighASCII value %u", value);
goto bail;
}
pArchive->valStripHighASCII = value;
@ -187,7 +185,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueJunkSkipMax:
if (value > kMaxJunkSkipMax) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueJunkSkipMax value %ld", value);
"Invalid kNuValueJunkSkipMax value %u", value);
goto bail;
}
pArchive->valJunkSkipMax = value;
@ -195,7 +193,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueIgnoreLZW2Len:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueIgnoreLZW2Len value %ld", value);
"Invalid kNuValueIgnoreLZW2Len value %u", value);
goto bail;
}
pArchive->valIgnoreLZW2Len = value;
@ -203,7 +201,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value)
case kNuValueHandleBadMac:
if (value != true && value != false) {
Nu_ReportError(NU_BLOB, err,
"Invalid kNuValueHandleBadMac value %ld", value);
"Invalid kNuValueHandleBadMac value %u", value);
goto bail;
}
pArchive->valHandleBadMac = value;
@ -225,11 +223,10 @@ bail:
* pry into pArchive to get at (like the archive type) or get the master
* header (like the number of records).
*/
NuError
Nu_GetAttr(NuArchive* pArchive, NuAttrID ident, NuAttr* pAttr)
NuError Nu_GetAttr(NuArchive* pArchive, NuAttrID ident, NuAttr* pAttr)
{
NuError err = kNuErrNone;
if (pAttr == nil)
if (pAttr == NULL)
return kNuErrInvalidArg;
switch (ident) {
@ -260,8 +257,8 @@ bail:
*
* Unsupported compression types cause a warning to be flagged.
*/
NuThreadFormat
Nu_ConvertCompressValToFormat(NuArchive* pArchive, NuValue compValue)
NuThreadFormat Nu_ConvertCompressValToFormat(NuArchive* pArchive,
NuValue compValue)
{
NuThreadFormat threadFormat;
Boolean unsup = false;
@ -312,14 +309,14 @@ Nu_ConvertCompressValToFormat(NuArchive* pArchive, NuValue compValue)
default:
Nu_ReportError(NU_BLOB, kNuErrInvalidArg,
"Unknown compress value %ld", compValue);
"Unknown compress value %u", compValue);
Assert(false);
return kNuThreadFormatUncompressed;
}
if (unsup) {
Nu_ReportError(NU_BLOB, kNuErrNone,
"Unsupported compression 0x%04x requested (%ld), storing",
"Unsupported compression 0x%04x requested (%u), storing",
threadFormat, compValue);
return kNuThreadFormatUncompressed;
}

View File

@ -23,19 +23,18 @@ static const char gNuBuildFlags[] = "-";
/*
* Return the version number, date built, and build flags.
*/
NuError
Nu_GetVersion(long* pMajorVersion, long* pMinorVersion, long* pBugVersion,
const char** ppBuildDate, const char** ppBuildFlags)
NuError Nu_GetVersion(int32_t* pMajorVersion, int32_t* pMinorVersion,
int32_t* pBugVersion, const char** ppBuildDate, const char** ppBuildFlags)
{
if (pMajorVersion != nil)
if (pMajorVersion != NULL)
*pMajorVersion = kNuVersionMajor;
if (pMinorVersion != nil)
if (pMinorVersion != NULL)
*pMinorVersion = kNuVersionMinor;
if (pBugVersion != nil)
if (pBugVersion != NULL)
*pBugVersion = kNuVersionBug;
if (ppBuildDate != nil)
if (ppBuildDate != NULL)
*ppBuildDate = gNuBuildDate;
if (ppBuildFlags != nil)
if (ppBuildFlags != NULL)
*ppBuildFlags = gNuBuildFlags;
return kNuErrNone;
}

1456
nufxlib/config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -27,18 +27,6 @@
/* Define if your <sys/time.h> declares struct tm. */
#undef TM_IN_SYS_TIME
/* Define to `unsigned char' if <sys/types.h> doesn't define. */
#undef uchar
/* Define to `unsigned short' if <sys/types.h> doesn't define. */
#undef ushort
/* Define to `unsigned int' if <sys/types.h> doesn't define. */
#undef uint
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
#undef ulong
/* Define to `int' if <sys/types.h> doesn't define. */
#undef mode_t

2785
nufxlib/config.sub vendored

File diff suppressed because it is too large Load Diff

100
nufxlib/configure vendored
View File

@ -626,6 +626,7 @@ BUILD_FLAGS
EGREP
GREP
CPP
NUFX_VERSION
RANLIB
SET_MAKE
INSTALL_DATA
@ -665,6 +666,7 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -741,6 +743,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
@ -993,6 +996,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1130,7 +1142,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir
libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1283,6 +1295,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@ -3273,6 +3286,10 @@ else
fi
NUFX_VERSION=3.1.0
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@ -3879,50 +3896,6 @@ $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
fi
ac_fn_c_check_type "$LINENO" "uchar" "ac_cv_type_uchar" "$ac_includes_default"
if test "x$ac_cv_type_uchar" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define uchar unsigned char
_ACEOF
fi
ac_fn_c_check_type "$LINENO" "ushort" "ac_cv_type_ushort" "$ac_includes_default"
if test "x$ac_cv_type_ushort" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define ushort unsigned short
_ACEOF
fi
ac_fn_c_check_type "$LINENO" "uint" "ac_cv_type_uint" "$ac_includes_default"
if test "x$ac_cv_type_uint" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define uint unsigned int
_ACEOF
fi
ac_fn_c_check_type "$LINENO" "ulong" "ac_cv_type_ulong" "$ac_includes_default"
if test "x$ac_cv_type_ulong" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define ulong unsigned long
_ACEOF
fi
for ac_func in fdopen ftruncate memmove mkdir mkstemp mktime timelocal \
localtime_r snprintf strcasecmp strncasecmp strtoul strerror vsnprintf
@ -3961,7 +3934,8 @@ rm -f conftest*
fi
if test $nufxlib_cv_snprintf_in_header = "yes"; then
$as_echo "#define SNPRINTF_DECLARED 1" >>confdefs.h
$as_echo "#define SNPRINTF_DECLARED /**/" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nufxlib_cv_snprintf_in_header" >&5
@ -3990,7 +3964,8 @@ rm -f conftest*
fi
if test $nufxlib_cv_vsnprintf_in_header = "yes"; then
$as_echo "#define VSNPRINTF_DECLARED 1" >>confdefs.h
$as_echo "#define VSNPRINTF_DECLARED /**/" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nufxlib_cv_vsnprintf_in_header" >&5
@ -4014,11 +3989,6 @@ elif test "$host_os" = "beos"; then
SHARE_FLAGS='-nostartfiles -Xlinker -soname="$@"'
fi
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
echo "checking for Mac OS X... yes, adding -framework Carbon"
LIBS="$LIBS -framework Carbon"
fi
@ -4063,7 +4033,7 @@ else
int count;
char buf[8];
count = sprintf(buf, "123"); /* should return three */
exit(count != 3);
return count != 3;
}
_ACEOF
@ -4081,7 +4051,8 @@ fi
if test $nufxlib_cv_sprintf_returns_int = "yes"; then
$as_echo "#define SPRINTF_RETURNS_INT 1" >>confdefs.h
$as_echo "#define SPRINTF_RETURNS_INT /**/" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nufxlib_cv_sprintf_returns_int" >&5
@ -4096,7 +4067,8 @@ else
fi
if test $enable_sq = "yes"; then
$as_echo "#define ENABLE_SQ 1" >>confdefs.h
$as_echo "#define ENABLE_SQ /**/" >>confdefs.h
fi
@ -4108,7 +4080,8 @@ else
fi
if test $enable_lzw = "yes"; then
$as_echo "#define ENABLE_LZW 1" >>confdefs.h
$as_echo "#define ENABLE_LZW /**/" >>confdefs.h
fi
@ -4120,7 +4093,8 @@ else
fi
if test $enable_lzc = "yes"; then
$as_echo "#define ENABLE_LZC 1" >>confdefs.h
$as_echo "#define ENABLE_LZC /**/" >>confdefs.h
fi
@ -4185,7 +4159,8 @@ fi
fi
if $got_zlibh; then
echo " (found libz and zlib.h, enabling deflate)"
$as_echo "#define ENABLE_DEFLATE 1" >>confdefs.h
$as_echo "#define ENABLE_DEFLATE /**/" >>confdefs.h
else
echo " (couldn't find libz and zlib.h, not enabling deflate)"
@ -4253,7 +4228,8 @@ fi
fi
if $got_bzlibh; then
echo " (found libbz2 and bzlib.h, enabling bzip2)"
$as_echo "#define ENABLE_BZIP2 1" >>confdefs.h
$as_echo "#define ENABLE_BZIP2 /**/" >>confdefs.h
else
echo " (couldn't find libbz2 and bzlib.h, not enabling bzip2)"
@ -4264,12 +4240,13 @@ fi
# Check whether --enable-dmalloc was given.
if test "${enable_dmalloc+set}" = set; then :
enableval=$enable_dmalloc; echo "--- enabling dmalloc";
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; $as_echo "#define USE_DMALLOC 1" >>confdefs.h
LIBS="$LIBS -L/usr/local/lib -ldmalloc";
$as_echo "#define USE_DMALLOC /**/" >>confdefs.h
fi
ac_config_files="$ac_config_files Makefile samples/Makefile"
ac_config_files="$ac_config_files Makefile samples/Makefile nufxlib.pc"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@ -4964,6 +4941,7 @@ do
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"samples/Makefile") CONFIG_FILES="$CONFIG_FILES samples/Makefile" ;;
"nufxlib.pc") CONFIG_FILES="$CONFIG_FILES nufxlib.pc" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac

View File

@ -16,6 +16,10 @@ AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_RANLIB
NUFX_VERSION=3.1.0
AC_SUBST(NUFX_VERSION)
dnl Checks for header files.
AC_CHECK_HEADERS(fcntl.h malloc.h stdlib.h sys/stat.h sys/time.h sys/types.h \
sys/utime.h unistd.h utime.h)
@ -29,10 +33,6 @@ AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_STRUCT_TM
AC_CHECK_TYPE(uchar, unsigned char)
AC_CHECK_TYPE(ushort, unsigned short)
AC_CHECK_TYPE(uint, unsigned int)
AC_CHECK_TYPE(ulong, unsigned long)
dnl Checks for library functions.
AC_CHECK_FUNCS(fdopen ftruncate memmove mkdir mkstemp mktime timelocal \
@ -46,7 +46,7 @@ AC_CACHE_VAL(nufxlib_cv_snprintf_in_header, [
[nufxlib_cv_snprintf_in_header=no])
])
if test $nufxlib_cv_snprintf_in_header = "yes"; then
AC_DEFINE(SNPRINTF_DECLARED)
AC_DEFINE(SNPRINTF_DECLARED, [], [Define it SNPRINTF is declared in stdio.h.])
fi
AC_MSG_RESULT($nufxlib_cv_snprintf_in_header)
@ -58,7 +58,7 @@ AC_CACHE_VAL(nufxlib_cv_vsnprintf_in_header, [
[nufxlib_cv_vsnprintf_in_header=no])
])
if test $nufxlib_cv_vsnprintf_in_header = "yes"; then
AC_DEFINE(VSNPRINTF_DECLARED)
AC_DEFINE(VSNPRINTF_DECLARED, [], [Define if VSNPRINTF is declared in stdio.h.])
fi
AC_MSG_RESULT($nufxlib_cv_vsnprintf_in_header)
@ -94,12 +94,6 @@ elif test "$host_os" = "beos"; then
SHARE_FLAGS='-nostartfiles -Xlinker -soname="$@"'
fi
dnl Mac OS X (powerpc-apple-darwin6.6) needs an extra flag.
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
echo "checking for Mac OS X... yes, adding -framework Carbon"
LIBS="$LIBS -framework Carbon"
fi
AC_SUBST(BUILD_FLAGS)
AC_SUBST(SHARE_FLAGS)
@ -140,7 +134,7 @@ AC_CACHE_VAL(nufxlib_cv_sprintf_returns_int, [
int count;
char buf[8];
count = sprintf(buf, "123"); /* should return three */
exit(count != 3);
return count != 3;
}
],
[nufxlib_cv_sprintf_returns_int=yes], [nufxlib_cv_sprintf_returns_int=no],
@ -148,7 +142,7 @@ AC_CACHE_VAL(nufxlib_cv_sprintf_returns_int, [
])
if test $nufxlib_cv_sprintf_returns_int = "yes"; then
AC_DEFINE(SPRINTF_RETURNS_INT)
AC_DEFINE(SPRINTF_RETURNS_INT, [], [Define if sprintf returns an int.])
fi
AC_MSG_RESULT($nufxlib_cv_sprintf_returns_int)
@ -165,21 +159,21 @@ AC_ARG_ENABLE(sq,
[ --disable-sq disable SQ compression],
[ ], [ enable_sq=yes ])
if test $enable_sq = "yes"; then
AC_DEFINE(ENABLE_SQ)
AC_DEFINE(ENABLE_SQ, [], [Define to include SQ (Huffman+RLE) compression.])
fi
AC_ARG_ENABLE(lzw,
[ --disable-lzw disable LZW/1 and LZW/2 compression],
[ ], [ enable_lzw=yes ])
if test $enable_lzw = "yes"; then
AC_DEFINE(ENABLE_LZW)
AC_DEFINE(ENABLE_LZW, [], [Define to include LZW (ShrinkIt LZW/1 and LZW/2) compression.])
fi
AC_ARG_ENABLE(lzc,
[ --disable-lzc disable 12- and 16-bit LZC compression],
[ ], [ enable_lzc=yes ])
if test $enable_lzc = "yes"; then
AC_DEFINE(ENABLE_LZC)
AC_DEFINE(ENABLE_LZC, [], [Define to include LZC (12-bit and 16-bit UNIX "compress") compression.])
fi
AC_ARG_ENABLE(deflate,
@ -194,7 +188,7 @@ if test $enable_deflate = "yes"; then
fi
if $got_zlibh; then
echo " (found libz and zlib.h, enabling deflate)"
AC_DEFINE(ENABLE_DEFLATE)
AC_DEFINE(ENABLE_DEFLATE, [], [Define to include deflate (zlib) compression (also need -l in Makefile).])
else
echo " (couldn't find libz and zlib.h, not enabling deflate)"
fi
@ -214,7 +208,7 @@ if test $enable_bzip2 = "yes"; then
fi
if $got_bzlibh; then
echo " (found libbz2 and bzlib.h, enabling bzip2)"
AC_DEFINE(ENABLE_BZIP2)
AC_DEFINE(ENABLE_BZIP2, [], [Define to include bzip2 (libbz2) compression (also need -l in Makefile).])
else
echo " (couldn't find libbz2 and bzlib.h, not enabling bzip2)"
fi
@ -223,6 +217,6 @@ fi
AC_ARG_ENABLE(dmalloc, [ --enable-dmalloc do dmalloc stuff],
[ echo "--- enabling dmalloc";
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC) ])
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC, [], [Define if we want to use the dmalloc library (also need -l in Makefile).]) ])
AC_OUTPUT(Makefile samples/Makefile)
AC_OUTPUT(Makefile samples/Makefile nufxlib.pc)

View File

@ -16,6 +16,8 @@ EXPORTS
NuAddThread
NuClose
NuContents
NuConvertMORToUNI
NuConvertUNIToMOR
NuCreateDataSinkForBuffer
NuCreateDataSinkForFP
NuCreateDataSinkForFile

10
nufxlib/nufxlib.pc.in Normal file
View File

@ -0,0 +1,10 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: nufxlib
Description: NuFX archive manipulation library.
Version: @NUFX_VERSION@
Libs: -L${libdir} -lnufx @LIBS@
Cflags: -I${includedir}

View File

@ -6,8 +6,8 @@
*
* Common functions for NuLib tests.
*/
#ifndef __Common__
#define __Common__
#ifndef NUFXLIB_SAMPLES_COMMON_H
#define NUFXLIB_SAMPLES_COMMON_H
#include "SysDefs.h" /* might as well draft off the autoconf */
#include "NufxLib.h"
@ -16,8 +16,6 @@
# include "dmalloc.h"
#endif
#define nil NULL /* this is seriously habit-forming */
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
#ifndef __cplusplus
@ -65,4 +63,4 @@
# define PATH_SEP '/'
#endif
#endif /*__Common__*/
#endif /*NUFXLIB_SAMPLES_COMMON_H*/

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,7 @@
#include "Common.h"
#ifndef HAVE_STRCASECMP
static int
strcasecmp(const char *str1, const char *str2)
static int strcasecmp(const char *str1, const char *str2)
{
while (*str1 && *str2 && toupper(*str1) == toupper(*str2))
str1++, str2++;
@ -51,35 +50,33 @@ strcasecmp(const char *str1, const char *str2)
typedef struct ImgHeader {
char magic[4];
char creator[4];
short headerLen;
short version;
long imageFormat;
unsigned long flags;
long numBlocks;
long dataOffset;
long dataLen;
long cmntOffset;
long cmntLen;
long creatorOffset;
long creatorLen;
long spare[4];
uint16_t headerLen;
uint16_t version;
uint32_t imageFormat;
uint32_t flags;
uint32_t numBlocks;
uint32_t dataOffset;
uint32_t dataLen;
uint32_t cmntOffset;
uint32_t cmntLen;
uint32_t creatorOffset;
uint32_t creatorLen;
uint32_t spare[4];
} ImgHeader;
/*
* Read a two-byte little-endian value.
*/
void
ReadShortLE(FILE* fp, short* pBuf)
void ReadShortLE(FILE* fp, uint16_t* pBuf)
{
*pBuf = getc(fp);
*pBuf += (short) getc(fp) << 8;
*pBuf += (uint16_t) getc(fp) << 8;
}
/*
* Write a two-byte little-endian value.
*/
void
WriteShortLE(FILE* fp, unsigned short val)
void WriteShortLE(FILE* fp, uint16_t val)
{
putc(val, fp);
putc(val >> 8, fp);
@ -88,20 +85,18 @@ WriteShortLE(FILE* fp, unsigned short val)
/*
* Read a four-byte little-endian value.
*/
void
ReadLongLE(FILE* fp, long* pBuf)
void ReadLongLE(FILE* fp, uint32_t* pBuf)
{
*pBuf = getc(fp);
*pBuf += (long) getc(fp) << 8;
*pBuf += (long) getc(fp) << 16;
*pBuf += (long) getc(fp) << 24;
*pBuf += (uint32_t) getc(fp) << 8;
*pBuf += (uint32_t) getc(fp) << 16;
*pBuf += (uint32_t) getc(fp) << 24;
}
/*
* Write a four-byte little-endian value.
*/
void
WriteLongLE(FILE* fp, unsigned long val)
void WriteLongLE(FILE* fp, uint32_t val)
{
putc(val, fp);
putc(val >> 8, fp);
@ -112,8 +107,7 @@ WriteLongLE(FILE* fp, unsigned long val)
/*
* Read the header from a 2IMG file.
*/
int
ReadImgHeader(FILE* fp, ImgHeader* pHeader)
int ReadImgHeader(FILE* fp, ImgHeader* pHeader)
{
size_t ignored;
ignored = fread(pHeader->magic, 4, 1, fp);
@ -121,7 +115,7 @@ ReadImgHeader(FILE* fp, ImgHeader* pHeader)
ReadShortLE(fp, &pHeader->headerLen);
ReadShortLE(fp, &pHeader->version);
ReadLongLE(fp, &pHeader->imageFormat);
ReadLongLE(fp, (long*)&pHeader->flags);
ReadLongLE(fp, &pHeader->flags);
ReadLongLE(fp, &pHeader->numBlocks);
ReadLongLE(fp, &pHeader->dataOffset);
ReadLongLE(fp, &pHeader->dataLen);
@ -154,8 +148,7 @@ ReadImgHeader(FILE* fp, ImgHeader* pHeader)
/*
* Write the header to a 2IMG file.
*/
int
WriteImgHeader(FILE* fp, ImgHeader* pHeader)
int WriteImgHeader(FILE* fp, ImgHeader* pHeader)
{
fwrite(pHeader->magic, 4, 1, fp);
fwrite(pHeader->creator, 4, 1, fp);
@ -185,23 +178,22 @@ WriteImgHeader(FILE* fp, ImgHeader* pHeader)
/*
* Dump the contents of an ImgHeader.
*/
void
DumpImgHeader(ImgHeader* pHeader)
void DumpImgHeader(ImgHeader* pHeader)
{
printf("--- header contents:\n");
printf("\tmagic = '%.4s'\n", pHeader->magic);
printf("\tcreator = '%.4s'\n", pHeader->creator);
printf("\theaderLen = %d\n", pHeader->headerLen);
printf("\tversion = %d\n", pHeader->version);
printf("\timageFormat = %ld\n", pHeader->imageFormat);
printf("\tflags = 0x%08lx\n", pHeader->flags);
printf("\tnumBlocks = %ld\n", pHeader->numBlocks);
printf("\tdataOffset = %ld\n", pHeader->dataOffset);
printf("\tdataLen = %ld\n", pHeader->dataLen);
printf("\tcmntOffset = %ld\n", pHeader->cmntOffset);
printf("\tcmntLen = %ld\n", pHeader->cmntLen);
printf("\tcreatorOffset = %ld\n", pHeader->creatorOffset);
printf("\tcreatorLen = %ld\n", pHeader->creatorLen);
printf("\timageFormat = %u\n", pHeader->imageFormat);
printf("\tflags = 0x%08x\n", pHeader->flags);
printf("\tnumBlocks = %u\n", pHeader->numBlocks);
printf("\tdataOffset = %u\n", pHeader->dataOffset);
printf("\tdataLen = %u\n", pHeader->dataLen);
printf("\tcmntOffset = %u\n", pHeader->cmntOffset);
printf("\tcmntLen = %u\n", pHeader->cmntLen);
printf("\tcreatorOffset = %u\n", pHeader->creatorOffset);
printf("\tcreatorLen = %u\n", pHeader->creatorLen);
printf("\n");
}
@ -217,8 +209,7 @@ typedef enum ArchiveKind { kKindUnknown, kKindShk, kKindImg } ArchiveKind;
/*
* This gets called when a buffer DataSource is no longer needed.
*/
NuResult
FreeCallback(NuArchive* pArchive, void* args)
NuResult FreeCallback(NuArchive* pArchive, void* args)
{
free(args);
return kNuOK;
@ -227,8 +218,7 @@ FreeCallback(NuArchive* pArchive, void* args)
/*
* This gets called when an "FP" DataSource is no longer needed.
*/
NuResult
FcloseCallback(NuArchive* pArchive, void* args)
NuResult FcloseCallback(NuArchive* pArchive, void* args)
{
fclose((FILE*) args);
return kNuOK;
@ -242,8 +232,7 @@ FcloseCallback(NuArchive* pArchive, void* args)
* of NufxLib. We could just as easily not set it and call fclose()
* ourselves, because the structure of this program is pretty simple.
*/
NuError
CreateProdosSource(const ImgHeader* pHeader, FILE* fp,
NuError CreateProdosSource(const ImgHeader* pHeader, FILE* fp,
NuDataSource** ppDataSource)
{
return NuCreateDataSourceForFP(kNuThreadFormatUncompressed, 0, fp,
@ -254,17 +243,16 @@ CreateProdosSource(const ImgHeader* pHeader, FILE* fp,
* Create a data source for a DOS-ordered image. This is a little harder,
* since we have to reorder the blocks into ProDOS ordering for ShrinkIt.
*/
NuError
CreateDosSource(const ImgHeader* pHeader, FILE* fp,
NuError CreateDosSource(const ImgHeader* pHeader, FILE* fp,
NuDataSource** ppDataSource)
{
NuError err;
char* diskBuffer = nil;
char* diskBuffer = NULL;
long offset;
if (pHeader->dataLen % 4096) {
fprintf(stderr,
"ERROR: image size must be multiple of 4096 (%ld isn't)\n",
"ERROR: image size must be multiple of 4096 (%u isn't)\n",
pHeader->dataLen);
err = kNuErrGeneric;
goto bail;
@ -277,8 +265,8 @@ CreateDosSource(const ImgHeader* pHeader, FILE* fp,
}
diskBuffer = malloc(pHeader->dataLen);
if (diskBuffer == nil) {
fprintf(stderr, "ERROR: malloc(%ld) failed\n", pHeader->dataLen);
if (diskBuffer == NULL) {
fprintf(stderr, "ERROR: malloc(%u) failed\n", pHeader->dataLen);
err = kNuErrMalloc;
goto bail;
}
@ -288,7 +276,7 @@ CreateDosSource(const ImgHeader* pHeader, FILE* fp,
* reversible transformation, i.e. if you do this twice you're back
* to ProDOS ordering.
*/
for (offset = 0; offset < pHeader->dataLen; offset += 4096) {
for (offset = 0; offset < (long) pHeader->dataLen; offset += 4096) {
size_t ignored;
ignored = fread(diskBuffer + offset + 0x0000, 256, 1, fp);
ignored = fread(diskBuffer + offset + 0x0e00, 256, 1, fp);
@ -319,13 +307,13 @@ CreateDosSource(const ImgHeader* pHeader, FILE* fp,
* "true", so NufxLib will free the buffer for us.
*/
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed, 0,
(const unsigned char*) diskBuffer, 0, pHeader->dataLen,
(const uint8_t*) diskBuffer, 0, pHeader->dataLen,
FreeCallback, ppDataSource);
if (err == kNuErrNone)
diskBuffer = nil;
diskBuffer = NULL;
bail:
if (diskBuffer != nil)
if (diskBuffer != NULL)
free(diskBuffer);
return err;
}
@ -338,18 +326,17 @@ bail:
* This requires opening up the 2IMG file, verifying that it's okay, and
* then creating a new disk image record and thread.
*/
int
ConvertFromImgToShk(const char* srcName, const char* dstName)
int ConvertFromImgToShk(const char* srcName, const char* dstName)
{
NuError err;
NuArchive* pArchive = nil;
NuDataSource* pDataSource = nil;
NuArchive* pArchive = NULL;
NuDataSource* pDataSource = NULL;
NuRecordIdx recordIdx;
NuFileDetails fileDetails;
ImgHeader header;
FILE* fp = nil;
long flushStatus;
char* storageName = nil;
FILE* fp = NULL;
uint32_t flushStatus;
char* storageName = NULL;
char* cp;
printf("Converting 2IMG file '%s' to ShrinkIt archive '%s'\n\n",
@ -394,10 +381,10 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
/* create the name that will be stored in the archive */
storageName = strdup(dstName);
cp = strrchr(storageName, '.');
if (cp != nil)
if (cp != NULL)
*cp = '\0';
cp = strrchr(storageName, kLocalFssep);
if (cp != nil && *(cp+1) != '\0')
if (cp != NULL && *(cp+1) != '\0')
cp++;
else
cp = storageName;
@ -410,7 +397,7 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
/* set up the contents of the NuFX Record */
memset(&fileDetails, 0, sizeof(fileDetails));
fileDetails.storageName = cp;
fileDetails.storageNameMOR = cp;
fileDetails.fileSysID = kNuFileSysUnknown; /* DOS? ProDOS? */
fileDetails.fileSysInfo = kLocalFssep;
fileDetails.access = kNuAccessUnlocked;
@ -433,11 +420,11 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
switch (header.imageFormat) {
case kImageFormatDOS:
err = CreateDosSource(&header, fp, &pDataSource);
fp = nil;
fp = NULL;
break;
case kImageFormatProDOS:
err = CreateProdosSource(&header, fp, &pDataSource);
fp = nil;
fp = NULL;
break;
default:
fprintf(stderr, "How the heck did I get here?");
@ -451,17 +438,17 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
/* add a disk image thread */
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDiskImage, pDataSource,
nil);
NULL);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to create thread (err=%d)\n", err);
goto bail;
}
pDataSource = nil; /* library owns it now */
pDataSource = NULL; /* library owns it now */
/* nothing happens until we Flush */
err = NuFlush(pArchive, &flushStatus);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: flush failed (err=%d, status=0x%04lx)\n",
fprintf(stderr, "ERROR: flush failed (err=%d, status=0x%04x)\n",
err, flushStatus);
goto bail;
}
@ -470,17 +457,17 @@ ConvertFromImgToShk(const char* srcName, const char* dstName)
fprintf(stderr, "ERROR: close failed (err=%d)\n", err);
goto bail;
}
pArchive = nil;
pArchive = NULL;
bail:
if (pArchive != nil) {
if (pArchive != NULL) {
(void)NuAbort(pArchive);
(void)NuClose(pArchive);
}
NuFreeDataSource(pDataSource);
if (storageName != nil)
if (storageName != NULL)
free(storageName);
if (fp != nil)
if (fp != NULL)
fclose(fp);
return (err == kNuErrNone) ? 0 : -1;
}
@ -492,17 +479,16 @@ bail:
* This takes a simple-minded approach and assumes that the first record
* in the archive has the disk image in it. If it doesn't, we give up.
*/
int
ConvertFromShkToImg(const char* srcName, const char* dstName)
int ConvertFromShkToImg(const char* srcName, const char* dstName)
{
NuError err;
NuArchive* pArchive = nil;
NuDataSink* pDataSink = nil;
NuArchive* pArchive = NULL;
NuDataSink* pDataSink = NULL;
NuRecordIdx recordIdx;
const NuRecord* pRecord;
const NuThread* pThread = nil;
const NuThread* pThread = NULL;
ImgHeader header;
FILE* fp = nil;
FILE* fp = NULL;
int idx;
printf("Converting ShrinkIt archive '%s' to 2IMG file '%s'\n\n",
@ -592,10 +578,10 @@ ConvertFromShkToImg(const char* srcName, const char* dstName)
}
bail:
if (pArchive != nil)
if (pArchive != NULL)
NuClose(pArchive);
NuFreeDataSink(pDataSink);
if (fp != nil)
if (fp != NULL)
fclose(fp);
return (err == kNuErrNone) ? 0 : -1;
}
@ -604,13 +590,12 @@ bail:
/*
* Figure out what kind of archive this is by looking at the filename.
*/
ArchiveKind
DetermineKind(const char* filename)
ArchiveKind DetermineKind(const char* filename)
{
const char* dot;
dot = strrchr(filename, '.');
if (dot == nil)
if (dot == NULL)
return kKindUnknown;
if (strcasecmp(dot, ".shk") == 0 || strcasecmp(dot, ".sdk") == 0)
@ -626,8 +611,7 @@ DetermineKind(const char* filename)
/*
* Figure out what we want to do.
*/
int
main(int argc, char** argv)
int main(int argc, char** argv)
{
ArchiveKind kind;
int cc;

View File

@ -47,8 +47,7 @@ char gSentRecordWarning = false;
/*
* This gets called when a buffer DataSource is no longer needed.
*/
NuResult
FreeCallback(NuArchive* pArchive, void* args)
NuResult FreeCallback(NuArchive* pArchive, void* args)
{
free(args);
return kNuOK;
@ -60,14 +59,13 @@ FreeCallback(NuArchive* pArchive, void* args)
* This assumes the library is configured for compression (it defaults
* to LZW/2, so this is a reasonable assumption).
*/
NuError
CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
NuError CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
long flags, const NuThread* pThread, long newRecordIdx)
{
NuError err = kNuErrNone;
NuDataSource* pDataSource = nil;
NuDataSink* pDataSink = nil;
uchar* buffer = nil;
NuDataSource* pDataSource = NULL;
NuDataSink* pDataSink = NULL;
uint8_t* buffer = NULL;
/*
* Allocate a buffer large enough to hold all the uncompressed data, and
@ -77,7 +75,7 @@ CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
*/
if (pThread->actualThreadEOF) {
buffer = malloc(pThread->actualThreadEOF);
if (buffer == nil) {
if (buffer == NULL) {
err = kNuErrMalloc;
goto bail;
}
@ -95,7 +93,7 @@ CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
*/
err = NuExtractThread(pInArchive, pThread->threadIdx, pDataSink);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to extract thread %ld (err=%d)\n",
fprintf(stderr, "ERROR: unable to extract thread %u (err=%d)\n",
pThread->threadIdx, err);
goto bail;
}
@ -111,7 +109,7 @@ CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
* We always use "actualThreadEOF" because "thThreadEOF" is broken
* for disk archives created by certain versions of ShrinkIt.
*
* It's okay to pass in a nil value for "buffer", so long as the
* It's okay to pass in a NULL value for "buffer", so long as the
* amount of data in the buffer is also zero. The library will do
* the right thing.
*/
@ -134,25 +132,25 @@ CopyThreadRecompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
goto bail;
}
}
buffer = nil; /* doClose was set, so it's owned by the data source */
buffer = NULL; /* doClose was set, so it's owned by the data source */
/*
* Schedule the data for addition to the record.
*/
err = NuAddThread(pOutArchive, newRecordIdx, NuGetThreadID(pThread),
pDataSource, nil);
pDataSource, NULL);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to add thread (err=%d)\n", err);
goto bail;
}
pDataSource = nil; /* library owns it now */
pDataSource = NULL; /* library owns it now */
bail:
if (pDataSource != nil)
if (pDataSource != NULL)
NuFreeDataSource(pDataSource);
if (pDataSink != nil)
if (pDataSink != NULL)
NuFreeDataSink(pDataSink);
if (buffer != nil)
if (buffer != NULL)
free(buffer);
return err;
}
@ -174,14 +172,13 @@ bail:
* reliable but extracts a little more than we need on pre-sized
* threads (filenames, comments).
*/
NuError
CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
NuError CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
long flags, const NuThread* pThread, long newRecordIdx)
{
NuError err = kNuErrNone;
NuDataSource* pDataSource = nil;
NuDataSink* pDataSink = nil;
uchar* buffer = nil;
NuDataSource* pDataSource = NULL;
NuDataSink* pDataSink = NULL;
uint8_t* buffer = NULL;
/*
* If we have some data files that were left uncompressed, perhaps
@ -207,7 +204,7 @@ CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
* wrap a data sink around it.
*/
buffer = malloc(pThread->thCompThreadEOF);
if (buffer == nil) {
if (buffer == NULL) {
err = kNuErrMalloc;
goto bail;
}
@ -225,7 +222,7 @@ CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
*/
err = NuExtractThread(pInArchive, pThread->threadIdx, pDataSink);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to extract thread %ld (err=%d)\n",
fprintf(stderr, "ERROR: unable to extract thread %u (err=%d)\n",
pThread->threadIdx, err);
goto bail;
}
@ -265,7 +262,7 @@ CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
goto bail;
}
}
buffer = nil; /* doClose was set, so it's owned by the data source */
buffer = NULL; /* doClose was set, so it's owned by the data source */
/* yes, this is a kluge... sigh */
err = NuDataSourceSetRawCrc(pDataSource, pThread->thThreadCRC);
@ -281,19 +278,19 @@ CopyThreadUncompressed(NuArchive* pInArchive, NuArchive* pOutArchive,
* "doClose" on our copy, so we are free to dispose of pDataSource.
*/
err = NuAddThread(pOutArchive, newRecordIdx, NuGetThreadID(pThread),
pDataSource, nil);
pDataSource, NULL);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to add thread (err=%d)\n", err);
goto bail;
}
pDataSource = nil; /* library owns it now */
pDataSource = NULL; /* library owns it now */
bail:
if (pDataSource != nil)
if (pDataSource != NULL)
NuFreeDataSource(pDataSource);
if (pDataSink != nil)
if (pDataSink != NULL)
NuFreeDataSink(pDataSink);
if (buffer != nil)
if (buffer != NULL)
free(buffer);
return err;
}
@ -305,8 +302,7 @@ bail:
* Depending on "flags", this will either copy it raw or uncompress and
* recompress.
*/
NuError
CopyThread(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
NuError CopyThread(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
const NuThread* pThread, long newRecordIdx)
{
if (flags & kFlagCopyOnly) {
@ -327,8 +323,7 @@ CopyThread(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
* of which will not usually have any effect since NufxLib imposes a
* specific thread ordering on most common types) depending on "flags".
*/
NuError
CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
NuError CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
NuRecordIdx recordIdx)
{
NuError err = kNuErrNone;
@ -344,7 +339,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
*/
err = NuGetRecord(pInArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to get recordIdx %ld\n", recordIdx);
fprintf(stderr, "ERROR: unable to get recordIdx %u\n", recordIdx);
goto bail;
}
@ -362,7 +357,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
numThreads = NuRecordGetNumThreads(pRecord);
if (!numThreads) {
fprintf(stderr, "WARNING: recordIdx=%ld was empty\n", recordIdx);
fprintf(stderr, "WARNING: recordIdx=%u was empty\n", recordIdx);
goto bail;
}
@ -370,7 +365,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
* Create a new record that looks just like the original.
*/
memset(&fileDetails, 0, sizeof(fileDetails));
fileDetails.storageName = pRecord->filename;
fileDetails.storageNameMOR = pRecord->filenameMOR;
fileDetails.fileSysID = pRecord->recFileSysID;
fileDetails.fileSysInfo = pRecord->recFileSysInfo;
fileDetails.access = pRecord->recAccess;
@ -393,7 +388,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
if (flags & kFlagReverseThreads) {
for (idx = numThreads-1; idx >= 0; idx--) {
pThread = NuGetThread(pRecord, idx);
assert(pThread != nil);
assert(pThread != NULL);
err = CopyThread(pInArchive, pOutArchive, flags, pThread,
newRecordIdx);
@ -403,7 +398,7 @@ CopyRecord(NuArchive* pInArchive, NuArchive* pOutArchive, long flags,
} else {
for (idx = 0; idx < numThreads; idx++) {
pThread = NuGetThread(pRecord, idx);
assert(pThread != nil);
assert(pThread != NULL);
err = CopyThread(pInArchive, pOutArchive, flags, pThread,
newRecordIdx);
@ -422,16 +417,15 @@ bail:
*
* Returns 0 on success, nonzero on failure.
*/
int
LaunderArchive(const char* inFile, const char* outFile, NuValue compressMethod,
long flags)
int LaunderArchive(const char* inFile, const char* outFile,
NuValue compressMethod, long flags)
{
NuError err = kNuErrNone;
NuArchive* pInArchive = nil;
NuArchive* pOutArchive = nil;
NuArchive* pInArchive = NULL;
NuArchive* pOutArchive = NULL;
const NuMasterHeader* pMasterHeader;
NuRecordIdx recordIdx;
long idx, flushStatus;
uint32_t idx, flushStatus;
err = NuOpenRO(inFile, &pInArchive);
if (err != kNuErrNone) {
@ -487,10 +481,10 @@ LaunderArchive(const char* inFile, const char* outFile, NuValue compressMethod,
/*
* Iterate through the set of records.
*/
for (idx = 0; idx < (int)pMasterHeader->mhTotalRecords; idx++) {
for (idx = 0; idx < pMasterHeader->mhTotalRecords; idx++) {
err = NuGetRecordIdxByPosition(pInArchive, idx, &recordIdx);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't get record #%ld (err=%d)\n",
fprintf(stderr, "ERROR: couldn't get record #%u (err=%d)\n",
idx, err);
goto bail;
}
@ -525,7 +519,7 @@ LaunderArchive(const char* inFile, const char* outFile, NuValue compressMethod,
err = NuFlush(pOutArchive, &flushStatus);
if (err != kNuErrNone) {
fprintf(stderr,
"ERROR: flush failed (err=%d, status=0x%04lx)\n",
"ERROR: flush failed (err=%d, status=0x%04x)\n",
err, flushStatus);
goto bail;
}
@ -535,15 +529,15 @@ LaunderArchive(const char* inFile, const char* outFile, NuValue compressMethod,
/* first and only flush if frequent-flushing wasn't enabled */
err = NuFlush(pOutArchive, &flushStatus);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: flush failed (err=%d, status=0x%04lx)\n",
fprintf(stderr, "ERROR: flush failed (err=%d, status=0x%04x)\n",
err, flushStatus);
goto bail;
}
bail:
if (pInArchive != nil)
if (pInArchive != NULL)
NuClose(pInArchive);
if (pOutArchive != nil) {
if (pOutArchive != NULL) {
if (err != kNuErrNone)
NuAbort(pOutArchive);
NuClose(pOutArchive); /* flush pending changes and close */
@ -559,12 +553,11 @@ bail:
* does everything we need here.
*/
int myoptind = 0;
char* myoptarg = nil;
const char* curchar = nil;
char* myoptarg = NULL;
const char* curchar = NULL;
int skipnext = false;
int
mygetopt(int argc, char** argv, const char* optstr)
int mygetopt(int argc, char** argv, const char* optstr)
{
if (!myoptind) {
myoptind = 1;
@ -609,8 +602,7 @@ mygetopt(int argc, char** argv, const char* optstr)
/*
* Print usage info.
*/
void
Usage(const char* argv0)
void Usage(const char* argv0)
{
fprintf(stderr, "Usage: %s [-crfat] [-m method] infile.shk outfile.shk\n",
argv0);
@ -627,19 +619,18 @@ Usage(const char* argv0)
/*
* Grab the name of an archive to read.
*/
int
main(int argc, char** argv)
int main(int argc, char** argv)
{
NuValue compressMethod = kNuCompressLZW2;
long major, minor, bug;
int32_t major, minor, bug;
const char* pBuildDate;
long flags = 0;
int errorFlag;
int ic;
int cc;
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, nil);
printf("Using NuFX lib %ld.%ld.%ld built on or after %s\n",
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, NULL);
printf("Using NuFX lib %d.%d.%d built on or after %s\n",
major, minor, bug, pBuildDate);
errorFlag = false;

View File

@ -28,49 +28,35 @@ ALL_SRCS = Exerciser.c ImgConv.c Launder.c TestBasic.c \
NUFXLIB = -L.. -lnufx
PRODUCTS = exerciser imgconv launder test-basic test-extract test-simple \
test-twirl
#ifdef PURIFY_BUILD
# PURIFY = purify
# CFLAGS += -DPURIFY
#endif
#ifdef QUANTIFY_BUILD
# QUANTIFY = quantify
# CFLAGS += -DQUANTIFY
#endif
PRODUCTS = exerciser imgconv launder test-basic test-extract test-names \
test-simple test-twirl
all: $(PRODUCTS)
@true
#quantify:
# -rm -f $(PRODUCT)
# @$(MAKE) QUANTIFY_BUILD=1
#
#purify:
# -rm -f $(PRODUCT)
# @$(MAKE) PURIFY_BUILD=1
exerciser: Exerciser.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ Exerciser.o $(NUFXLIB) @LIBS@
$(CC) -o $@ Exerciser.o $(NUFXLIB) @LIBS@
imgconv: ImgConv.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ ImgConv.o $(NUFXLIB) @LIBS@
$(CC) -o $@ ImgConv.o $(NUFXLIB) @LIBS@
launder: Launder.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ Launder.o $(NUFXLIB) @LIBS@
$(CC) -o $@ Launder.o $(NUFXLIB) @LIBS@
test-basic: TestBasic.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestBasic.o $(NUFXLIB) @LIBS@
test-simple: TestSimple.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestSimple.o $(NUFXLIB) @LIBS@
$(CC) -o $@ TestBasic.o $(NUFXLIB) @LIBS@
test-extract: TestExtract.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestExtract.o $(NUFXLIB) @LIBS@
$(CC) -o $@ TestExtract.o $(NUFXLIB) @LIBS@
test-names: TestNames.o $(LIB_PRODUCT)
$(CC) -o $@ TestNames.o $(NUFXLIB) @LIBS@
test-simple: TestSimple.o $(LIB_PRODUCT)
$(CC) -o $@ TestSimple.o $(NUFXLIB) @LIBS@
test-twirl: TestTwirl.o $(LIB_PRODUCT)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ TestTwirl.o $(NUFXLIB) @LIBS@
$(CC) -o $@ TestTwirl.o $(NUFXLIB) @LIBS@
tags::
ctags --totals -R ../*
@ -84,8 +70,12 @@ distclean: clean
-rm -f tags
-rm -f Makefile Makefile.bak
depend:
makedepend -- $(CFLAGS) -I/usr/local/include -- $(ALL_SRCS)
# DO NOT DELETE THIS LINE -- make depend depends on it.
COMMON_HDRS = ../NufxLibPriv.h ../NufxLib.h ../MiscStuff.h ../SysDefs.h
Exerciser.o: Exerciser.c $(COMMON_HDRS)
ImgConv.o: ImgConv.c $(COMMON_HDRS)
Launder.o: Launder.c $(COMMON_HDRS)
TestBasic.o: TestBasic.c $(COMMON_HDRS)
TestExtract.o: TestExtract.c $(COMMON_HDRS)
TestNames.o: TestNames.c $(COMMON_HDRS)
TestSimple.o: TestSimple.c $(COMMON_HDRS)
TestTwirl.o: TestTwirl.c $(COMMON_HDRS)

View File

@ -8,6 +8,9 @@ test-basic
Basic tests. Run this to verify that things are working.
On Win32 there will be a second executable, test-basic-d, that links against
the DLL rather than the static library.
exerciser
=========
@ -82,6 +85,15 @@ of memory on very large archives, you can reduce the memory requirements
by specifying the "-f" flag.
test-names
==========
Tests Unicode filename handling. Run without arguments.
(This currently fails on Win32 because the Unicode filename support is
incomplete there.)
test-simple
===========

View File

@ -15,6 +15,8 @@
#define kTestTempFile "nlbt.tmp"
#define kNumEntries 3 /* how many records are we going to add? */
/* stick to ASCII characters for these -- not doing conversions just yet */
#define kTestEntryBytes "bytes"
#define kTestEntryBytesUPPER "BYTES"
#define kTestEntryEnglish "English"
@ -39,12 +41,11 @@ char gSuppressError = false;
/*
* Get a single character of input from the user.
*/
static char
TGetReplyChar(char defaultReply)
static char TGetReplyChar(char defaultReply)
{
char tmpBuf[32];
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == nil)
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == NULL)
return defaultReply;
if (tmpBuf[0] == '\n' || tmpBuf[0] == '\r')
return defaultReply;
@ -52,14 +53,13 @@ TGetReplyChar(char defaultReply)
return tmpBuf[0];
}
NuError
AddSimpleRecord(NuArchive* pArchive, const char* filename,
NuError AddSimpleRecord(NuArchive* pArchive, const char* filenameMOR,
NuRecordIdx* pRecordIdx)
{
NuFileDetails fileDetails;
memset(&fileDetails, 0, sizeof(fileDetails));
fileDetails.storageName = filename;
fileDetails.storageNameMOR = filenameMOR;
fileDetails.fileSysInfo = kLocalFssep;
fileDetails.access = kNuAccessUnlocked;
@ -70,8 +70,7 @@ AddSimpleRecord(NuArchive* pArchive, const char* filename,
/*
* Display error messages... or not.
*/
NuResult
ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
NuResult ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
{
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
@ -80,12 +79,12 @@ ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
if (pErrorMessage->isDebug) {
fprintf(stderr, "%sNufxLib says: [%s:%d %s] %s\n",
pArchive == nil ? "GLOBAL>" : "",
pArchive == NULL ? "GLOBAL>" : "",
pErrorMessage->file, pErrorMessage->line, pErrorMessage->function,
pErrorMessage->message);
} else {
fprintf(stderr, "%sNufxLib says: %s\n",
pArchive == nil ? "GLOBAL>" : "",
pArchive == NULL ? "GLOBAL>" : "",
pErrorMessage->message);
}
@ -95,13 +94,37 @@ ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
/*
* This gets called when a buffer DataSource is no longer needed.
*/
NuResult
FreeCallback(NuArchive* pArchive, void* args)
NuResult FreeCallback(NuArchive* pArchive, void* args)
{
free(args);
return kNuOK;
}
/*
* If the test file currently exists, ask the user if it's okay to remove
* it.
*
* Returns 0 if the file was successfully removed, -1 if the file could not
* be removed (because the unlink failed, or the user refused).
*/
int RemoveTestFile(const char* title, const char* fileName)
{
char answer;
if (access(fileName, F_OK) == 0) {
printf("%s '%s' exists, remove (y/n)? ", title, fileName);
fflush(stdout);
answer = TGetReplyChar('n');
if (tolower(answer) != 'y')
return -1;
if (unlink(fileName) < 0) {
perror("unlink");
return -1;
}
}
return 0;
}
/*
* ===========================================================================
@ -113,21 +136,20 @@ FreeCallback(NuArchive* pArchive, void* args)
* Make sure the flags that control how we open the file work right,
* and verify that we handle existing zero-byte archive files correctly.
*/
int
Test_OpenFlags(void)
int Test_OpenFlags(void)
{
NuError err;
FILE* fp = nil;
NuArchive* pArchive = nil;
FILE* fp = NULL;
NuArchive* pArchive = NULL;
printf("... open zero-byte existing\n");
fp = fopen(kTestArchive, kNuFileOpenWriteTrunc);
if (fp == nil) {
if (fp == NULL) {
perror("fopen kTestArchive");
goto failed;
}
fclose(fp);
fp = nil;
fp = NULL;
FAIL_OK;
err = NuOpenRW(kTestArchive, kTestTempFile, kNuOpenCreat|kNuOpenExcl,
@ -149,7 +171,7 @@ Test_OpenFlags(void)
fprintf(stderr, "ERROR: close failed\n");
goto failed;
}
pArchive = nil;
pArchive = NULL;
if (access(kTestArchive, F_OK) == 0) {
fprintf(stderr, "ERROR: archive should have been removed but wasn't\n");
@ -159,7 +181,7 @@ Test_OpenFlags(void)
return 0;
failed:
if (pArchive != nil) {
if (pArchive != NULL) {
NuAbort(pArchive);
NuClose(pArchive);
}
@ -170,14 +192,13 @@ failed:
/*
* Add some files to the archive. These will be used by later tests.
*/
int
Test_AddStuff(NuArchive* pArchive)
int Test_AddStuff(NuArchive* pArchive)
{
NuError err;
uchar* buf = nil;
NuDataSource* pDataSource = nil;
uint8_t* buf = NULL;
NuDataSource* pDataSource = NULL;
NuRecordIdx recordIdx;
long status;
uint32_t status;
int i;
static const char* testMsg =
"This is a nice test message that has linefeeds in it so we can\n"
@ -185,20 +206,20 @@ Test_AddStuff(NuArchive* pArchive)
"all. It's certainly nice to know that everything works the way\n"
"it's supposed to, which I suppose is why we have this nifty test\n"
"program available. It sure would be nice if everybody tested\n"
"there code, but where would Microsoft be without endless upgrades\n"
"their code, but where would Microsoft be without endless upgrades\n"
"and service packs? Bugs are what America was built on, and\n"
"anybody who says otherwise is a pinko commie lowlife. Verily.\n";
printf("... add 'bytes' record\n");
buf = malloc(131072);
if (buf == nil)
if (buf == NULL)
goto failed;
for (i = 0; i < 131072; i++)
*(buf+i) = i & 0xff;
FAIL_OK;
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
0, nil, 0, 131072, FreeCallback, &pDataSource);
0, NULL, 0, 131072, FreeCallback, &pDataSource);
FAIL_BAD;
if (err == kNuErrNone) {
fprintf(stderr, "ERROR: that should've failed!\n");
@ -215,7 +236,7 @@ Test_AddStuff(NuArchive* pArchive)
"ERROR: 'bytes' data source create failed (err=%d)\n", err);
goto failed;
}
buf = nil; /* now owned by library */
buf = NULL; /* now owned by library */
err = AddSimpleRecord(pArchive, kTestEntryBytes, &recordIdx);
if (err != kNuErrNone) {
@ -224,12 +245,12 @@ Test_AddStuff(NuArchive* pArchive)
}
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDataFork, pDataSource,
nil);
NULL);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: 'bytes' thread add failed (err=%d)\n", err);
goto failed;
}
pDataSource = nil; /* now owned by library */
pDataSource = NULL; /* now owned by library */
/*
@ -237,7 +258,7 @@ Test_AddStuff(NuArchive* pArchive)
*/
printf("... add 'English' record\n");
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
0, (const uchar*)testMsg, 0, strlen(testMsg), nil, &pDataSource);
0, (const uint8_t*)testMsg, 0, strlen(testMsg), NULL, &pDataSource);
if (err != kNuErrNone) {
fprintf(stderr,
"ERROR: 'English' source create failed (err=%d)\n", err);
@ -246,7 +267,7 @@ Test_AddStuff(NuArchive* pArchive)
FAIL_OK;
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDataFork, pDataSource,
nil);
NULL);
FAIL_BAD;
if (err == kNuErrNone) {
fprintf(stderr, "ERROR: 'English' add should've conflicted!\n");
@ -268,20 +289,21 @@ Test_AddStuff(NuArchive* pArchive)
}
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDataFork, pDataSource,
nil);
NULL);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: 'English' thread add failed (err=%d)\n", err);
goto failed;
}
pDataSource = nil; /* now owned by library */
pDataSource = NULL; /* now owned by library */
/*
* Create an empty file with a rather non-empty name.
* Create an empty file with a rather non-empty name. Add it as
* a resource fork.
*/
printf("... add 'long' record\n");
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
0, nil, 0, 0, nil, &pDataSource);
0, NULL, 0, 0, NULL, &pDataSource);
if (err != kNuErrNone) {
fprintf(stderr,
"ERROR: 'English' source create failed (err=%d)\n", err);
@ -295,12 +317,12 @@ Test_AddStuff(NuArchive* pArchive)
}
err = NuAddThread(pArchive, recordIdx, kNuThreadIDRsrcFork, pDataSource,
nil);
NULL);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: 'long' thread add failed (err=%d)\n", err);
goto failed;
}
pDataSource = nil; /* now owned by library */
pDataSource = NULL; /* now owned by library */
/*
@ -308,7 +330,7 @@ Test_AddStuff(NuArchive* pArchive)
*/
err = NuFlush(pArchive, &status);
if (err != kNuErrNone) {
fprintf(stderr,"ERROR: couldn't flush after add (err=%d, status=%ld)\n",
fprintf(stderr, "ERROR: couldn't flush after add (err=%d, status=%u)\n",
err, status);
goto failed;
}
@ -318,16 +340,16 @@ Test_AddStuff(NuArchive* pArchive)
*/
err = NuFlush(pArchive, &status);
if (err != kNuErrNone) {
fprintf(stderr,"ERROR: second add flush failed (err=%d, status=%ld)\n",
fprintf(stderr, "ERROR: second add flush failed (err=%d, status=%u)\n",
err, status);
goto failed;
}
return 0;
failed:
if (pDataSource != nil)
if (pDataSource != NULL)
NuFreeDataSource(pDataSource);
if (buf != nil)
if (buf != NULL)
free(buf);
return -1;
}
@ -336,19 +358,18 @@ failed:
/*
* Make sure that what we're seeing makes sense.
*/
NuResult
TestContentsCallback(NuArchive* pArchive, void* vpRecord)
NuResult TestContentsCallback(NuArchive* pArchive, void* vpRecord)
{
const NuRecord* pRecord = (NuRecord*) vpRecord;
if (strcmp(pRecord->filename, kTestEntryBytes) == 0 ||
strcmp(pRecord->filename, kTestEntryEnglish) == 0 ||
strcmp(pRecord->filename, kTestEntryLong) == 0)
if (strcmp(pRecord->filenameMOR, kTestEntryBytes) == 0 ||
strcmp(pRecord->filenameMOR, kTestEntryEnglish) == 0 ||
strcmp(pRecord->filenameMOR, kTestEntryLong) == 0)
{
return kNuOK;
}
fprintf(stderr, "ERROR: found mystery entry '%s'\n", pRecord->filename);
fprintf(stderr, "ERROR: found mystery entry '%s'\n", pRecord->filenameMOR);
return kNuAbort;
}
@ -356,8 +377,7 @@ TestContentsCallback(NuArchive* pArchive, void* vpRecord)
/*
* Verify that the contents look about right.
*/
int
Test_Contents(NuArchive* pArchive)
int Test_Contents(NuArchive* pArchive)
{
NuError err;
long posn;
@ -386,21 +406,21 @@ Test_Contents(NuArchive* pArchive)
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
recordIdx, err);
goto failed;
}
assert(pRecord != nil);
assert(pRecord != NULL);
switch (posn) {
case 0:
cc = strcmp(pRecord->filename, kTestEntryBytes);
cc = strcmp(pRecord->filenameMOR, kTestEntryBytes);
break;
case 1:
cc = strcmp(pRecord->filename, kTestEntryEnglish);
cc = strcmp(pRecord->filenameMOR, kTestEntryEnglish);
break;
case 2:
cc = strcmp(pRecord->filename, kTestEntryLong);
cc = strcmp(pRecord->filenameMOR, kTestEntryLong);
if (!cc)
cc = !(pRecord->recStorageType == kNuStorageExtended);
break;
@ -411,8 +431,8 @@ Test_Contents(NuArchive* pArchive)
}
if (cc) {
fprintf(stderr, "ERROR: got '%s' for %ld (%ld), not expected\n",
pRecord->filename, posn, recordIdx);
fprintf(stderr, "ERROR: got '%s' for %ld (%u), not expected\n",
pRecord->filenameMOR, posn, recordIdx);
goto failed;
}
}
@ -435,19 +455,19 @@ failed:
/*
* Selection callback filter for "test". This gets called once per record.
* Selection callback filter for "test". This gets called once per record,
* twice per record for forked files.
*/
NuResult
VerifySelectionCallback(NuArchive* pArchive, void* vpProposal)
NuResult VerifySelectionCallback(NuArchive* pArchive, void* vpProposal)
{
NuError err;
const NuSelectionProposal* pProposal = vpProposal;
long count;
if (pProposal->pRecord == nil || pProposal->pThread == nil ||
pProposal->pRecord->filename == nil)
if (pProposal->pRecord == NULL || pProposal->pThread == NULL ||
pProposal->pRecord->filenameMOR == NULL)
{
fprintf(stderr, "ERROR: unexpected nil in proposal\n");
fprintf(stderr, "ERROR: unexpected NULL in proposal\n");
goto failed;
}
@ -473,8 +493,7 @@ failed:
/*
* Verify the archive contents.
*/
int
Test_Verify(NuArchive* pArchive)
int Test_Verify(NuArchive* pArchive)
{
NuError err;
long count;
@ -506,7 +525,9 @@ Test_Verify(NuArchive* pArchive)
goto failed;
}
if (count != kNumEntries) {
/* the count will be one higher than the number of records because
the last entry is forked, and each fork is tested separately */
if (count != kNumEntries + 1) {
fprintf(stderr, "ERROR: verified %ld when expecting %d\n", count,
kNumEntries);
goto failed;
@ -520,15 +541,14 @@ failed:
/*
* Extract stuff.
*/
int
Test_Extract(NuArchive* pArchive)
int Test_Extract(NuArchive* pArchive)
{
NuError err;
NuRecordIdx recordIdx;
const NuRecord* pRecord;
const NuThread* pThread;
NuDataSink* pDataSink = nil;
uchar* buf = nil;
NuDataSink* pDataSink = NULL;
uint8_t* buf = NULL;
printf("... extracting files\n");
@ -549,24 +569,24 @@ Test_Extract(NuArchive* pArchive)
}
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
recordIdx, err);
goto failed;
}
assert(pRecord != nil);
assert(pRecord != NULL);
/* we're not using ShrinkIt compat mode, so there should not be a comment */
pThread = NuGetThread(pRecord, 1);
assert(pThread != nil);
assert(pThread != NULL);
if (NuGetThreadID(pThread) != kNuThreadIDDataFork) {
fprintf(stderr, "ERROR: 'bytes' had unexpected threadID 0x%08lx\n",
fprintf(stderr, "ERROR: 'bytes' had unexpected threadID 0x%08x\n",
NuGetThreadID(pThread));
goto failed;
}
buf = malloc(pThread->actualThreadEOF);
if (buf == nil) {
fprintf(stderr, "ERROR: malloc(%ld) failed\n",pThread->actualThreadEOF);
if (buf == NULL) {
fprintf(stderr, "ERROR: malloc(%u) failed\n",pThread->actualThreadEOF);
goto failed;
}
@ -587,7 +607,7 @@ Test_Extract(NuArchive* pArchive)
goto failed;
}
NuFreeDataSink(pDataSink);
pDataSink = nil;
pDataSink = NULL;
/*
* Try to extract with "on" conversion, which should fail because the
@ -608,7 +628,7 @@ Test_Extract(NuArchive* pArchive)
goto failed;
}
NuFreeDataSink(pDataSink);
pDataSink = nil;
pDataSink = NULL;
/*
* Try to extract with "auto" conversion, which should conclude that
@ -628,12 +648,12 @@ Test_Extract(NuArchive* pArchive)
goto failed;
}
NuFreeDataSink(pDataSink);
pDataSink = nil;
pDataSink = NULL;
free(buf);
buf = nil;
buf = NULL;
@ -648,24 +668,24 @@ Test_Extract(NuArchive* pArchive)
}
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
recordIdx, err);
goto failed;
}
assert(pRecord != nil);
assert(pRecord != NULL);
/* we're not using ShrinkIt compat mode, so there should not be a comment */
pThread = NuGetThread(pRecord, 1);
assert(pThread != nil);
assert(pThread != NULL);
if (NuGetThreadID(pThread) != kNuThreadIDDataFork) {
fprintf(stderr, "ERROR: 'English' had unexpected threadID 0x%08lx\n",
fprintf(stderr, "ERROR: 'English' had unexpected threadID 0x%08x\n",
NuGetThreadID(pThread));
goto failed;
}
buf = malloc(pThread->actualThreadEOF);
if (buf == nil) {
fprintf(stderr, "ERROR: malloc(%ld) failed\n",pThread->actualThreadEOF);
if (buf == NULL) {
fprintf(stderr, "ERROR: malloc(%u) failed\n", pThread->actualThreadEOF);
goto failed;
}
@ -686,7 +706,7 @@ Test_Extract(NuArchive* pArchive)
goto failed;
}
NuFreeDataSink(pDataSink);
pDataSink = nil;
pDataSink = NULL;
/*
* Try to extract with "auto" conversion, which should fail because the
@ -707,12 +727,12 @@ Test_Extract(NuArchive* pArchive)
goto failed;
}
NuFreeDataSink(pDataSink);
pDataSink = nil;
pDataSink = NULL;
/*Free(buf);*/
/*buf = nil;*/
/*buf = NULL;*/
@ -727,17 +747,17 @@ Test_Extract(NuArchive* pArchive)
}
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
recordIdx, err);
goto failed;
}
assert(pRecord != nil);
assert(pRecord != NULL);
/* we're not using ShrinkIt compat mode, so there should not be a comment */
pThread = NuGetThread(pRecord, 1);
assert(pThread != nil);
assert(pThread != NULL);
if (NuGetThreadID(pThread) != kNuThreadIDRsrcFork) {
fprintf(stderr, "ERROR: 'Long' had unexpected threadID 0x%08lx\n",
fprintf(stderr, "ERROR: 'Long' had unexpected threadID 0x%08x\n",
NuGetThreadID(pThread));
goto failed;
}
@ -759,20 +779,20 @@ Test_Extract(NuArchive* pArchive)
goto failed;
}
NuFreeDataSink(pDataSink);
pDataSink = nil;
pDataSink = NULL;
free(buf);
buf = nil;
buf = NULL;
return 0;
failed:
if (buf != nil)
if (buf != NULL)
free(buf);
if (pDataSink != nil)
if (pDataSink != NULL)
(void) NuFreeDataSink(pDataSink);
return -1;
}
@ -780,13 +800,12 @@ failed:
/*
* Delete the first and last records. Does *not* flush the archive.
*/
int
Test_Delete(NuArchive* pArchive)
int Test_Delete(NuArchive* pArchive)
{
NuError err;
NuRecordIdx recordIdx;
const NuRecord* pRecord;
const NuThread* pThread = nil;
const NuThread* pThread = NULL;
long count;
int idx;
@ -802,33 +821,33 @@ Test_Delete(NuArchive* pArchive)
}
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
recordIdx, err);
goto failed;
}
assert(pRecord != nil);
assert(pRecord != NULL);
assert(pRecord->recTotalThreads > 0);
for (idx = 0; idx < (int)pRecord->recTotalThreads; idx++) {
pThread = NuGetThread(pRecord, idx);
assert(pThread != nil);
assert(pThread != NULL);
err = NuDeleteThread(pArchive, pThread->threadIdx);
if (err != kNuErrNone) {
fprintf(stderr,
"ERROR: couldn't delete thread #%d (%ld) (err=%d)\n",
"ERROR: couldn't delete thread #%d (%u) (err=%d)\n",
idx, recordIdx, err);
goto failed;
}
}
/* try to re-delete the same thread */
assert(pThread != nil);
assert(pThread != NULL);
FAIL_OK;
err = NuDeleteThread(pArchive, pThread->threadIdx);
FAIL_BAD;
if (err == kNuErrNone) {
fprintf(stderr, "ERROR: allowed to re-delete thread (%ld) (err=%d)\n",
fprintf(stderr, "ERROR: allowed to re-delete thread (%u) (err=%d)\n",
recordIdx, err);
goto failed;
}
@ -839,7 +858,7 @@ Test_Delete(NuArchive* pArchive)
FAIL_BAD;
if (err == kNuErrNone) {
fprintf(stderr,
"ERROR: able to delete modified record (%ld) (err=%d)\n",
"ERROR: able to delete modified record (%u) (err=%d)\n",
recordIdx, err);
goto failed;
}
@ -847,7 +866,8 @@ Test_Delete(NuArchive* pArchive)
/*
* Make sure the attr hasn't been updated yet.
*/
err = NuGetAttr(pArchive, kNuAttrNumRecords, (unsigned long*) &count);
count = 0;
err = NuGetAttr(pArchive, kNuAttrNumRecords, (uint32_t*) &count);
if (count != kNumEntries) {
fprintf(stderr, "ERROR: kNuAttrNumRecords %ld vs %d\n",
count, kNumEntries);
@ -864,19 +884,19 @@ Test_Delete(NuArchive* pArchive)
}
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't get record index %ld (err=%d)\n",
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
recordIdx, err);
goto failed;
}
assert(pRecord != nil);
assert(pRecord != NULL);
/* grab the first thread before we whack the record */
pThread = NuGetThread(pRecord, 0);
assert(pThread != nil);
assert(pThread != NULL);
err = NuDeleteRecord(pArchive, recordIdx);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to delete record #%d (%ld) (err=%d)\n",
fprintf(stderr, "ERROR: unable to delete record #%d (%u) (err=%d)\n",
kNumEntries-1, recordIdx, err);
goto failed;
}
@ -887,7 +907,7 @@ Test_Delete(NuArchive* pArchive)
FAIL_BAD;
if (err == kNuErrNone) {
fprintf(stderr,
"ERROR: allowed to delete from deleted (%ld) (err=%d)\n",
"ERROR: allowed to delete from deleted (%u) (err=%d)\n",
pThread->threadIdx, err);
goto failed;
}
@ -901,8 +921,7 @@ failed:
/*
* Verify that the count in the master header has been updated.
*/
int
Test_MasterCount(NuArchive* pArchive, long expected)
int Test_MasterCount(NuArchive* pArchive, long expected)
{
NuError err;
const NuMasterHeader* pMasterHeader;
@ -915,8 +934,8 @@ Test_MasterCount(NuArchive* pArchive, long expected)
goto failed;
}
if (pMasterHeader->mhTotalRecords != (ulong)expected) {
fprintf(stderr, "ERROR: unexpected MH count (%ld vs %ld)\n",
if (pMasterHeader->mhTotalRecords != (uint32_t)expected) {
fprintf(stderr, "ERROR: unexpected MH count (%u vs %ld)\n",
pMasterHeader->mhTotalRecords, expected);
goto failed;
}
@ -932,41 +951,21 @@ failed:
*
* Returns 0 on success, -1 on error.
*/
int
DoTests(void)
int DoTests(void)
{
NuError err;
NuArchive* pArchive = nil;
long status;
NuArchive* pArchive = NULL;
uint32_t status;
int cc, result = 0;
char answer;
/*
* Make sure we're starting with a clean slate.
*/
if (access(kTestArchive, F_OK) == 0) {
printf("Test archive '%s' exists, remove (y/n)? ", kTestArchive);
fflush(stdout);
answer = TGetReplyChar('n');
if (tolower(answer) != 'y')
goto failed;
cc = unlink(kTestArchive);
if (cc < 0) {
perror("unlink kTestArchive");
goto failed;
}
if (RemoveTestFile("Test archive", kTestArchive) < 0) {
goto failed;
}
if (access(kTestTempFile, F_OK) == 0) {
printf("Test temp file '%s' exists, remove (y/n)? ", kTestTempFile);
fflush(stdout);
answer = TGetReplyChar('n');
if (tolower(answer) != 'y')
goto failed;
cc = unlink(kTestTempFile);
if (cc < 0) {
perror("unlink kTestTempFile");
goto failed;
}
if (RemoveTestFile("Test temp file", kTestTempFile) < 0) {
goto failed;
}
/*
@ -1013,7 +1012,7 @@ DoTests(void)
fprintf(stderr, "ERROR: mid NuClose failed (err=%d)\n", err);
goto failed;
}
pArchive = nil;
pArchive = NULL;
err = NuOpenRO(kTestArchive, &pArchive);
if (err != kNuErrNone) {
@ -1028,14 +1027,14 @@ DoTests(void)
}
/*
* Make sure the contents are still what we expect.
* Make sure the TOC (i.e. list of files) is still what we expect.
*/
printf("... checking contents\n");
if (Test_Contents(pArchive) != 0)
goto failed;
/*
* Verify the archive contents.
* Verify the archive data.
*/
if (Test_Verify(pArchive) != 0)
goto failed;
@ -1055,7 +1054,7 @@ DoTests(void)
fprintf(stderr, "ERROR: late NuClose failed (err=%d)\n", err);
goto failed;
}
pArchive = nil;
pArchive = NULL;
err = NuOpenRW(kTestArchive, kTestTempFile, 0, &pArchive);
if (err != kNuErrNone) {
@ -1107,7 +1106,7 @@ DoTests(void)
*/
err = NuFlush(pArchive, &status);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: flush failed (err=%d, status=%ld)\n",
fprintf(stderr, "ERROR: flush failed (err=%d, status=%d)\n",
err, status);
goto failed;
}
@ -1122,7 +1121,7 @@ DoTests(void)
* That's all, folks...
*/
NuClose(pArchive);
pArchive = nil;
pArchive = NULL;
printf("... removing '%s'\n", kTestArchive);
cc = unlink(kTestArchive);
@ -1133,7 +1132,7 @@ DoTests(void)
leave:
if (pArchive != nil) {
if (pArchive != NULL) {
NuAbort(pArchive);
NuClose(pArchive);
}
@ -1148,16 +1147,15 @@ failed:
/*
* Crank away.
*/
int
main(void)
int main(void)
{
long major, minor, bug;
int32_t major, minor, bug;
const char* pBuildDate;
const char* pBuildFlags;
int cc;
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, &pBuildFlags);
printf("Using NuFX library v%ld.%ld.%ld, built on or after\n"
printf("Using NuFX library v%d.%d.%d, built on or after\n"
" %s with [%s]\n\n",
major, minor, bug, pBuildDate, pBuildFlags);

View File

@ -37,7 +37,7 @@
* Track an archive record.
*/
typedef struct ArchiveRecord {
char* filename;
char* filenameMOR;
NuRecordIdx recordIdx;
long numThreads;
@ -50,25 +50,24 @@ typedef struct ArchiveRecord {
/*
* Alloc a new ArchiveRecord.
*/
ArchiveRecord*
ArchiveRecord_New(const NuRecord* pRecord)
ArchiveRecord* ArchiveRecord_New(const NuRecord* pRecord)
{
ArchiveRecord* pArcRec = nil;
ArchiveRecord* pArcRec = NULL;
pArcRec = malloc(sizeof(*pArcRec));
if (pArcRec == nil)
return nil;
if (pArcRec == NULL)
return NULL;
if (pRecord->filename == nil)
pArcRec->filename = strdup("<unknown>");
if (pRecord->filenameMOR == NULL)
pArcRec->filenameMOR = strdup("<unknown>");
else
pArcRec->filename = strdup((char*)pRecord->filename);
pArcRec->filenameMOR = strdup(pRecord->filenameMOR);
pArcRec->recordIdx = pRecord->recordIdx;
pArcRec->numThreads = NuRecordGetNumThreads(pRecord);
(void) NuRecordCopyThreads(pRecord, &pArcRec->pThreads);
pArcRec->pNext = nil;
pArcRec->pNext = NULL;
return pArcRec;
}
@ -76,15 +75,14 @@ ArchiveRecord_New(const NuRecord* pRecord)
/*
* Free up an ArchiveRecord.
*/
void
ArchiveRecord_Free(ArchiveRecord* pArcRec)
void ArchiveRecord_Free(ArchiveRecord* pArcRec)
{
if (pArcRec == nil)
if (pArcRec == NULL)
return;
if (pArcRec->filename != nil)
free(pArcRec->filename);
if (pArcRec->pThreads != nil)
if (pArcRec->filenameMOR != NULL)
free(pArcRec->filenameMOR);
if (pArcRec->pThreads != NULL)
free(pArcRec->pThreads);
free(pArcRec);
}
@ -92,8 +90,8 @@ ArchiveRecord_Free(ArchiveRecord* pArcRec)
/*
* Find a thread with a matching NuThreadID.
*/
const NuThread*
ArchiveRecord_FindThreadByID(const ArchiveRecord* pArcRec, NuThreadID threadID)
const NuThread* ArchiveRecord_FindThreadByID(const ArchiveRecord* pArcRec,
NuThreadID threadID)
{
const NuThread* pThread;
int i;
@ -104,44 +102,38 @@ ArchiveRecord_FindThreadByID(const ArchiveRecord* pArcRec, NuThreadID threadID)
return pThread;
}
return nil;
return NULL;
}
const char*
ArchiveRecord_GetFilename(const ArchiveRecord* pArcRec)
const char* ArchiveRecord_GetFilename(const ArchiveRecord* pArcRec)
{
return pArcRec->filename;
return pArcRec->filenameMOR;
}
NuRecordIdx
ArchiveRecord_GetRecordIdx(const ArchiveRecord* pArcRec)
NuRecordIdx ArchiveRecord_GetRecordIdx(const ArchiveRecord* pArcRec)
{
return pArcRec->recordIdx;
}
long
ArchiveRecord_GetNumThreads(const ArchiveRecord* pArcRec)
long ArchiveRecord_GetNumThreads(const ArchiveRecord* pArcRec)
{
return pArcRec->numThreads;
}
const NuThread*
ArchiveRecord_GetThread(const ArchiveRecord* pArcRec, int idx)
const NuThread* ArchiveRecord_GetThread(const ArchiveRecord* pArcRec, int idx)
{
if (idx < 0 || idx >= pArcRec->numThreads)
return nil;
return NULL;
return NuThreadGetByIdx(pArcRec->pThreads, idx);
}
void
ArchiveRecord_SetNext(ArchiveRecord* pArcRec, ArchiveRecord* pNextRec)
void ArchiveRecord_SetNext(ArchiveRecord* pArcRec, ArchiveRecord* pNextRec)
{
pArcRec->pNext = pNextRec;
}
ArchiveRecord*
ArchiveRecord_GetNext(const ArchiveRecord* pArcRec)
ArchiveRecord* ArchiveRecord_GetNext(const ArchiveRecord* pArcRec)
{
return pArcRec->pNext;
}
@ -163,31 +155,29 @@ typedef struct ArchiveData {
} ArchiveData;
ArchiveData*
ArchiveData_New(void)
ArchiveData* ArchiveData_New(void)
{
ArchiveData* pArcData;
pArcData = malloc(sizeof(*pArcData));
if (pArcData == nil)
return nil;
if (pArcData == NULL)
return NULL;
pArcData->numRecords = 0;
pArcData->pRecordHead = pArcData->pRecordTail = nil;
pArcData->pRecordHead = pArcData->pRecordTail = NULL;
return pArcData;
}
void
ArchiveData_Free(ArchiveData* pArcData)
void ArchiveData_Free(ArchiveData* pArcData)
{
ArchiveRecord* pNext;
if (pArcData == nil)
if (pArcData == NULL)
return;
printf("*** Deleting %ld records!\n", pArcData->numRecords);
while (pArcData->pRecordHead != nil) {
while (pArcData->pRecordHead != NULL) {
pNext = ArchiveRecord_GetNext(pArcData->pRecordHead);
ArchiveRecord_Free(pArcData->pRecordHead);
pArcData->pRecordHead = pNext;
@ -197,22 +187,20 @@ ArchiveData_Free(ArchiveData* pArcData)
}
ArchiveRecord*
ArchiveData_GetRecordHead(const ArchiveData* pArcData)
ArchiveRecord* ArchiveData_GetRecordHead(const ArchiveData* pArcData)
{
return pArcData->pRecordHead;
}
/* add an ArchiveRecord to the list pointed at by ArchiveData */
void
ArchiveData_AddRecord(ArchiveData* pArcData, ArchiveRecord* pRecord)
void ArchiveData_AddRecord(ArchiveData* pArcData, ArchiveRecord* pRecord)
{
assert(pRecord != nil);
assert((pArcData->pRecordHead == nil && pArcData->pRecordTail == nil) ||
(pArcData->pRecordHead != nil && pArcData->pRecordTail != nil));
assert(pRecord != NULL);
assert((pArcData->pRecordHead == NULL && pArcData->pRecordTail == NULL) ||
(pArcData->pRecordHead != NULL && pArcData->pRecordTail != NULL));
if (pArcData->pRecordHead == nil) {
if (pArcData->pRecordHead == NULL) {
/* first */
pArcData->pRecordHead = pArcData->pRecordTail = pRecord;
} else {
@ -225,24 +213,23 @@ ArchiveData_AddRecord(ArchiveData* pArcData, ArchiveRecord* pRecord)
}
/* dump the contents of the ArchiveData to stdout */
void
ArchiveData_DumpContents(const ArchiveData* pArcData)
void ArchiveData_DumpContents(const ArchiveData* pArcData)
{
ArchiveRecord* pArcRec;
pArcRec = pArcData->pRecordHead;
while (pArcRec != nil) {
while (pArcRec != NULL) {
const NuThread* pThread;
int i, count;
printf("%5ld '%s'\n",
printf("%5u '%s'\n",
ArchiveRecord_GetRecordIdx(pArcRec),
ArchiveRecord_GetFilename(pArcRec));
count = ArchiveRecord_GetNumThreads(pArcRec);
for (i = 0; i < count; i++) {
pThread = ArchiveRecord_GetThread(pArcRec, i);
printf(" %5ld 0x%04x 0x%04x\n", pThread->threadIdx,
printf(" %5u 0x%04x 0x%04x\n", pThread->threadIdx,
pThread->thThreadClass, pThread->thThreadKind);
}
@ -260,18 +247,18 @@ ArchiveData_DumpContents(const ArchiveData* pArcData)
/*
* Callback function to collect archive information.
*/
NuResult
GatherContents(NuArchive* pArchive, void* vpRecord)
NuResult GatherContents(NuArchive* pArchive, void* vpRecord)
{
NuRecord* pRecord = (NuRecord*) vpRecord;
ArchiveData* pArchiveData = nil;
ArchiveData* pArchiveData = NULL;
ArchiveRecord* pArchiveRecord = ArchiveRecord_New(pRecord);
NuGetExtraData(pArchive, (void**)&pArchiveData);
assert(pArchiveData != nil);
assert(pArchiveData != NULL);
printf("*** Filename = '%s'\n",
pRecord->filename == nil ? "<unknown>":(const char*)pRecord->filename);
pRecord->filenameMOR == NULL ?
"<unknown>" : pRecord->filenameMOR);
ArchiveData_AddRecord(pArchiveData, pArchiveRecord);
@ -282,8 +269,7 @@ GatherContents(NuArchive* pArchive, void* vpRecord)
/*
* Copy the filename thread from every record to "pDataSink".
*/
NuError
ReadAllFilenameThreads(NuArchive* pArchive, ArchiveData* pArchiveData,
NuError ReadAllFilenameThreads(NuArchive* pArchive, ArchiveData* pArchiveData,
NuDataSink* pDataSink)
{
NuError err = kNuErrNone;
@ -291,10 +277,10 @@ ReadAllFilenameThreads(NuArchive* pArchive, ArchiveData* pArchiveData,
const NuThread* pThread;
pArchiveRecord = ArchiveData_GetRecordHead(pArchiveData);
while (pArchiveRecord != nil) {
while (pArchiveRecord != NULL) {
pThread = ArchiveRecord_FindThreadByID(pArchiveRecord,
kNuThreadIDFilename);
if (pThread != nil) {
if (pThread != NULL) {
err = NuExtractThread(pArchive, pThread->threadIdx, pDataSink);
if (err != kNuErrNone) {
fprintf(stderr, "*** Extract failed (%d)\n", err);
@ -310,11 +296,10 @@ bail:
/* extract every filename thread into a single file, overwriting each time */
NuError
ExtractToFile(NuArchive* pArchive, ArchiveData* pArchiveData)
NuError ExtractToFile(NuArchive* pArchive, ArchiveData* pArchiveData)
{
NuError err;
NuDataSink* pDataSink = nil;
NuDataSink* pDataSink = NULL;
err = NuCreateDataSinkForFile(true, kNuConvertOff, "out.file", PATH_SEP,
&pDataSink);
@ -337,14 +322,13 @@ bail:
}
/* extract every filename thread into a FILE*, appending */
NuError
ExtractToFP(NuArchive* pArchive, ArchiveData* pArchiveData)
NuError ExtractToFP(NuArchive* pArchive, ArchiveData* pArchiveData)
{
NuError err;
FILE* fp = nil;
NuDataSink* pDataSink = nil;
FILE* fp = NULL;
NuDataSink* pDataSink = NULL;
if ((fp = fopen("out.fp", kNuFileOpenWriteTrunc)) == nil)
if ((fp = fopen("out.fp", kNuFileOpenWriteTrunc)) == NULL)
return kNuErrFileOpen;
err = NuCreateDataSinkForFP(true, kNuConvertOff, fp, &pDataSink);
@ -357,7 +341,7 @@ ExtractToFP(NuArchive* pArchive, ArchiveData* pArchiveData)
bail:
(void) NuFreeDataSink(pDataSink);
if (fp != nil)
if (fp != NULL)
fclose(fp);
if (err == kNuErrNone)
printf("*** FP write complete\n");
@ -365,13 +349,12 @@ bail:
}
/* extract every filename thread into a buffer, advancing as we go */
NuError
ExtractToBuffer(NuArchive* pArchive, ArchiveData* pArchiveData)
NuError ExtractToBuffer(NuArchive* pArchive, ArchiveData* pArchiveData)
{
NuError err;
unsigned char buffer[kHappySize];
NuDataSink* pDataSink = nil;
unsigned long count;
uint8_t buffer[kHappySize];
NuDataSink* pDataSink = NULL;
uint32_t count;
err = NuCreateDataSinkForBuffer(true, kNuConvertOff, buffer, kHappySize,
&pDataSink);
@ -389,9 +372,9 @@ ExtractToBuffer(NuArchive* pArchive, ArchiveData* pArchiveData)
(void) NuDataSinkGetOutCount(pDataSink, &count);
if (count > 0) {
FILE* fp;
if ((fp = fopen("out.buf", kNuFileOpenWriteTrunc)) != nil) {
if ((fp = fopen("out.buf", kNuFileOpenWriteTrunc)) != NULL) {
printf("*** Writing %ld bytes\n", count);
printf("*** Writing %u bytes\n", count);
if (fwrite(buffer, count, 1, fp) != 1)
err = kNuErrFileWrite;
fclose(fp);
@ -409,14 +392,13 @@ bail:
/*
* Do file stuff.
*/
int
DoFileStuff(const char* filename)
int DoFileStuff(const UNICHAR* filenameUNI)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
ArchiveData* pArchiveData = ArchiveData_New();
err = NuOpenRO(filename, &pArchive);
err = NuOpenRO(filenameUNI, &pArchive);
if (err != kNuErrNone)
goto bail;
@ -444,7 +426,7 @@ bail:
if (err != kNuErrNone)
fprintf(stderr, "*** ERROR: got error %d\n", err);
if (pArchive != nil) {
if (pArchive != NULL) {
NuError err2 = NuClose(pArchive);
if (err == kNuErrNone && err2 != kNuErrNone)
err = err2;
@ -459,21 +441,20 @@ bail:
/*
* Grab the name of an archive to read. If no name was provided, use stdin.
*/
int
main(int argc, char** argv)
int main(int argc, char** argv)
{
long major, minor, bug;
int32_t major, minor, bug;
const char* pBuildDate;
FILE* infp = nil;
FILE* infp = NULL;
int cc;
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, nil);
printf("Using NuFX lib %ld.%ld.%ld built on or after %s\n",
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, NULL);
printf("Using NuFX lib %d.%d.%d built on or after %s\n",
major, minor, bug, pBuildDate);
if (argc == 2) {
infp = fopen(argv[1], kNuFileOpenReadOnly);
if (infp == nil) {
if (infp == NULL) {
perror("fopen failed");
exit(1);
}
@ -484,7 +465,7 @@ main(int argc, char** argv)
cc = DoFileStuff(argv[1]);
if (infp != nil)
if (infp != NULL)
fclose(infp);
exit(cc != 0);

580
nufxlib/samples/TestNames.c Normal file
View File

@ -0,0 +1,580 @@
/*
* NuFX archive manipulation library
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.LIB.
*
* Test local and storage names with Unicode and Mac OS Roman content.
*
* On Windows, opening files with fancy filenames requires UTF-16 and
* special functions. On Linux and Mac OS X we're just writing UTF-8 data,
* so they don't really need to do anything special other than be 8-bit
* clean. NufxLib functions take UTF-8 strings, so on Windows we define
* everything in UTF-16 and convert to UTF-8. (We need the UTF-16 form so
* we can use "wide" I/O functions to confirm that the file was created
* with the correct name.)
*
* To see files with the correct appearance with "ls", you may need to
* do something like:
*
* % LC_ALL=en_US.UTF-8 ls
*
* (Many users set LC_ALL=POSIX to avoid GNU grep slowdowns and altered
* sort ordering in ls.)
*/
#include <stdio.h>
#include <ctype.h>
#include "NufxLib.h"
#include "Common.h"
/*
* Test filenames.
*
* The local filename (kTestArchive) contains non-MOR Unicode values
* (two Japanese characters that Google Translate claims form the verb
* "shrink"). The temp file name is similar.
*
* The entry name uses a mix of simple ASCII, CP1252 MOR, and
* non-CP1252 MOR characters: fl ligature, double dagger, copyright symbol,
* Apple logo (the latter of which doesn't have a glyph on Windows or Linux).
* All of the characters have MOR translations.
*/
#ifdef USE_UTF16
const UNICHAR kTestArchive[] = L"nlTest\u7e2e\u3080.shk";
const UNICHAR kTestEntryName[] = L"nl-test\u2013\ufb01_\u2021_\u00a9\uf8ff!";
const UNICHAR kTestTempFile[] = L"nlTest\4e00\u6642\u30d5\u30a1\u30a4\u30eb.tmp";
#else
const UNICHAR kTestArchive[] = "nlTest\xe7\xb8\xae\xe3\x82\x80.shk";
const UNICHAR kTestEntryName[] = "nl-test\xe2\x80\x93\xef\xac\x81_\xe2\x80\xa1_"
"\xc2\xa9\xef\xa3\xbf!";
const UNICHAR kTestTempFile[] = "nlTest\xe4\xb8\x80\xe6\x99\x82\xe3\x83\x95"
"\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab.tmp";
#endif
const UNICHAR kLocalFssep = '|';
/*
* ===========================================================================
* Helper functions
* ===========================================================================
*/
/*
* Get a single character of input from the user.
*/
static char TGetReplyChar(char defaultReply)
{
char tmpBuf[32];
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == NULL)
return defaultReply;
if (tmpBuf[0] == '\n' || tmpBuf[0] == '\r')
return defaultReply;
return tmpBuf[0];
}
NuError AddSimpleRecord(NuArchive* pArchive, const char* fileNameMOR,
NuRecordIdx* pRecordIdx)
{
NuFileDetails fileDetails;
memset(&fileDetails, 0, sizeof(fileDetails));
fileDetails.storageNameMOR = fileNameMOR;
fileDetails.fileSysInfo = kLocalFssep;
fileDetails.access = kNuAccessUnlocked;
return NuAddRecord(pArchive, &fileDetails, pRecordIdx);
}
/*
* Display error messages... or not.
*/
NuResult ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
{
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
//if (gSuppressError)
// return kNuOK;
if (pErrorMessage->isDebug) {
fprintf(stderr, "%sNufxLib says: [%s:%d %s] %s\n",
pArchive == NULL ? "GLOBAL>" : "",
pErrorMessage->file, pErrorMessage->line, pErrorMessage->function,
pErrorMessage->message);
} else {
fprintf(stderr, "%sNufxLib says: %s\n",
pArchive == NULL ? "GLOBAL>" : "",
pErrorMessage->message);
}
return kNuOK;
}
#ifdef USE_UTF16
TODO - use _waccess, _wunlink, etc.
#else
int RemoveTestFile(const char* title, const char* fileName)
{
char answer;
if (access(fileName, F_OK) == 0) {
printf("%s '%s' exists, remove (y/n)? ", title, fileName);
fflush(stdout);
answer = TGetReplyChar('n');
if (tolower(answer) != 'y')
return -1;
if (unlink(fileName) < 0) {
perror("unlink");
return -1;
}
}
return 0;
}
#endif
/*
* Utility function that wraps NuConvertUNIToMOR, allocating a new
* buffer to hold the converted string. The caller must free the result.
*/
char* CopyUNIToMOR(const UNICHAR* stringUNI)
{
size_t morLen;
char* morBuf;
morLen = NuConvertUNIToMOR(stringUNI, NULL, 0);
if (morLen == (size_t) -1) {
return NULL;
}
morBuf = (char*) malloc(morLen);
(void) NuConvertUNIToMOR(stringUNI, morBuf, morLen);
return morBuf;
}
/*
* Utility function that wraps NuConvertMORToUNI, allocating a new
* buffer to hold the converted string. The caller must free the result.
*/
UNICHAR* CopyMORToUNI(const char* stringMOR)
{
size_t uniLen;
char* uniBuf;
uniLen = NuConvertMORToUNI(stringMOR, NULL, 0);
if (uniLen == (size_t) -1) {
return NULL;
}
uniBuf = (UNICHAR*) malloc(uniLen);
(void) NuConvertMORToUNI(stringMOR, uniBuf, uniLen);
return uniBuf;
}
/*
* ===========================================================================
* Tests
* ===========================================================================
*/
void DumpMorString(const char* str)
{
printf("(%d) ", (int) strlen(str));
while (*str != '\0') {
if (*str >= 0x20 && *str < 0x7f) {
putchar(*str);
} else {
printf("\\x%02x", (uint8_t) *str);
}
str++;
}
putchar('\n');
}
void DumpUnicharString(const UNICHAR* str)
{
printf("(%d) ", (int) strlen(str));
while (*str != '\0') {
if (*str >= 0x20 && *str < 0x7f) {
putchar(*str);
} else {
if (sizeof(UNICHAR) == 1) {
printf("\\x%02x", (uint8_t) *str);
} else {
printf("\\u%04x", (uint16_t) *str);
}
}
str++;
}
putchar('\n');
}
/*
* Some basic string conversion unit tests.
*
* TODO: test with short buffer, make sure we don't get partial code
* points when converting to Unicode
*/
int TestStringConversion(void)
{
static const char kMORTest[] = "test\xe0\xe9\xed\xf3\xfa#\xf0\xb0";
size_t outLen;
char morBuf[512];
UNICHAR uniBuf[512];
// convert test string to Unicode
memset(uniBuf, 0xcc, sizeof(uniBuf));
//printf("MOR: "); DumpMorString(kMORTest);
outLen = NuConvertMORToUNI(kMORTest, NULL, 0);
//printf("outLen is %u\n", (unsigned int) outLen);
if (NuConvertMORToUNI(kMORTest, uniBuf, sizeof(uniBuf)) != outLen) {
fprintf(stderr, "Inconsistent MORToUNI len\n");
return -1;
}
//printf("UNI: "); DumpUnicharString(uniBuf);
if (strlen(uniBuf) + 1 != outLen) {
fprintf(stderr, "Expected length != actual length\n");
return -1;
}
// convert Unicode back to MOR
memset(morBuf, 0xcc, sizeof(morBuf));
outLen = NuConvertUNIToMOR(uniBuf, NULL, 0);
//printf("outLen is %u\n", (unsigned int) outLen);
if (NuConvertUNIToMOR(uniBuf, morBuf, sizeof(morBuf)) != outLen) {
fprintf(stderr, "Inconsistent UNIToMOR len\n");
return -1;
}
//printf("MOR: "); DumpMorString(morBuf);
if (strlen(morBuf) + 1 != outLen) {
fprintf(stderr, "Expected length != actual length\n");
return -1;
}
// check vs. original
if (strcmp(kMORTest, morBuf) != 0) {
fprintf(stderr, "Test string corrupted by double conversion\n");
return -1;
}
#ifdef USE_UTF16
static const UNICHAR kNonMorUniStr[] = L"nlTest\u7e2e\u3080.shk";
static const UNICHAR kBadUniStr[] = L"nlTest\u7e2e\x30";
#else
static const UNICHAR kNonMorUniStr[] = "nlTest\xe7\xb8\xae\xe3\x82\x80.shk";
static const UNICHAR kBadUniStr[] = "nlTest\x81\xe7";
#endif
static const char kNonMorExpected[] = "nlTest??.shk";
static const char kBadExpected[] = "nlTest??";
NuConvertUNIToMOR(kNonMorUniStr, morBuf, sizeof(morBuf));
if (strcmp(morBuf, kNonMorExpected) != 0) {
fprintf(stderr, "Non-MOR string conversion failed\n");
return -1;
}
NuConvertUNIToMOR(kBadUniStr, morBuf, sizeof(morBuf));
if (strcmp(morBuf, kBadExpected) != 0) {
fprintf(stderr, "Bad UNI string conversion failed\n");
return -1;
}
printf("... string conversion tests successful\n");
return 0;
}
/*
* Create a new entry and give it a trivial data fork.
*/
int AddTestEntry(NuArchive* pArchive, const char* entryNameMOR)
{
NuDataSource* pDataSource = NULL;
NuRecordIdx recordIdx;
static const char* kTestMsg = "Hello, world!\n";
uint32_t status;
NuError err;
/*
* Add our test entry.
*/
err = AddSimpleRecord(pArchive, entryNameMOR, &recordIdx);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: add record failed (err=%d)\n", err);
goto failed;
}
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
0, (const uint8_t*)kTestMsg, 0, strlen(kTestMsg), NULL,
&pDataSource);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: source create failed (err=%d)\n", err);
goto failed;
}
err = NuAddThread(pArchive, recordIdx, kNuThreadIDDataFork, pDataSource,
NULL);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: thread add failed (err=%d)\n", err);
goto failed;
}
pDataSource = NULL; /* now owned by library */
/*
* Flush changes.
*/
err = NuFlush(pArchive, &status);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't flush after add (err=%d, status=%u)\n",
err, status);
goto failed;
}
return 0;
failed:
if (pDataSource != NULL)
NuFreeDataSource(pDataSource);
return -1;
}
/*
* Extract the file we created.
*/
int TestExtract(NuArchive* pArchive, const char* entryNameMOR)
{
const NuRecord* pRecord;
NuRecordIdx recordIdx;
NuError err;
err = NuGetRecordIdxByName(pArchive, entryNameMOR, &recordIdx);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't find '%s' (err=%d)\n",
entryNameMOR, err);
return -1;
}
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: couldn't get record index %u (err=%d)\n",
recordIdx, err);
return -1;
}
assert(pRecord != NULL);
const NuThread* pThread = NULL;
uint32_t idx;
for (idx = 0; idx < NuRecordGetNumThreads(pRecord); idx++) {
pThread = NuGetThread(pRecord, idx);
if (NuGetThreadID(pThread) == kNuThreadIDDataFork)
break;
}
if (pThread == NULL) {
fprintf(stderr, "ERROR: no data thread?\n");
return -1;
}
/*
* Prepare the output file.
*/
UNICHAR* entryNameUNI = CopyMORToUNI(entryNameMOR);
NuDataSink* pDataSink = NULL;
err = NuCreateDataSinkForFile(true, kNuConvertOff, entryNameUNI,
kLocalFssep, &pDataSink);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to create data sink for file (err=%d)\n",
err);
free(entryNameUNI);
return -1;
}
err = NuExtractThread(pArchive, pThread->threadIdx, pDataSink);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: extract failed (err=%d)\n", err);
(void) NuFreeDataSink(pDataSink);
free(entryNameUNI);
return -1;
}
(void) NuFreeDataSink(pDataSink);
printf("... confirming extraction of '%s'\n", entryNameUNI);
if (access(entryNameUNI, F_OK) != 0) {
fprintf(stderr, "ERROR: unable to read '%s' (err=%d)\n",
entryNameUNI, errno);
free(entryNameUNI);
return -1;
}
if (unlink(entryNameUNI) < 0) {
perror("unlink test entry");
free(entryNameUNI);
return -1;
}
free(entryNameUNI);
return 0;
}
/*
* Run some tests.
*
* Returns 0 on success, -1 on error.
*/
int DoTests(void)
{
NuError err;
NuArchive* pArchive = NULL;
char* testEntryNameMOR = NULL;
int result = 0;
if (TestStringConversion() < 0) {
goto failed;
}
/*
* Make sure we're starting with a clean slate.
*/
if (RemoveTestFile("Test archive", kTestArchive) < 0) {
goto failed;
}
if (RemoveTestFile("Test temp file", kTestTempFile) < 0) {
goto failed;
}
if (RemoveTestFile("Test entry", kTestEntryName) < 0) {
goto failed;
}
testEntryNameMOR = CopyUNIToMOR(kTestEntryName);
/*
* Create a new archive to play with.
*/
err = NuOpenRW(kTestArchive, kTestTempFile, kNuOpenCreat|kNuOpenExcl,
&pArchive);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: NuOpenRW failed (err=%d)\n", err);
goto failed;
}
if (NuSetErrorMessageHandler(pArchive, ErrorMessageHandler) ==
kNuInvalidCallback)
{
fprintf(stderr, "ERROR: couldn't set message handler\n");
goto failed;
}
/*
* Add a single entry.
*/
if (AddTestEntry(pArchive, testEntryNameMOR) != 0) {
goto failed;
}
printf("... checking presence of '%s' and '%s'\n",
kTestArchive, kTestTempFile);
if (access(kTestTempFile, F_OK) != 0) {
/* in theory, NufxLib doesn't need to use the temp file we provide,
so this test isn't entirely sound */
fprintf(stderr, "ERROR: did not find %s (err=%d)\n",
kTestTempFile, err);
goto failed;
}
/*
* Close it and confirm that the file has the expected name.
*/
err = NuClose(pArchive);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: mid NuClose failed (err=%d)\n", err);
goto failed;
}
pArchive = NULL;
if (access(kTestArchive, F_OK) != 0) {
fprintf(stderr, "ERROR: did not find %s (err=%d)\n", kTestArchive, err);
goto failed;
}
/*
* Reopen it read-only.
*/
printf("... reopening archive read-only\n");
err = NuOpenRO(kTestArchive, &pArchive);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: NuOpenRO failed (err=%d)\n", err);
goto failed;
}
if (NuSetErrorMessageHandler(pArchive, ErrorMessageHandler) ==
kNuInvalidCallback)
{
fprintf(stderr, "ERROR: couldn't set message handler\n");
goto failed;
}
/*
* Extract the file.
*/
if (TestExtract(pArchive, testEntryNameMOR) < 0) {
goto failed;
}
/*
* That's all, folks...
*/
NuClose(pArchive);
pArchive = NULL;
printf("... removing '%s'\n", kTestArchive);
if (unlink(kTestArchive) < 0) {
perror("unlink kTestArchive");
goto failed;
}
leave:
if (pArchive != NULL) {
NuAbort(pArchive);
NuClose(pArchive);
}
free(testEntryNameMOR);
return result;
failed:
result = -1;
goto leave;
}
/*
* Start here.
*/
int main(void)
{
int32_t major, minor, bug;
const char* pBuildDate;
const char* pBuildFlags;
int cc;
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, &pBuildFlags);
printf("Using NuFX library v%d.%d.%d, built on or after\n"
" %s with [%s]\n\n",
major, minor, bug, pBuildDate, pBuildFlags);
if (NuSetGlobalErrorMessageHandler(ErrorMessageHandler) ==
kNuInvalidCallback)
{
fprintf(stderr, "ERROR: can't set the global message handler");
exit(1);
}
printf("... starting tests\n");
cc = DoTests();
printf("... tests ended, %s\n", cc == 0 ? "SUCCESS" : "FAILURE");
exit(cc != 0);
}

View File

@ -21,12 +21,20 @@
* header, a filename thread, or a default value ("UNKNOWN", stuffed in
* when a record has no filename at all).
*/
NuResult
ShowContents(NuArchive* pArchive, void* vpRecord)
NuResult ShowContents(NuArchive* pArchive, void* vpRecord)
{
const NuRecord* pRecord = (NuRecord*) vpRecord;
printf("*** Filename = '%s'\n", pRecord->filename);
size_t bufLen = NuConvertMORToUNI(pRecord->filenameMOR, NULL, 0);
if (bufLen == (size_t) -1) {
fprintf(stderr, "GLITCH: unable to convert '%s'\n",
pRecord->filenameMOR);
} else {
UNICHAR* buf = (UNICHAR*) malloc(bufLen);
NuConvertMORToUNI(pRecord->filenameMOR, buf, bufLen);
printf("*** Filename = '%s'\n", buf);
free(buf);
}
return kNuOK;
}
@ -38,11 +46,10 @@ ShowContents(NuArchive* pArchive, void* vpRecord)
* If we're not interested in handling an archive on stdin, we could just
* pass the filename in here and use NuOpenRO instead.
*/
int
DoStreamStuff(FILE* fp)
int DoStreamStuff(FILE* fp)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
err = NuStreamOpenRO(fp, &pArchive);
if (err != kNuErrNone) {
@ -59,7 +66,7 @@ DoStreamStuff(FILE* fp)
}
bail:
if (pArchive != nil) {
if (pArchive != NULL) {
NuError err2 = NuClose(pArchive);
if (err == kNuErrNone)
err = err2;
@ -72,16 +79,15 @@ bail:
/*
* Grab the name of an archive to read. If "-" was given, use stdin.
*/
int
main(int argc, char** argv)
int main(int argc, char** argv)
{
long major, minor, bug;
int32_t major, minor, bug;
const char* pBuildDate;
FILE* infp = nil;
FILE* infp = NULL;
int cc;
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, nil);
printf("Using NuFX lib %ld.%ld.%ld built on or after %s\n",
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, NULL);
printf("Using NuFX lib %d.%d.%d built on or after %s\n",
major, minor, bug, pBuildDate);
if (argc != 2) {
@ -93,7 +99,7 @@ main(int argc, char** argv)
infp = stdin;
else {
infp = fopen(argv[1], kNuFileOpenReadOnly);
if (infp == nil) {
if (infp == NULL) {
fprintf(stderr, "ERROR: unable to open '%s'\n", argv[1]);
exit(1);
}

View File

@ -29,16 +29,15 @@ const int kMaxHeldLen = 1024 * 1024;
* A list of CRCs.
*/
typedef struct CRCList {
int numEntries;
unsigned short* entries;
int numEntries;
uint16_t* entries;
} CRCList;
/*
* Returns true if the compression type is supported, false otherwise.
*/
int
CompressionSupported(NuValue compression)
int CompressionSupported(NuValue compression)
{
int result;
@ -76,8 +75,7 @@ CompressionSupported(NuValue compression)
/*
* This gets called when a buffer DataSource is no longer needed.
*/
NuResult
FreeCallback(NuArchive* pArchive, void* args)
NuResult FreeCallback(NuArchive* pArchive, void* args)
{
free(args);
return kNuOK;
@ -87,8 +85,7 @@ FreeCallback(NuArchive* pArchive, void* args)
/*
* Dump a CRC list.
*/
void
DumpCRCs(const CRCList* pCRCList)
void DumpCRCs(const CRCList* pCRCList)
{
int i;
@ -101,10 +98,9 @@ DumpCRCs(const CRCList* pCRCList)
/*
* Free a CRC list.
*/
void
FreeCRCs(CRCList* pCRCList)
void FreeCRCs(CRCList* pCRCList)
{
if (pCRCList == nil)
if (pCRCList == NULL)
return;
free(pCRCList->entries);
@ -117,21 +113,20 @@ FreeCRCs(CRCList* pCRCList)
* We assume there are at most two data threads (e.g. data fork and rsrc
* fork) in a record.
*
* Returns the list on success, nil on failure.
* Returns the list on success, NULL on failure.
*/
CRCList*
GatherCRCs(NuArchive* pArchive)
CRCList* GatherCRCs(NuArchive* pArchive)
{
NuError err = kNuErrNone;
const NuMasterHeader* pMasterHeader;
CRCList* pCRCList = nil;
unsigned short* pEntries = nil;
CRCList* pCRCList = NULL;
uint16_t* pEntries = NULL;
long recCount, maxCRCs;
long recIdx, crcIdx;
int i;
pCRCList = malloc(sizeof(*pCRCList));
if (pCRCList == nil) {
if (pCRCList == NULL) {
fprintf(stderr, "ERROR: couldn't alloc CRC list\n");
err = kNuErrGeneric;
goto bail;
@ -148,7 +143,7 @@ GatherCRCs(NuArchive* pArchive)
maxCRCs = recCount * 2;
pEntries = malloc(sizeof(*pEntries) * maxCRCs);
if (pEntries == nil) {
if (pEntries == NULL) {
fprintf(stderr, "ERROR: unable to alloc CRC list (%ld entries)\n",
maxCRCs);
err = kNuErrGeneric;
@ -178,17 +173,18 @@ GatherCRCs(NuArchive* pArchive)
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to get recordIdx %ld\n", recordIdx);
fprintf(stderr, "ERROR: unable to get recordIdx %u\n", recordIdx);
goto bail;
}
if (NuRecordGetNumThreads(pRecord) == 0) {
fprintf(stderr, "ERROR: not expecting empty record (%ld)!\n",
fprintf(stderr, "ERROR: not expecting empty record (%u)!\n",
recordIdx);
err = kNuErrGeneric;
goto bail;
}
int rsrcCrcIdx = -1;
for (i = 0; i < (int)NuRecordGetNumThreads(pRecord); i++) {
pThread = NuGetThread(pRecord, i);
if (pThread->thThreadClass == kNuThreadClassData) {
@ -199,7 +195,30 @@ GatherCRCs(NuArchive* pArchive)
goto bail;
}
pEntries[crcIdx++] = pThread->thThreadCRC;
/*
* Ensure that the data fork CRC comes first. Otherwise
* we can fail if it gets rearranged. This is only a
* problem for GSHK-created archives that don't have
* threads for every fork, so "mask dataless" is create
* fake entries.
*
* The correct way to do this is to store a tuple
* { thread-kind, crc }, but that's more work.
*/
if (pThread->thThreadKind == kNuThreadKindRsrcFork) {
rsrcCrcIdx = crcIdx;
}
if (pThread->thThreadKind == kNuThreadKindDataFork &&
rsrcCrcIdx != -1)
{
/* this is the data fork, we've already seen the
resource fork; swap entries */
pEntries[crcIdx++] = pEntries[rsrcCrcIdx];
pEntries[rsrcCrcIdx] = pThread->thThreadCRC;
} else {
pEntries[crcIdx++] = pThread->thThreadCRC;
}
}
}
}
@ -211,7 +230,7 @@ GatherCRCs(NuArchive* pArchive)
bail:
if (err != kNuErrNone) {
FreeCRCs(pCRCList);
pCRCList = nil;
pCRCList = NULL;
}
return pCRCList;
}
@ -228,16 +247,15 @@ bail:
*
* Returns 0 on success, nonzero on failure.
*/
int
CompareCRCs(NuArchive* pArchive, const CRCList* pOldCRCList)
int CompareCRCs(NuArchive* pArchive, const CRCList* pOldCRCList)
{
CRCList* pNewCRCList = nil;
CRCList* pNewCRCList = NULL;
int result = -1;
int badCrc = 0;
int i;
pNewCRCList = GatherCRCs(pArchive);
if (pNewCRCList == nil) {
if (pNewCRCList == NULL) {
fprintf(stderr, "ERROR: unable to gather new list\n");
goto bail;
}
@ -274,18 +292,17 @@ bail:
*
* All of this good stuff gets queued up until the next NuFlush call.
*/
NuError
RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
NuError RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
const NuThread* pThread)
{
NuError err = kNuErrNone;
NuDataSource* pDataSource = nil;
NuDataSink* pDataSink = nil;
unsigned char* buf = nil;
NuDataSource* pDataSource = NULL;
NuDataSink* pDataSink = NULL;
uint8_t* buf = NULL;
if (pThread->actualThreadEOF == 0) {
buf = malloc(1);
if (buf == nil) {
if (buf == NULL) {
fprintf(stderr, "ERROR: failed allocating trivial buffer\n");
err = kNuErrGeneric;
goto bail;
@ -295,8 +312,8 @@ RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
* Create a buffer and data sink to hold the data.
*/
buf = malloc(pThread->actualThreadEOF);
if (buf == nil) {
fprintf(stderr, "ERROR: failed allocating %ld bytes\n",
if (buf == NULL) {
fprintf(stderr, "ERROR: failed allocating %u bytes\n",
pThread->actualThreadEOF);
err = kNuErrGeneric;
goto bail;
@ -314,8 +331,8 @@ RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
*/
err = NuExtractThread(pArchive, pThread->threadIdx, pDataSink);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: failed extracting thread %ld in '%s': %s\n",
pThread->threadIdx, pRecord->filename, NuStrError(err));
fprintf(stderr, "ERROR: failed extracting thread %u in '%s': %s\n",
pThread->threadIdx, pRecord->filenameMOR, NuStrError(err));
goto bail;
}
}
@ -325,7 +342,7 @@ RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
*/
err = NuDeleteThread(pArchive, pThread->threadIdx);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to delete thread %ld\n",
fprintf(stderr, "ERROR: unable to delete thread %u\n",
pThread->threadIdx);
goto bail;
}
@ -340,19 +357,19 @@ RecompressThread(NuArchive* pArchive, const NuRecord* pRecord,
fprintf(stderr, "ERROR: unable to create data source (err=%d)\n", err);
goto bail;
}
buf = nil;
buf = NULL;
/*
* Create replacement thread.
*/
err = NuAddThread(pArchive, pRecord->recordIdx, NuGetThreadID(pThread),
pDataSource, nil);
pDataSource, NULL);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to add new thread ID=0x%08lx (err=%d)\n",
fprintf(stderr, "ERROR: unable to add new thread ID=0x%08x (err=%d)\n",
NuGetThreadID(pThread), err);
goto bail;
}
pDataSource = nil; /* now owned by NufxLib */
pDataSource = NULL; /* now owned by NufxLib */
bail:
NuFreeDataSink(pDataSink);
@ -367,21 +384,20 @@ bail:
* The amount of data we're holding in memory as a result of the
* recompression is placed in "*pLen".
*/
NuError
RecompressRecord(NuArchive* pArchive, NuRecordIdx recordIdx, long* pLen)
NuError RecompressRecord(NuArchive* pArchive, NuRecordIdx recordIdx, long* pLen)
{
NuError err = kNuErrNone;
const NuRecord* pRecord;
const NuThread* pThread;
int i;
printf(" Recompressing %ld\n", recordIdx);
printf(" Recompressing %u\n", recordIdx);
*pLen = 0;
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to get record %ld (err=%d)\n",
fprintf(stderr, "ERROR: unable to get record %u (err=%d)\n",
recordIdx, err);
goto bail;
}
@ -393,8 +409,8 @@ RecompressRecord(NuArchive* pArchive, NuRecordIdx recordIdx, long* pLen)
NuGetThreadID(pThread));*/
err = RecompressThread(pArchive, pRecord, pThread);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: failed recompressing thread %ld "
" in record %ld (err=%d)\n",
fprintf(stderr, "ERROR: failed recompressing thread %u "
" in record %u (err=%d)\n",
pThread->threadIdx, pRecord->recordIdx, err);
goto bail;
}
@ -412,23 +428,22 @@ bail:
/*
* Recompress every data thread in the archive.
*/
NuError
RecompressArchive(NuArchive* pArchive, NuValue compression)
NuError RecompressArchive(NuArchive* pArchive, NuValue compression)
{
NuError err = kNuErrNone;
NuRecordIdx* pIndices = nil;
NuRecordIdx* pIndices = NULL;
NuAttr countAttr;
long heldLen;
long idx;
err = NuSetValue(pArchive, kNuValueDataCompression, compression);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to set compression to %ld (err=%d)\n",
fprintf(stderr, "ERROR: unable to set compression to %u (err=%d)\n",
compression, err);
goto bail;
}
printf("Recompressing threads with compression type %ld\n", compression);
printf("Recompressing threads with compression type %u\n", compression);
err = NuGetAttr(pArchive, kNuAttrNumRecords, &countAttr);
if (err != kNuErrNone) {
@ -446,8 +461,8 @@ RecompressArchive(NuArchive* pArchive, NuValue compression)
* record to "disappear" during processing, we will know about it.
*/
pIndices = malloc(countAttr * sizeof(*pIndices));
if (pIndices == nil) {
fprintf(stderr, "ERROR: malloc on %ld indices failed\n", countAttr);
if (pIndices == NULL) {
fprintf(stderr, "ERROR: malloc on %u indices failed\n", countAttr);
err = kNuErrGeneric;
goto bail;
}
@ -470,7 +485,7 @@ RecompressArchive(NuArchive* pArchive, NuValue compression)
err = RecompressRecord(pArchive, pIndices[idx], &recHeldLen);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: failed recompressing record %ld (err=%d)\n",
fprintf(stderr, "ERROR: failed recompressing record %u (err=%d)\n",
pIndices[idx], err);
goto bail;
}
@ -478,7 +493,7 @@ RecompressArchive(NuArchive* pArchive, NuValue compression)
heldLen += recHeldLen;
if (heldLen > kMaxHeldLen) {
long statusFlags;
uint32_t statusFlags;
printf(" (flush)\n");
err = NuFlush(pArchive, &statusFlags);
@ -500,12 +515,11 @@ bail:
/*
* Initiate the twirling.
*/
int
TwirlArchive(const char* filename)
int TwirlArchive(const char* filename)
{
NuError err = kNuErrNone;
NuArchive* pArchive = nil;
CRCList* pCRCList = nil;
NuArchive* pArchive = NULL;
CRCList* pCRCList = NULL;
int compression;
int cc;
@ -534,7 +548,7 @@ TwirlArchive(const char* filename)
}
pCRCList = GatherCRCs(pArchive);
if (pCRCList == nil) {
if (pCRCList == NULL) {
fprintf(stderr, "ERROR: unable to get CRC list\n");
goto bail;
}
@ -545,7 +559,7 @@ TwirlArchive(const char* filename)
for (compression = kNuCompressNone; compression <= kNuCompressBzip2;
compression++)
{
long statusFlags;
uint32_t statusFlags;
if (!CompressionSupported(compression))
continue;
@ -571,7 +585,7 @@ TwirlArchive(const char* filename)
for (compression = kNuCompressBzip2; compression >= kNuCompressNone;
compression--)
{
long statusFlags;
uint32_t statusFlags;
if (!CompressionSupported(compression))
continue;
@ -599,7 +613,7 @@ TwirlArchive(const char* filename)
bail:
FreeCRCs(pCRCList);
if (pArchive != nil) {
if (pArchive != NULL) {
NuAbort(pArchive);
NuClose(pArchive);
}
@ -611,22 +625,21 @@ bail:
/*
* Copy from the current offset in "srcfp" to a new file called
* "outFileName". Returns a writable file descriptor for the new file
* on success, or nil on error.
* on success, or NULL on error.
*
* (Note "CopyFile()" exists under Win32.)
*/
FILE*
MyCopyFile(const char* outFileName, FILE* srcfp)
FILE* MyCopyFile(const char* outFileName, FILE* srcfp)
{
char buf[24576];
FILE* outfp;
size_t count;
outfp = fopen(outFileName, kNuFileOpenWriteTrunc);
if (outfp == nil) {
if (outfp == NULL) {
fprintf(stderr, "ERROR: unable to open '%s' (err=%d)\n", outFileName,
errno);
return nil;
return NULL;
}
while (!feof(srcfp)) {
@ -636,14 +649,14 @@ MyCopyFile(const char* outFileName, FILE* srcfp)
if (fwrite(buf, 1, count, outfp) != count) {
fprintf(stderr, "ERROR: failed writing outfp (err=%d)\n", errno);
fclose(outfp);
return nil;
return NULL;
}
}
if (ferror(srcfp)) {
fprintf(stderr, "ERROR: failed reading srcfp (err=%d)\n", errno);
fclose(outfp);
return nil;
return NULL;
}
return outfp;
@ -652,26 +665,25 @@ MyCopyFile(const char* outFileName, FILE* srcfp)
/*
* Let's get started.
*/
int
main(int argc, char** argv)
int main(int argc, char** argv)
{
long major, minor, bug;
int32_t major, minor, bug;
const char* pBuildDate;
FILE* srcfp = nil;
FILE* infp = nil;
FILE* srcfp = NULL;
FILE* infp = NULL;
int cc;
/* don't buffer output */
setvbuf(stdout, nil, _IONBF, 0);
setvbuf(stderr, nil, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, nil);
printf("Using NuFX lib %ld.%ld.%ld built on or after %s\n\n",
(void) NuGetVersion(&major, &minor, &bug, &pBuildDate, NULL);
printf("Using NuFX lib %d.%d.%d built on or after %s\n\n",
major, minor, bug, pBuildDate);
if (argc == 2) {
srcfp = fopen(argv[1], kNuFileOpenReadOnly);
if (srcfp == nil) {
if (srcfp == NULL) {
perror("fopen failed");
exit(1);
}
@ -683,7 +695,7 @@ main(int argc, char** argv)
printf("Copying '%s' to '%s'\n", argv[1], kWorkFileName);
infp = MyCopyFile(kWorkFileName, srcfp);
if (infp == nil) {
if (infp == NULL) {
fprintf(stderr, "Copy failed, bailing.\n");
exit(1);
}

View File

@ -1,12 +1,12 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* Add files to or update files in the archive.
*/
#include "Nulib2.h"
#include "NuLib2.h"
static NuError AddToArchive(NulibState* pState, NuArchive* pArchive);
@ -14,21 +14,20 @@ static NuError AddToArchive(NulibState* pState, NuArchive* pArchive);
/*
* Add the specified files to a new or existing archive.
*/
NuError
DoAdd(NulibState* pState)
NuError DoAdd(NulibState* pState)
{
NuError err;
NuArchive* pArchive = nil;
long flushStatus;
NuArchive* pArchive = NULL;
uint32_t flushStatus;
Assert(pState != nil);
Assert(pState != NULL);
err = OpenArchiveReadWrite(pState);
if (err != kNuErrNone)
goto bail;
pArchive = NState_GetNuArchive(pState);
Assert(pArchive != nil);
Assert(pArchive != NULL);
NState_SetMatchCount(pState, 0);
@ -43,7 +42,7 @@ DoAdd(NulibState* pState)
printf("%s: no records matched\n", gProgName);
bail:
if (pArchive != nil) {
if (pArchive != NULL) {
NuError err2;
#if 0
@ -62,7 +61,7 @@ bail:
"failed afterward");
} else {
ReportError(err,
"Unable to flush archive changes (status=0x%04lx)",
"Unable to flush archive changes (status=0x%04x)",
flushStatus);
}
NuAbort(pArchive);
@ -84,15 +83,14 @@ bail:
* This just results in NuAddFile calls; the deferred write operation
* isn't initiated.
*/
static NuError
AddToArchive(NulibState* pState, NuArchive* pArchive)
static NuError AddToArchive(NulibState* pState, NuArchive* pArchive)
{
NuError err = kNuErrNone;
char* const* pSpec;
int i;
Assert(pState != nil);
Assert(pArchive != nil);
Assert(pState != NULL);
Assert(pArchive != NULL);
if (!NState_GetFilespecCount(pState)) {
err = kNuErrSyntax;

View File

@ -1,12 +1,12 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* Common archive-related utility functions.
*/
#include "Nulib2.h"
#include "NuLib2.h"
/*
@ -24,19 +24,18 @@
* The buffer we return to the archive library will be overwritten the
* next time this function gets called. This is expected.
*/
static NuResult
OutputPathnameFilter(NuArchive* pArchive, void* vproposal)
static NuResult OutputPathnameFilter(NuArchive* pArchive, void* vproposal)
{
NuPathnameProposal* pathProposal = vproposal;
NulibState* pState;
const char* newPathname;
const UNICHAR* newPathnameUNI;
NuRecordIdx renameFromIdx;
char* renameToStr;
char* resultBuf;
UNICHAR* renameToStrUNI;
UNICHAR* resultBufUNI;
Assert(pArchive != nil);
Assert(pArchive != NULL);
(void) NuGetExtraData(pArchive, (void**) &pState);
Assert(pState != nil);
Assert(pState != NULL);
/* handle extract-to-pipe */
if (NState_GetCommand(pState) == kCommandExtractToPipe) {
@ -50,22 +49,22 @@ OutputPathnameFilter(NuArchive* pArchive, void* vproposal)
* the output through the normalizer; if the user typed it, assume
* that it's okay (and let the OS tell them if it isn't).
*/
renameToStr = NState_GetRenameToStr(pState);
if (renameToStr != nil) {
renameToStrUNI = NState_GetRenameToStr(pState);
if (renameToStrUNI != NULL) {
renameFromIdx = NState_GetRenameFromIdx(pState);
if (renameFromIdx == pathProposal->pRecord->recordIdx) {
/* right source file, proceed with the rename */
NState_SetTempPathnameLen(pState, strlen(renameToStr) +1);
resultBuf = NState_GetTempPathnameBuf(pState);
Assert(resultBuf != nil);
strcpy(resultBuf, renameToStr);
NState_SetTempPathnameLen(pState, strlen(renameToStrUNI) +1);
resultBufUNI = NState_GetTempPathnameBuf(pState);
Assert(resultBufUNI != NULL);
strcpy(resultBufUNI, renameToStrUNI);
pathProposal->newPathname = resultBuf;
pathProposal->newPathnameUNI = resultBufUNI;
}
/* free up renameToStr */
NState_SetRenameToStr(pState, nil);
/* free up renameToStrUNI */
NState_SetRenameToStr(pState, NULL);
goto bail;
}
@ -73,13 +72,13 @@ OutputPathnameFilter(NuArchive* pArchive, void* vproposal)
/*
* Convert the pathname into something suitable for the current OS.
*/
newPathname = NormalizePath(pState, pathProposal);
if (newPathname == nil) {
newPathnameUNI = NormalizePath(pState, pathProposal);
if (newPathnameUNI == NULL) {
ReportError(kNuErrNone, "unable to convert pathname");
return kNuAbort;
}
pathProposal->newPathname = newPathname;
pathProposal->newPathnameUNI = newPathnameUNI;
bail:
return kNuOK;
@ -99,12 +98,11 @@ bail:
* first character. A fancier version would play with line disciplines
* so you wouldn't have to hit "return".
*/
static char
GetReplyChar(char defaultReply)
static char GetReplyChar(char defaultReply)
{
char tmpBuf[32];
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == nil)
if (fgets(tmpBuf, sizeof(tmpBuf), stdin) == NULL)
return defaultReply;
if (tmpBuf[0] == '\n' || tmpBuf[0] == '\r')
return defaultReply;
@ -120,8 +118,7 @@ GetReplyChar(char defaultReply)
*
* String returned should be freed by the caller.
*/
static char*
GetReplyString(const char* prompt)
static char* GetReplyString(const char* prompt)
{
char buf[kMaxInputLen];
char* result;
@ -130,10 +127,10 @@ GetReplyString(const char* prompt)
printf("%s", prompt);
fflush(stdout);
result = fgets(buf, sizeof(buf), stdin);
if (result == nil || feof(stdin) || ferror(stdin) || buf[0] == '\0' ||
if (result == NULL || feof(stdin) || ferror(stdin) || buf[0] == '\0' ||
buf[0] == '\n')
{
return nil;
return NULL;
}
/* nuke the terminating '\n', which is lots of fun in filenames */
@ -148,30 +145,29 @@ GetReplyString(const char* prompt)
/*
* Get a one-line comment from the user, of at most "maxLen" bytes.
*
* If the user enters a blank line, return "nil".
* If the user enters a blank line, return "NULL".
*
* A pointer to a newly-allocated buffer is returned.
*/
char*
GetSimpleComment(NulibState* pState, const char* pathname, int maxLen)
char* GetSimpleComment(NulibState* pState, const char* pathname, int maxLen)
{
char* buf = nil;
char* buf = NULL;
char* result;
int len;
buf = Malloc(maxLen);
if (buf == nil)
return nil;
if (buf == NULL)
return NULL;
printf("Enter one-line comment for '%s'\n: ", pathname);
fflush(stdout);
result = fgets(buf, maxLen, stdin);
if (result == nil || feof(stdin) || ferror(stdin) || buf[0] == '\0' ||
if (result == NULL || feof(stdin) || ferror(stdin) || buf[0] == '\0' ||
buf[0] == '\n')
{
Free(buf);
return nil;
return NULL;
}
/* nuke the terminating '\n', which we don't need */
@ -196,8 +192,8 @@ GetSimpleComment(NulibState* pState, const char* pathname, int maxLen)
*
* (Someday "spec" might be a regexp.)
*/
static Boolean
SpecMatchesRecord(NulibState* pState, const char* spec, const NuRecord* pRecord)
static Boolean SpecMatchesRecord(NulibState* pState, const char* spec,
const NuRecord* pRecord)
{
#ifdef NU_CASE_SENSITIVE
if (NState_GetModRecurse(pState))
@ -206,9 +202,9 @@ SpecMatchesRecord(NulibState* pState, const char* spec, const NuRecord* pRecord)
return (strcmp(spec, pRecord->filename) == 0);
#else
if (NState_GetModRecurse(pState))
return (strncasecmp(spec, pRecord->filename, strlen(spec)) == 0);
return (strncasecmp(spec, pRecord->filenameMOR, strlen(spec)) == 0);
else
return (strcasecmp(spec, pRecord->filename) == 0);
return (strcasecmp(spec, pRecord->filenameMOR) == 0);
#endif
}
@ -222,8 +218,7 @@ SpecMatchesRecord(NulibState* pState, const char* spec, const NuRecord* pRecord)
* extraction by criteria other than name, e.g. all text files or all
* files archived before a certain date.
*/
Boolean
IsSpecified(NulibState* pState, const NuRecord* pRecord)
Boolean IsSpecified(NulibState* pState, const NuRecord* pRecord)
{
char* const* pSpec;
int i;
@ -245,36 +240,36 @@ IsSpecified(NulibState* pState, const NuRecord* pRecord)
* General-purpose selection filter, invoked as a callback. Compares the
* selection proposal with the filenames in "filespec".
*/
NuResult
SelectionFilter(NuArchive* pArchive, void* vproposal)
NuResult SelectionFilter(NuArchive* pArchive, void* vproposal)
{
const NuSelectionProposal* selProposal = vproposal;
NulibState* pState;
Assert(pArchive != nil);
Assert(pArchive != NULL);
(void) NuGetExtraData(pArchive, (void**) &pState);
Assert(pState != nil);
Assert(pState != NULL);
if (IsSpecified(pState, selProposal->pRecord)) {
NState_IncMatchCount(pState);
/* we don't get progress notifications for delete, so do it here */
if (NState_GetCommand(pState) == kCommandDelete)
printf("Deleting %s\n", selProposal->pRecord->filename);
if (NState_GetCommand(pState) == kCommandDelete) {
printf("Deleting %s\n", selProposal->pRecord->filenameMOR);
}
return kNuOK;
} else
} else {
return kNuSkip;
}
}
/*
* Print a three-digit progress percentage; range is 0% to 100%.
*/
void
PrintPercentage(ulong total, ulong progress)
void PrintPercentage(uint32_t total, uint32_t progress)
{
ulong perc;
uint32_t perc;
if (!total) {
/*printf(" %%");*/
@ -292,15 +287,14 @@ PrintPercentage(ulong total, ulong progress)
perc = 100;
}
printf("%3ld%%", perc);
printf("%3d%%", perc);
}
/*
* Show our progress, unless we're expanding to a pipe. Invoked as a
* callback by nufxlib.
*/
NuResult
ProgressUpdater(NuArchive* pArchive, void* vProgress)
NuResult ProgressUpdater(NuArchive* pArchive, void* vProgress)
{
const NuProgressData* pProgress = vProgress;
NulibState* pState;
@ -309,14 +303,14 @@ ProgressUpdater(NuArchive* pArchive, void* vProgress)
char nameBuf[kMaxDisplayLen+1];
Boolean showName, eolConv;
Assert(pArchive != nil);
Assert(pArchive != NULL);
(void) NuGetExtraData(pArchive, (void**) &pState);
Assert(pState != nil);
Assert(pState != NULL);
if (NState_GetSuppressOutput(pState))
return kNuOK;
percStr = nil;
percStr = NULL;
showName = false;
eolConv = false;
@ -384,19 +378,19 @@ ProgressUpdater(NuArchive* pArchive, void* vProgress)
switch (pProgress->state) {
case kNuProgressDone:
actionStr = nil;
actionStr = NULL;
percStr = "DONE\n";
break;
case kNuProgressSkipped:
actionStr = nil;
actionStr = NULL;
percStr = "SKIP\n";
break;
case kNuProgressAborted: /* not currently possible in NuLib2 */
actionStr = nil;
actionStr = NULL;
percStr = "CNCL\n";
break;
case kNuProgressFailed:
actionStr = nil;
actionStr = NULL;
percStr = "FAIL\n";
break;
default:
@ -409,21 +403,22 @@ ProgressUpdater(NuArchive* pArchive, void* vProgress)
* Could also use "origPathname", but I like to show what they're
* getting instead of what they're giving.
*/
int len = strlen(pProgress->pathname);
int len = strlen(pProgress->pathnameUNI);
if (len < sizeof(nameBuf)) {
strcpy(nameBuf, pProgress->pathname);
strcpy(nameBuf, pProgress->pathnameUNI);
} else {
nameBuf[0] = nameBuf[1] = '.';
strncpy(nameBuf+2, pProgress->pathname + len - (sizeof(nameBuf)-3),
strncpy(nameBuf+2,
pProgress->pathnameUNI + len - (sizeof(nameBuf)-3),
sizeof(nameBuf)-3);
nameBuf[sizeof(nameBuf)-1] = '\0';
}
}
if (actionStr == nil && percStr != nil) {
if (actionStr == NULL && percStr != NULL) {
printf("\r%s", percStr);
} else if (actionStr != nil && percStr == nil) {
if (percStr == nil) {
} else if (actionStr != NULL && percStr == NULL) {
if (percStr == NULL) {
putc('\r', stdout);
PrintPercentage(pProgress->uncompressedLength,
pProgress->uncompressedProgress);
@ -449,17 +444,16 @@ ProgressUpdater(NuArchive* pArchive, void* vProgress)
* Decide whether or not to replace an existing file (during extract)
* or record (during add).
*/
static NuResult
HandleReplaceExisting(NulibState* pState, NuArchive* pArchive,
static NuResult HandleReplaceExisting(NulibState* pState, NuArchive* pArchive,
const NuErrorStatus* pErrorStatus)
{
NuResult result = kNuOK;
char* renameName;
char reply;
Assert(pState != nil);
Assert(pErrorStatus != nil);
Assert(pErrorStatus->pathname != nil);
Assert(pState != NULL);
Assert(pErrorStatus != NULL);
Assert(pErrorStatus->pathnameUNI != NULL);
Assert(pErrorStatus->canOverwrite);
Assert(pErrorStatus->canSkip);
@ -474,7 +468,7 @@ HandleReplaceExisting(NulibState* pState, NuArchive* pArchive,
while (1) {
printf("\n Replace %s? [y]es, [n]o, [A]ll, [N]one",
pErrorStatus->pathname);
pErrorStatus->pathnameUNI);
if (pErrorStatus->canRename) /* renaming record adds not allowed */
printf(", [r]ename: ");
else
@ -506,10 +500,10 @@ HandleReplaceExisting(NulibState* pState, NuArchive* pArchive,
break; /* continue in "while" loop */
}
renameName = GetReplyString("New name: ");
if (renameName == nil)
if (renameName == NULL)
break; /* continue in "while" loop */
if (pErrorStatus->pRecord == nil) {
ReportError(kNuErrNone, "Unexpected nil record");
if (pErrorStatus->pRecord == NULL) {
ReportError(kNuErrNone, "Unexpected NULL record");
break; /* continue in "while" loop */
}
NState_SetRenameFromIdx(pState,
@ -534,18 +528,17 @@ bail:
/*
* Found a bad CRC... should we press onward?
*
* Note pErrorStatus->pathname may be nil if the error was found in the
* Note pErrorStatus->pathname may be NULL if the error was found in the
* master header or in the record header.
*/
static NuResult
HandleBadCRC(NulibState* pState, NuArchive* pArchive,
static NuResult HandleBadCRC(NulibState* pState, NuArchive* pArchive,
const NuErrorStatus* pErrorStatus)
{
NuResult result = kNuOK;
char reply;
Assert(pState != nil);
Assert(pErrorStatus != nil);
Assert(pState != NULL);
Assert(pErrorStatus != NULL);
if (NState_GetInputUnavailable(pState)) {
putc('\n', stderr);
@ -555,9 +548,9 @@ HandleBadCRC(NulibState* pState, NuArchive* pArchive,
}
while (1) {
if (pErrorStatus->pathname != nil)
if (pErrorStatus->pathnameUNI != NULL)
fprintf(stderr, "\n Found a bad CRC in %s\n",
pErrorStatus->pathname);
pErrorStatus->pathnameUNI);
else
fprintf(stderr, "\n Found a bad CRC in the archive\n");
@ -597,16 +590,15 @@ bail:
* the system equivalent of readdir to scan a directory, so deleting a
* file just means it won't get added.
*/
static NuResult
HandleAddNotFound(NulibState* pState, NuArchive* pArchive,
static NuResult HandleAddNotFound(NulibState* pState, NuArchive* pArchive,
const NuErrorStatus* pErrorStatus)
{
NuResult result = kNuOK;
char reply;
Assert(pState != nil);
Assert(pErrorStatus != nil);
Assert(pErrorStatus->pathname != nil);
Assert(pState != NULL);
Assert(pErrorStatus != NULL);
Assert(pErrorStatus->pathnameUNI != NULL);
if (NState_GetInputUnavailable(pState)) {
putc('\n', stdout);
@ -617,7 +609,7 @@ HandleAddNotFound(NulibState* pState, NuArchive* pArchive,
while (1) {
fprintf(stderr, "\n Couldn't find %s, continue? [y]es, [n]o: ",
pErrorStatus->pathname);
pErrorStatus->pathnameUNI);
fflush(stderr);
reply = GetReplyChar('n');
@ -644,16 +636,15 @@ bail:
* Something failed, and the user may want to choose how to handle it.
* Invoked as a callback.
*/
NuResult
ErrorHandler(NuArchive* pArchive, void* vErrorStatus)
NuResult ErrorHandler(NuArchive* pArchive, void* vErrorStatus)
{
const NuErrorStatus* pErrorStatus = vErrorStatus;
NulibState* pState;
NuResult result;
Assert(pArchive != nil);
Assert(pArchive != NULL);
(void) NuGetExtraData(pArchive, (void**) &pState);
Assert(pState != nil);
Assert(pState != NULL);
/* default action is to abort the current operation */
result = kNuAbort;
@ -722,13 +713,12 @@ ErrorHandler(NuArchive* pArchive, void* vErrorStatus)
* (This was just a test to see if it worked... NufxLib's default behavior
* is fine for NuLib2.)
*/
NuResult
ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
NuResult ErrorMessageHandler(NuArchive* pArchive, void* vErrorMessage)
{
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
fprintf(stderr, "%s%d %3d %s:%d %s %s\n",
pArchive == nil ? "(GLOBAL)" : "",
pArchive == NULL ? "(GLOBAL)" : "",
pErrorMessage->isDebug, pErrorMessage->err, pErrorMessage->file,
pErrorMessage->line, pErrorMessage->function, pErrorMessage->message);
return kNuOK;
@ -752,8 +742,7 @@ static const char* kStdinArchive = "-";
*
* Uses a simplified view of the access flags.
*/
Boolean
IsRecordReadOnly(const NuRecord* pRecord)
Boolean IsRecordReadOnly(const NuRecord* pRecord)
{
if (pRecord->recAccess == 0x21L || pRecord->recAccess == 0x01L)
return true;
@ -765,10 +754,9 @@ IsRecordReadOnly(const NuRecord* pRecord)
/*
* Returns "true" if "archiveName" is the name we use to represent stdin.
*/
Boolean
IsFilenameStdin(const char* archiveName)
Boolean IsFilenameStdin(const char* archiveName)
{
Assert(archiveName != nil);
Assert(archiveName != NULL);
return (strcmp(archiveName, kStdinArchive) == 0);
}
@ -779,13 +767,12 @@ IsFilenameStdin(const char* archiveName)
* Open the archive in read-only mode. We use "file mode" for a file, or
* "streaming mode" for stdin.
*/
NuError
OpenArchiveReadOnly(NulibState* pState)
NuError OpenArchiveReadOnly(NulibState* pState)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
Assert(pState != nil);
Assert(pState != NULL);
if (IsFilenameStdin(NState_GetArchiveFilename(pState))) {
err = NuStreamOpenRO(stdin, &pArchive);
@ -881,10 +868,10 @@ OpenArchiveReadOnly(NulibState* pState)
BailError(err);
bail:
if (err != kNuErrNone && pArchive != nil) {
if (err != kNuErrNone && pArchive != NULL) {
/* clean up */
(void) NuClose(pArchive);
NState_SetNuArchive(pState, nil);
NState_SetNuArchive(pState, NULL);
}
return err;
}
@ -896,18 +883,17 @@ bail:
*
* "Streaming mode" isn't allowed.
*/
NuError
OpenArchiveReadWrite(NulibState* pState)
NuError OpenArchiveReadWrite(NulibState* pState)
{
NuError err = kNuErrNone;
NuArchive* pArchive = nil;
char* tempName = nil;
NuArchive* pArchive = NULL;
char* tempName = NULL;
Assert(pState != nil);
Assert(pState != NULL);
Assert(IsFilenameStdin(NState_GetArchiveFilename(pState)) == false);
tempName = MakeTempArchiveName(pState);
if (tempName == nil)
if (tempName == NULL)
goto bail;
DBUG(("TEMP NAME = '%s'\n", tempName));
@ -979,11 +965,11 @@ OpenArchiveReadWrite(NulibState* pState)
bail:
Free(tempName);
if (err != kNuErrNone && pArchive != nil) {
if (err != kNuErrNone && pArchive != NULL) {
/* clean up */
NuAbort(pArchive);
(void) NuClose(pArchive);
NState_SetNuArchive(pState, nil);
NState_SetNuArchive(pState, NULL);
}
return err;
}

View File

@ -1,5 +1,5 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
@ -17,7 +17,7 @@
*
* TO DO: add "junk skipping" like NufxLib has.
*/
#include "Nulib2.h"
#include "NuLib2.h"
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
@ -44,13 +44,12 @@
* Open a file read-only. We abstract this so we get "r" vs "rb" right.
* (Moves this to SysUtils.c if anybody else needs it.)
*/
NuError
OpenFileReadOnly(const char* filename, FILE** pFp)
NuError OpenFileReadOnly(const char* filename, FILE** pFp)
{
NuError err = kNuErrNone;
*pFp = fopen(filename, kFileOpenReadOnly);
if (*pFp == nil)
if (*pFp == NULL)
err = errno ? errno : kNuErrFileOpen;
return err;
@ -62,8 +61,7 @@ OpenFileReadOnly(const char* filename, FILE** pFp)
*
* If no filespec was provided, then all records are "specified".
*/
Boolean
NameIsSpecified(NulibState* pState, const char* filename)
Boolean NameIsSpecified(NulibState* pState, const char* filename)
{
char* const* pSpec;
int i;
@ -125,37 +123,36 @@ typedef struct BNYArchive {
* something else follows this entry.
*/
typedef struct BNYEntry {
ushort access;
ushort fileType;
ulong auxType;
uchar storageType;
ulong fileSize; /* in 512-byte blocks */
ushort prodosModDate;
ushort prodosModTime;
uint16_t access;
uint16_t fileType;
uint32_t auxType;
uint8_t storageType;
uint32_t fileSize; /* in 512-byte blocks */
uint16_t prodosModDate;
uint16_t prodosModTime;
NuDateTime modWhen; /* computed from previous two fields */
ushort prodosCreateDate;
ushort prodosCreateTime;
uint16_t prodosCreateDate;
uint16_t prodosCreateTime;
NuDateTime createWhen; /* computed from previous two fields */
ulong eof;
ulong realEOF; /* eof is bogus for directories */
char fileName[kBNYMaxFileName+1];
uint32_t eof;
uint32_t realEOF; /* eof is bogus for directories */
char fileName[kBNYMaxFileName+1]; /* ASCII only */
char nativeName[kBNYMaxNativeName+1];
ulong diskSpace; /* in 512-byte blocks */
uchar osType; /* not exactly same as NuFileSysID */
ushort nativeFileType;
uchar phantomFlag;
uchar dataFlags; /* advisory flags */
uchar version;
uchar filesToFollow; /* #of files after this one */
uint32_t diskSpace; /* in 512-byte blocks */
uint8_t osType; /* not exactly same as NuFileSysID */
uint16_t nativeFileType;
uint8_t phantomFlag;
uint8_t dataFlags; /* advisory flags */
uint8_t version;
uint8_t filesToFollow; /* #of files after this one */
uchar blockBuf[kBNYBlockSize];
uint8_t blockBuf[kBNYBlockSize];
} BNYEntry;
/*
* Test for the magic number on a file in SQueezed format.
*/
static inline Boolean
IsSqueezed(uchar one, uchar two)
static inline Boolean IsSqueezed(uint8_t one, uint8_t two)
{
return (one == 0x76 && two == 0xff);
}
@ -163,8 +160,7 @@ IsSqueezed(uchar one, uchar two)
/*
* Test if this entry is a directory.
*/
static inline Boolean
IsDir(BNYEntry* pEntry)
static inline Boolean IsDir(BNYEntry* pEntry)
{
/*
* NuLib and "unblu.c" compared against file type 15 (DIR), so I'm
@ -178,8 +174,7 @@ IsDir(BNYEntry* pEntry)
/*
* Initialize a BNYArchive structure.
*/
static BNYArchive*
BNYInit(NulibState* pState)
static BNYArchive* BNYInit(NulibState* pState)
{
BNYArchive* pBny;
@ -194,11 +189,10 @@ BNYInit(NulibState* pState)
/*
* Free up a BNYArchive, disposing of anything inside it.
*/
static void
BNYFree(BNYArchive* pBny)
static void BNYFree(BNYArchive* pBny)
{
/* don't need to do this on stdin, but won't really hurt */
if (pBny->fp != nil)
if (pBny->fp != NULL)
fclose(pBny->fp);
Free(pBny);
@ -209,15 +203,14 @@ BNYFree(BNYArchive* pBny)
* Open a Binary II archive read-only. Might be a file on disk or a
* stream on stdin.
*/
static NuError
BNYOpenReadOnly(BNYArchive* pBny)
static NuError BNYOpenReadOnly(BNYArchive* pBny)
{
NuError err = kNuErrNone;
NulibState* pState;
Assert(pBny != nil);
Assert(pBny->pState != nil);
Assert(pBny->fp == nil);
Assert(pBny != NULL);
Assert(pBny->pState != NULL);
Assert(pBny->fp == NULL);
pState = pBny->pState;
@ -248,15 +241,14 @@ bail:
* Wrapper for fread(). Note the arguments resemble read(2) rather
* than fread(3S).
*/
static NuError
BNYRead(BNYArchive* pBny, void* buf, size_t nbyte)
static NuError BNYRead(BNYArchive* pBny, void* buf, size_t nbyte)
{
size_t result;
Assert(pBny != nil);
Assert(buf != nil);
Assert(pBny != NULL);
Assert(buf != NULL);
Assert(nbyte > 0);
Assert(pBny->fp != nil);
Assert(pBny->fp != NULL);
errno = 0;
result = fread(buf, 1, nbyte, pBny->fp);
@ -270,12 +262,11 @@ BNYRead(BNYArchive* pBny, void* buf, size_t nbyte)
* and don't need to special-case anything, we only allow relative
* forward seeks.
*/
static NuError
BNYSeek(BNYArchive* pBny, long offset)
static NuError BNYSeek(BNYArchive* pBny, long offset)
{
Assert(pBny != nil);
Assert(pBny->fp != nil);
Assert(pBny->pState != nil);
Assert(pBny != NULL);
Assert(pBny->fp != NULL);
Assert(pBny->pState != NULL);
Assert(offset > 0);
/*DBUG(("--- seeking forward %ld bytes\n", offset));*/
@ -299,8 +290,8 @@ BNYSeek(BNYArchive* pBny, long offset)
/*
* Convert from ProDOS compact date format to the expanded DateTime format.
*/
static void
BNYConvertDateTime(ushort prodosDate, ushort prodosTime, NuDateTime* pWhen)
static void BNYConvertDateTime(uint16_t prodosDate, uint16_t prodosTime,
NuDateTime* pWhen)
{
pWhen->second = 0;
pWhen->minute = prodosTime & 0x3f;
@ -320,15 +311,14 @@ BNYConvertDateTime(ushort prodosDate, ushort prodosTime, NuDateTime* pWhen)
* See the File Type Note for $e0/8000 to decipher the buffer offsets
* and meanings.
*/
static NuError
BNYDecodeHeader(BNYArchive* pBny, BNYEntry* pEntry)
static NuError BNYDecodeHeader(BNYArchive* pBny, BNYEntry* pEntry)
{
NuError err = kNuErrNone;
uchar* raw;
uint8_t* raw;
int len;
Assert(pBny != nil);
Assert(pEntry != nil);
Assert(pBny != NULL);
Assert(pEntry != NULL);
raw = pEntry->blockBuf;
@ -406,8 +396,7 @@ bail:
* We return the new path, which is stored in NulibState's temporary
* filename buffer.
*/
const char*
BNYNormalizePath(BNYArchive* pBny, BNYEntry* pEntry)
const char* BNYNormalizePath(BNYArchive* pBny, BNYEntry* pEntry)
{
NuPathnameProposal pathProposal;
NuRecord fakeRecord;
@ -417,14 +406,14 @@ BNYNormalizePath(BNYArchive* pBny, BNYEntry* pEntry)
memset(&fakeRecord, 0xa1, sizeof(fakeRecord));
memset(&fakeThread, 0xa5, sizeof(fakeThread));
pathProposal.pathname = pEntry->fileName;
pathProposal.pathnameUNI = pEntry->fileName;
pathProposal.filenameSeparator = '/'; /* BNY always uses ProDOS conv */
pathProposal.pRecord = &fakeRecord;
pathProposal.pThread = &fakeThread;
pathProposal.newPathname = nil;
pathProposal.newPathnameUNI = NULL;
pathProposal.newFilenameSeparator = '\0';
pathProposal.newDataSink = nil;
pathProposal.newDataSink = NULL;
/* need the filetype and auxtype for -e/-ee */
fakeRecord.recFileType = pEntry->fileType;
@ -448,8 +437,7 @@ BNYNormalizePath(BNYArchive* pBny, BNYEntry* pEntry)
*
* Uses pEntry->blockBuf, which already has the first 128 bytes in it.
*/
static NuError
BNYCopyBlocks(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
static NuError BNYCopyBlocks(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
{
NuError err = kNuErrNone;
long bytesLeft;
@ -464,7 +452,7 @@ BNYCopyBlocks(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
if (toWrite > kBNYBlockSize)
toWrite = kBNYBlockSize;
if (outfp != nil) {
if (outfp != NULL) {
if (fwrite(pEntry->blockBuf, toWrite, 1, outfp) != 1) {
err = errno ? errno : kNuErrFileWrite;
ReportError(err, "BNY write failed");
@ -522,8 +510,8 @@ bail:
* State during uncompression.
*/
typedef struct USQState {
ulong dataInBuffer;
uchar* dataPtr;
uint32_t dataInBuffer;
uint8_t* dataPtr;
int bitPosn;
int bits;
@ -542,8 +530,7 @@ typedef struct USQState {
/*
* Decode the next symbol from the Huffman stream.
*/
static NuError
USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
static NuError USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
{
short val = 0;
int bits, bitPosn;
@ -579,8 +566,7 @@ USQDecodeHuffSymbol(USQState* pUsqState, int* pVal)
/*
* Read two bytes of signed data out of the buffer.
*/
static inline NuError
USQReadShort(USQState* pUsqState, short* pShort)
static inline NuError USQReadShort(USQState* pUsqState, short* pShort)
{
if (pUsqState->dataInBuffer < 2)
return kNuErrBufferUnderrun;
@ -598,22 +584,21 @@ USQReadShort(USQState* pUsqState, short* pShort)
* Because we have a stop symbol, knowing the uncompressed length of
* the file is not essential.
*/
static NuError
BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
static NuError BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
{
NuError err = kNuErrNone;
USQState usqState;
ulong compRemaining, getSize;
uint32_t compRemaining, getSize;
#ifdef FULL_SQ_HEADER
ushort magic, fileChecksum, checksum;
uint16_t magic, fileChecksum, checksum;
#endif
short nodeCount;
int i, inrep;
uchar* tmpBuf = nil;
uchar lastc = 0;
uint8_t* tmpBuf = NULL;
uint8_t lastc = 0;
tmpBuf = Malloc(kSqBufferSize);
if (tmpBuf == nil) {
if (tmpBuf == NULL) {
err = kNuErrMalloc;
goto bail;
}
@ -677,7 +662,7 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
err = BNYRead(pBny, usqState.dataPtr, getSize);
if (err != kNuErrNone) {
ReportError(err,
"failed reading compressed data (%ld bytes)", getSize);
"failed reading compressed data (%u bytes)", getSize);
goto bail;
}
usqState.dataInBuffer += getSize;
@ -787,7 +772,7 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
getSize);
if (err != kNuErrNone) {
ReportError(err,
"failed reading compressed data (%ld bytes)", getSize);
"failed reading compressed data (%u bytes)", getSize);
goto bail;
}
usqState.dataInBuffer += getSize;
@ -824,9 +809,9 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
val = 2;
}
while (--val) {
/*if (pCrc != nil)
/*if (pCrc != NULL)
*pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1);*/
if (outfp != nil)
if (outfp != NULL)
putc(lastc, outfp);
#ifdef FULL_SQ_HEADER
checksum += lastc;
@ -840,9 +825,9 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
inrep = true;
} else {
lastc = val;
/*if (pCrc != nil)
/*if (pCrc != NULL)
*pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1);*/
if (outfp != nil)
if (outfp != NULL)
putc(lastc, outfp);
#ifdef FULL_SQ_HEADER
checksum += lastc;
@ -876,7 +861,7 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
*/
if (compRemaining > kSqBufferSize) {
err = kNuErrBadData;
ReportError(err, "wow: found %ld bytes left over", compRemaining);
ReportError(err, "wow: found %u bytes left over", compRemaining);
goto bail;
}
if (compRemaining) {
@ -889,7 +874,7 @@ BNYUnSqueeze(BNYArchive* pBny, BNYEntry* pEntry, FILE* outfp)
}
bail:
if (outfp != nil)
if (outfp != NULL)
fflush(outfp);
Free(tmpBuf);
return err;
@ -909,23 +894,22 @@ typedef NuError (*BNYIteratorFunc)(BNYArchive* pBny, BNYEntry* pEntry,
* Iterate through a Binary II archive, calling "func" to perform
* operations on the file.
*/
static NuError
BNYIterate(NulibState* pState, BNYIteratorFunc func)
static NuError BNYIterate(NulibState* pState, BNYIteratorFunc func)
{
NuError err = kNuErrNone;
BNYArchive* pBny = nil;
BNYArchive* pBny = NULL;
BNYEntry entry;
Boolean consumed;
int first = true;
int toFollow;
Assert(pState != nil);
Assert(func != nil);
Assert(pState != NULL);
Assert(func != NULL);
NState_SetMatchCount(pState, 0);
pBny = BNYInit(pState);
if (pBny == nil) {
if (pBny == NULL) {
err = kNuErrMalloc;
goto bail;
}
@ -1012,7 +996,7 @@ BNYIterate(NulibState* pState, BNYIteratorFunc func)
printf("%s: no records match\n", gProgName);
bail:
if (pBny != nil)
if (pBny != NULL)
BNYFree(pBny);
if (err != kNuErrNone) {
DBUG(("--- Iterator returning failure %d\n", err));
@ -1023,8 +1007,8 @@ bail:
/*
* Get a quick table of contents.
*/
static NuError
BNYListShort(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
static NuError BNYListShort(BNYArchive* pBny, BNYEntry* pEntry,
Boolean* pConsumedFlag)
{
NuError err = kNuErrNone;
@ -1036,8 +1020,8 @@ BNYListShort(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
/*
* Get a verbose listing of contents.
*/
static NuError
BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
static NuError BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry,
Boolean* pConsumedFlag)
{
NuError err = kNuErrNone;
Boolean isSqueezed, isReadOnly;
@ -1077,7 +1061,7 @@ BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
printf("%c..%-25.25s ",
isReadOnly ? '+' : ' ', pEntry->fileName + len - 25);
}
printf("%s $%04lX ",
printf("%s $%04X ",
GetFileTypeString(pEntry->fileType), pEntry->auxType);
printf("%s ", FormatDateShort(&pEntry->modWhen, date1));
@ -1086,7 +1070,7 @@ BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
else
printf("unc ");
printf("%8ld", pEntry->realEOF);
printf("%8u", pEntry->realEOF);
printf("\n");
@ -1102,8 +1086,8 @@ BNYListVerbose(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
/*
* Get a verbose table of contents.
*/
static NuError
BNYListDebug(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
static NuError BNYListDebug(BNYArchive* pBny, BNYEntry* pEntry,
Boolean* pConsumedFlag)
{
NuError err = kNuErrNone;
@ -1123,9 +1107,9 @@ BNYListDebug(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
pEntry->createWhen.year+1900, pEntry->createWhen.month,
pEntry->createWhen.day, pEntry->createWhen.hour,
pEntry->createWhen.minute);
printf(" FileType: 0x%04x AuxType: 0x%08lx StorageType: 0x%02x\n",
printf(" FileType: 0x%04x AuxType: 0x%08x StorageType: 0x%02x\n",
pEntry->fileType, pEntry->auxType, pEntry->storageType);
printf(" EOF: %ld FileSize: %ld blocks DiskSpace: %ld blocks\n",
printf(" EOF: %u FileSize: %u blocks DiskSpace: %u blocks\n",
pEntry->eof, pEntry->fileSize, pEntry->diskSpace);
printf(" Access: 0x%04x OSType: %d NativeFileType: 0x%04x\n",
pEntry->access, pEntry->osType, pEntry->nativeFileType);
@ -1146,8 +1130,8 @@ typedef enum { kBNYExtNormal, kBNYExtPipe, kBNYExtTest } ExtMode;
/*
* Handle "extraction" of a directory.
*/
static NuError
BNYExtractDirectory(BNYArchive* pBny, BNYEntry* pEntry, ExtMode extMode)
static NuError BNYExtractDirectory(BNYArchive* pBny, BNYEntry* pEntry,
ExtMode extMode)
{
NuError err = kNuErrNone;
const char* newName;
@ -1173,7 +1157,7 @@ BNYExtractDirectory(BNYArchive* pBny, BNYEntry* pEntry, ExtMode extMode)
*/
/*newName = BNYNormalizePath(pBny, pEntry);*/
newName = pEntry->fileName;
if (newName == nil)
if (newName == NULL)
goto bail;
err = TestFileExistence(newName, &isDir);
@ -1209,14 +1193,14 @@ bail:
/*
* Handle "extract", "extract to pipe", and "test".
*/
static NuError
BNYExtract(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
static NuError BNYExtract(BNYArchive* pBny, BNYEntry* pEntry,
Boolean* pConsumedFlag)
{
NuError err = kNuErrNone;
NulibState* pState;
ExtMode extMode;
const char* actionStr = "HOSED";
FILE* outfp = nil;
FILE* outfp = NULL;
Boolean eolConv;
pState = pBny->pState;
@ -1275,7 +1259,7 @@ BNYExtract(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
}
newName = BNYNormalizePath(pBny, pEntry);
if (newName == nil)
if (newName == NULL)
goto bail;
err = TestFileExistence(newName, &isDir);
@ -1303,13 +1287,13 @@ BNYExtract(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
/* open it, overwriting anything present */
outfp = fopen(newName, "w");
if (outfp == nil) {
if (outfp == NULL) {
err = kNuErrFileOpen;
goto bail;
}
} else {
/* outfp == nil means we're in test mode */
Assert(outfp == nil);
/* outfp == NULL means we're in test mode */
Assert(outfp == NULL);
}
/*
@ -1358,8 +1342,16 @@ BNYExtract(BNYArchive* pBny, BNYEntry* pEntry, Boolean* pConsumedFlag)
*pConsumedFlag = true;
bail:
if (outfp != nil && outfp != stdout)
if (outfp != NULL && outfp != stdout) {
#if defined(MAC_LIKE)
if (SetFinderInfo(fileno(outfp), pEntry->fileType,
pEntry->auxType) != kNuErrNone)
{
fprintf(stderr, "WARNING: unable to set finder info\n");
}
#endif
fclose(outfp);
}
return err;
}
@ -1370,8 +1362,7 @@ bail:
* ===========================================================================
*/
NuError
BNYDoExtract(NulibState* pState)
NuError BNYDoExtract(NulibState* pState)
{
if (NState_GetModConvertText(pState) ||
NState_GetModConvertAll(pState))
@ -1402,26 +1393,22 @@ BNYDoExtract(NulibState* pState)
return BNYIterate(pState, BNYExtract);
}
NuError
BNYDoTest(NulibState* pState)
NuError BNYDoTest(NulibState* pState)
{
return BNYIterate(pState, BNYExtract);
}
NuError
BNYDoListShort(NulibState* pState)
NuError BNYDoListShort(NulibState* pState)
{
return BNYIterate(pState, BNYListShort);
}
NuError
BNYDoListVerbose(NulibState* pState)
NuError BNYDoListVerbose(NulibState* pState)
{
return BNYIterate(pState, BNYListVerbose);
}
NuError
BNYDoListDebug(NulibState* pState)
NuError BNYDoListDebug(NulibState* pState)
{
return BNYIterate(pState, BNYListDebug);
}

View File

@ -1,3 +1,22 @@
2017/09/21 ***** v3.1.0 shipped *****
2015/12/26 fadden
- Fix handling of entries with missing threads.
- Improve handling of Mac OS X file type attributes.
- Updated "recognized extensions" table.
2015/01/09 ***** v3.0.0 shipped *****
2015/01/03 fadden
- Mac OS X: get file/aux type from FinderInfo when adding files.
- Mac OS X: set file type and creator when extracting from Binary ][.
2015/01/02 fadden
- Distinguish Unicode and Mac OS Roman strings.
2014/12/22 fadden
- Source code cleanup.
2014/10/30 ***** v2.2.2 shipped *****
2014/10/28 fadden

View File

@ -1,12 +1,12 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* Delete files from the archive.
*/
#include "Nulib2.h"
#include "NuLib2.h"
/*
@ -15,19 +15,18 @@
* This uses the "bulk" delete call, allowing the SelectionFilter callback
* to do the matching against specified filenames.
*/
NuError
DoDelete(NulibState* pState)
NuError DoDelete(NulibState* pState)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
Assert(pState != nil);
Assert(pState != NULL);
err = OpenArchiveReadWrite(pState);
if (err != kNuErrNone)
goto bail;
pArchive = NState_GetNuArchive(pState);
Assert(pArchive != nil);
Assert(pArchive != NULL);
NState_SetMatchCount(pState, 0);
@ -39,7 +38,7 @@ DoDelete(NulibState* pState)
printf("%s: no records matched\n", gProgName);
bail:
if (pArchive != nil)
if (pArchive != NULL)
(void) NuClose(pArchive);
return err;
}

View File

@ -1,12 +1,12 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* Extract files and test archives.
*/
#include "Nulib2.h"
#include "NuLib2.h"
/*
@ -17,8 +17,7 @@
* show them while we're extracting the files, we have to manually find
* and extract them.
*/
static NuError
ExtractAllRecords(NulibState* pState, NuArchive* pArchive)
static NuError ExtractAllRecords(NulibState* pState, NuArchive* pArchive)
{
NuError err;
const NuRecord* pRecord;
@ -41,7 +40,7 @@ ExtractAllRecords(NulibState* pState, NuArchive* pArchive)
err = NuGetRecord(pArchive, recordIdx, &pRecord);
if (err != kNuErrNone) {
fprintf(stderr, "ERROR: unable to get recordIdx %ld\n", recordIdx);
fprintf(stderr, "ERROR: unable to get recordIdx %u\n", recordIdx);
goto bail;
}
@ -53,16 +52,18 @@ ExtractAllRecords(NulibState* pState, NuArchive* pArchive)
/*
* Look for a comment thread.
*/
for (threadIdx = 0; (ulong)threadIdx < pRecord->recTotalThreads;
for (threadIdx = 0; (uint32_t)threadIdx < pRecord->recTotalThreads;
threadIdx++)
{
pThread = NuGetThread(pRecord, threadIdx);
Assert(pThread != nil);
Assert(pThread != NULL);
if (NuGetThreadID(pThread) == kNuThreadIDComment &&
pThread->actualThreadEOF > 0)
{
printf("----- '%s':\n", pRecord->filename);
UNICHAR* filenameUNI = CopyMORToUNI(pRecord->filenameMOR);
printf("----- '%s':\n", filenameUNI);
free(filenameUNI);
err = NuExtractThread(pArchive, pThread->threadIdx,
NState_GetCommentSink(pState));
if (err != kNuErrNone) {
@ -87,13 +88,12 @@ bail:
/*
* Extract the specified files.
*/
NuError
DoExtract(NulibState* pState)
NuError DoExtract(NulibState* pState)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
Assert(pState != nil);
Assert(pState != NULL);
if (NState_GetModBinaryII(pState))
return BNYDoExtract(pState);
@ -104,7 +104,7 @@ DoExtract(NulibState* pState)
if (err != kNuErrNone)
goto bail;
pArchive = NState_GetNuArchive(pState);
Assert(pArchive != nil);
Assert(pArchive != NULL);
NState_SetMatchCount(pState, 0);
@ -126,7 +126,7 @@ DoExtract(NulibState* pState)
printf("%s: no records match\n", gProgName);
bail:
if (pArchive != nil)
if (pArchive != NULL)
(void) NuClose(pArchive);
return err;
}
@ -135,8 +135,7 @@ bail:
/*
* Extract the specified files to stdout.
*/
NuError
DoExtractToPipe(NulibState* pState)
NuError DoExtractToPipe(NulibState* pState)
{
/* we handle the "to pipe" part farther down */
return DoExtract(pState);
@ -146,13 +145,12 @@ DoExtractToPipe(NulibState* pState)
/*
* Do an integrity check on one or more records in the archive.
*/
NuError
DoTest(NulibState* pState)
NuError DoTest(NulibState* pState)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
Assert(pState != nil);
Assert(pState != NULL);
if (NState_GetModBinaryII(pState))
return BNYDoTest(pState);
@ -163,7 +161,7 @@ DoTest(NulibState* pState)
if (err != kNuErrNone)
goto bail;
pArchive = NState_GetNuArchive(pState);
Assert(pArchive != nil);
Assert(pArchive != NULL);
NState_SetMatchCount(pState, 0);
@ -175,7 +173,7 @@ DoTest(NulibState* pState)
printf("%s: no records match\n", gProgName);
bail:
if (pArchive != nil)
if (pArchive != NULL)
(void) NuClose(pArchive);
return err;
}

View File

@ -1,12 +1,12 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* Filename manipulation, including file type preservation.
*/
#include "Nulib2.h"
#include "NuLib2.h"
#include <ctype.h>
@ -72,31 +72,31 @@ static const char gFileTypeNames[256][4] = {
* file rather than a hard-coded table. Ought to fix that someday.
*/
static const struct {
const char* label;
ushort fileType;
ulong auxType;
uchar flags;
const char* label;
uint8_t fileType;
uint16_t auxType;
} gRecognizedExtensions[] = {
{ "ASM", 0xb0, 0x0003, 0 }, /* APW assembly source */
{ "C", 0xb0, 0x000a, 0 }, /* APW C source */
{ "H", 0xb0, 0x000a, 0 }, /* APW C header */
{ "BNY", 0xe0, 0x8000, 0 }, /* Binary II lib */
{ "BQY", 0xe0, 0x8000, 0 }, /* Binary II lib, w/ compress */
{ "BXY", 0xe0, 0x8000, 0 }, /* Binary II wrap around SHK */
{ "BSE", 0xe0, 0x8000, 0 }, /* Binary II wrap around SEA */
{ "SEA", 0xb3, 0xdb07, 0 }, /* GSHK SEA */
{ "GIF", 0xc0, 0x8006, 0 }, /* GIF image */
{ "JPG", 0x06, 0x0000, 0 }, /* JPEG (nicer than 'NON') */
{ "JPEG", 0x06, 0x0000, 0 }, /* JPEG (nicer than 'NON') */
{ "SHK", 0xe0, 0x8002, 0 }, /* ShrinkIt archive */
{ "ASM", 0xb0, 0x0003 }, /* APW assembly source */
{ "C", 0xb0, 0x000a }, /* APW C source */
{ "H", 0xb0, 0x000a }, /* APW C header */
{ "CPP", 0xb0, 0x0000 }, /* generic source file */
{ "BNY", 0xe0, 0x8000 }, /* Binary II lib */
{ "BQY", 0xe0, 0x8000 }, /* Binary II lib, w/ compress */
{ "BXY", 0xe0, 0x8000 }, /* Binary II wrap around SHK */
{ "BSE", 0xe0, 0x8000 }, /* Binary II wrap around SEA */
{ "SEA", 0xb3, 0xdb07 }, /* GSHK SEA */
{ "TEXT", 0x04, 0x0000 }, /* ASCII text */
{ "GIF", 0xc0, 0x8006 }, /* GIF image */
{ "JPG", 0x06, 0x0000 }, /* JPEG (nicer than 'NON') */
{ "JPEG", 0x06, 0x0000 }, /* JPEG (nicer than 'NON') */
{ "SHK", 0xe0, 0x8002 }, /* ShrinkIt archive */
};
/*
* Return a pointer to the three-letter representation of the file type name.
*/
const char*
GetFileTypeString(ulong fileType)
const char* GetFileTypeString(uint32_t fileType)
{
if (fileType < NELEM(gFileTypeNames))
return gFileTypeNames[fileType];
@ -117,8 +117,7 @@ GetFileTypeString(ulong fileType)
* "pathBuf" is assumed to have enough space to hold the current path
* plus kMaxPathGrowth more. It will be modified in place.
*/
static void
AddPreservationString(NulibState* pState,
static void AddPreservationString(NulibState* pState,
const NuPathnameProposal* pPathProposal, char* pathBuf)
{
char extBuf[kMaxPathGrowth +1];
@ -127,15 +126,15 @@ AddPreservationString(NulibState* pState,
NuThreadID threadID;
char* cp;
Assert(pState != nil);
Assert(pPathProposal != nil);
Assert(pathBuf != nil);
Assert(pState != NULL);
Assert(pPathProposal != NULL);
Assert(pathBuf != NULL);
Assert(NState_GetModPreserveType(pState));
pRecord = pPathProposal->pRecord;
pThread = pPathProposal->pThread;
Assert(pRecord != nil);
Assert(pThread != nil);
Assert(pRecord != NULL);
Assert(pThread != NULL);
cp = extBuf;
@ -144,11 +143,11 @@ AddPreservationString(NulibState* pState,
* return the #of characters written, so we add it up manually.
*/
if (pRecord->recFileType < 0x100 && pRecord->recExtraType < 0x10000) {
sprintf(cp, "%c%02lx%04lx", kPreserveIndic, pRecord->recFileType,
sprintf(cp, "%c%02x%04x", kPreserveIndic, pRecord->recFileType,
pRecord->recExtraType);
cp += 7;
} else {
sprintf(cp, "%c%08lx%08lx", kPreserveIndic, pRecord->recFileType,
sprintf(cp, "%c%08x%08x", kPreserveIndic, pRecord->recFileType,
pRecord->recExtraType);
cp += 17;
}
@ -179,26 +178,26 @@ AddPreservationString(NulibState* pState,
* to be ".txt", and perhaps do something clever for some others.
*/
if (pRecord->recFileType == 0x04 || threadID == kNuThreadIDDiskImage)
pExt = nil;
pExt = NULL;
else
pExt = FindExtension(pState, pathBuf);
if (pExt != nil) {
if (pExt != NULL) {
pExt++; /* skip past the '.' */
if (strlen(pExt) >= kMaxExtLen) {
/* too long, forget it */
pExt = nil;
pExt = NULL;
} else {
/* if strictly decimal-numeric, don't use it (.1, .2, etc) */
(void) strtoul(pExt, &end, 10);
if (*end == '\0') {
pExt = nil;
pExt = NULL;
} else {
/* if '#' appears in it, don't use it -- it'll confuse us */
const char* ccp = pExt;
while (*ccp != '\0') {
if (*ccp == '#') {
pExt = nil;
pExt = NULL;
break;
}
ccp++;
@ -217,11 +216,11 @@ AddPreservationString(NulibState* pState,
else if (pRecord->recFileType) {
pExt = GetFileTypeString(pRecord->recFileType);
if (pExt[0] == '?' || pExt[0] == '$')
pExt = nil;
pExt = NULL;
}
}
if (pExt != nil) {
if (pExt != NULL) {
*cp++ = kFilenameExtDelim;
strcpy(cp, pExt);
cp += strlen(pExt);
@ -248,8 +247,7 @@ AddPreservationString(NulibState* pState,
* This returns the new pathname, which is held in NulibState's temporary
* pathname buffer.
*/
const char*
NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
const char* NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
{
NuError err = kNuErrNone;
char* pathBuf;
@ -259,9 +257,9 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
char localFssep;
int newBufLen;
Assert(pState != nil);
Assert(pPathProposal != nil);
Assert(pPathProposal->pathname != nil);
Assert(pState != NULL);
Assert(pPathProposal != NULL);
Assert(pPathProposal->pathnameUNI != NULL);
localFssep = NState_GetSystemPathSeparator(pState);
@ -270,14 +268,14 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
* requires converting all chars to '%' codes and adding the longest
* possible preservation string.
*/
newBufLen = strlen(pPathProposal->pathname)*3 + kMaxPathGrowth +1;
newBufLen = strlen(pPathProposal->pathnameUNI)*3 + kMaxPathGrowth +1;
NState_SetTempPathnameLen(pState, newBufLen);
pathBuf = NState_GetTempPathnameBuf(pState);
Assert(pathBuf != nil);
if (pathBuf == nil)
return nil;
Assert(pathBuf != NULL);
if (pathBuf == NULL)
return NULL;
startp = pPathProposal->pathname;
startp = pPathProposal->pathnameUNI;
dstp = pathBuf;
while (*startp == pPathProposal->filenameSeparator) {
/* ignore leading path sep; always extract to current dir */
@ -285,9 +283,9 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
}
/* normalize all directory components and the filename component */
while (startp != nil) {
while (startp != NULL) {
endp = strchr(startp, pPathProposal->filenameSeparator);
if (endp != nil) {
if (endp != NULL) {
/* normalize directory component */
err = NormalizeDirectoryName(pState, startp, endp - startp,
pPathProposal->filenameSeparator, &dstp,
@ -312,15 +310,17 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
AddPreservationString(pState, pPathProposal, pathBuf);
} else if (NuGetThreadID(pPathProposal->pThread) == kNuThreadIDRsrcFork)
{
#ifndef HAS_RESOURCE_FORKS
/* add this in lieu of the preservation extension */
strcat(pathBuf, kResourceStr);
#endif
}
startp = nil; /* we're done */
startp = NULL; /* we're done */
}
}
pPathProposal->newPathname = pathBuf;
pPathProposal->newPathnameUNI = pathBuf;
pPathProposal->newFilenameSeparator = localFssep;
/* check for overflow */
@ -332,7 +332,7 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
if (NState_GetModJunkPaths(pState)) {
char* lastFssep;
lastFssep = strrchr(pathBuf, localFssep);
if (lastFssep != nil) {
if (lastFssep != NULL) {
Assert(*(lastFssep+1) != '\0'); /* should already have been caught*/
memmove(pathBuf, lastFssep+1, strlen(lastFssep+1)+1);
}
@ -340,7 +340,7 @@ NormalizePath(NulibState* pState, NuPathnameProposal* pPathProposal)
bail:
if (err != kNuErrNone)
return nil;
return NULL;
return pathBuf;
}
@ -357,9 +357,8 @@ bail:
* This checks the standard list of ProDOS types (which should catch things
* like "TXT" and "BIN") and the separate list of recognized extensions.
*/
static void
LookupExtension(NulibState* pState, const char* ext, ulong* pFileType,
ulong* pAuxType)
static void LookupExtension(NulibState* pState, const char* ext,
uint32_t* pFileType, uint32_t* pAuxType)
{
char uext3[4];
int i, extLen;
@ -409,19 +408,18 @@ bail:
/*
* Try to associate some meaning with the file extension.
*/
void
InterpretExtension(NulibState* pState, const char* pathName, ulong* pFileType,
ulong* pAuxType)
void InterpretExtension(NulibState* pState, const char* pathName,
uint32_t* pFileType, uint32_t* pAuxType)
{
const char* pExt;
Assert(pState != nil);
Assert(pathName != nil);
Assert(pFileType != nil);
Assert(pAuxType != nil);
Assert(pState != NULL);
Assert(pathName != NULL);
Assert(pFileType != NULL);
Assert(pAuxType != NULL);
pExt = FindExtension(pState, pathName);
if (pExt != nil)
if (pExt != NULL)
LookupExtension(pState, pExt+1, pFileType, pAuxType);
}
@ -434,25 +432,24 @@ InterpretExtension(NulibState* pState, const char* pathName, ulong* pFileType,
* We have to be careful not to trip on false-positive occurrences of '#'
* in the filename.
*/
Boolean
ExtractPreservationString(NulibState* pState, char* pathname, ulong* pFileType,
ulong* pAuxType, NuThreadID* pThreadID)
Boolean ExtractPreservationString(NulibState* pState, char* pathname,
uint32_t* pFileType, uint32_t* pAuxType, NuThreadID* pThreadID)
{
char numBuf[9];
ulong fileType, auxType;
uint32_t fileType, auxType;
NuThreadID threadID;
char* pPreserve;
char* cp;
int digitCount;
Assert(pState != nil);
Assert(pathname != nil);
Assert(pFileType != nil);
Assert(pAuxType != nil);
Assert(pThreadID != nil);
Assert(pState != NULL);
Assert(pathname != NULL);
Assert(pFileType != NULL);
Assert(pAuxType != NULL);
Assert(pThreadID != NULL);
pPreserve = strrchr(pathname, kPreserveIndic);
if (pPreserve == nil)
if (pPreserve == NULL)
return false;
/* count up the #of hex digits */
@ -528,8 +525,7 @@ ExtractPreservationString(NulibState* pState, char* pathname, ulong* pFileType,
* This always results in the filename staying the same length or getting
* smaller, so we can do it in place in the buffer.
*/
void
DenormalizePath(NulibState* pState, char* pathBuf)
void DenormalizePath(NulibState* pState, char* pathBuf)
{
const char* srcp;
char* dstp;
@ -583,20 +579,19 @@ DenormalizePath(NulibState* pState, char* pathBuf)
* Find the filename component of a local pathname. Uses the fssep defined
* in pState.
*
* Always returns a pointer to a string; never returns nil.
* Always returns a pointer to a string; never returns NULL.
*/
const char*
FilenameOnly(NulibState* pState, const char* pathname)
const char* FilenameOnly(NulibState* pState, const char* pathname)
{
const char* retstr;
const char* pSlash;
char* tmpStr = nil;
char* tmpStr = NULL;
Assert(pState != nil);
Assert(pathname != nil);
Assert(pState != NULL);
Assert(pathname != NULL);
pSlash = strrchr(pathname, NState_GetSystemPathSeparator(pState));
if (pSlash == nil) {
if (pSlash == NULL) {
retstr = pathname; /* whole thing is the filename */
goto bail;
}
@ -614,7 +609,7 @@ FilenameOnly(NulibState* pState, const char* pathname)
tmpStr[strlen(pathname)-1] = '\0';
pSlash = strrchr(tmpStr, NState_GetSystemPathSeparator(pState));
if (pSlash == nil) {
if (pSlash == NULL) {
retstr = pathname; /* just a filename with a '/' after it */
goto bail;
}
@ -642,11 +637,10 @@ bail:
* An extension is the stuff following the last '.' in the filename. If
* there is nothing following the last '.', then there is no extension.
*
* Returns a pointer to the '.' preceding the extension, or nil if no
* Returns a pointer to the '.' preceding the extension, or NULL if no
* extension was found.
*/
const char*
FindExtension(NulibState* pState, const char* pathname)
const char* FindExtension(NulibState* pState, const char* pathname)
{
const char* pFilename;
const char* pExt;
@ -656,13 +650,13 @@ FindExtension(NulibState* pState, const char* pathname)
* about "/foo.bar/file".
*/
pFilename = FilenameOnly(pState, pathname);
Assert(pFilename != nil);
Assert(pFilename != NULL);
pExt = strrchr(pFilename, kFilenameExtDelim);
/* also check for "/blah/foo.", which doesn't count */
if (pExt != nil && *(pExt+1) != '\0')
if (pExt != NULL && *(pExt+1) != '\0')
return pExt;
return nil;
return NULL;
}

View File

@ -1,12 +1,12 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* List files in the archive.
*/
#include "Nulib2.h"
#include "NuLib2.h"
/* kinds of records */
@ -40,8 +40,7 @@ static const char* gMonths[] = {
/*
* Compute a percentage.
*/
int
ComputePercent(ulong totalSize, ulong size)
int ComputePercent(uint32_t totalSize, uint32_t size)
{
int perc;
@ -69,8 +68,7 @@ ComputePercent(ulong totalSize, ulong size)
*
* Returns "buffer" for the benefit of printf() calls.
*/
char*
FormatDateShort(const NuDateTime* pDateTime, char* buffer)
char* FormatDateShort(const NuDateTime* pDateTime, char* buffer)
{
/* is it valid? */
if (pDateTime->day > 30 || pDateTime->month > 11 || pDateTime->hour > 24 ||
@ -101,21 +99,21 @@ bail:
/*
* NuStream callback function. Displays the filename.
*/
static NuResult
ShowContentsShort(NuArchive* pArchive, void* vpRecord)
static NuResult ShowContentsShort(NuArchive* pArchive, void* vpRecord)
{
const NuRecord* pRecord = (NuRecord*) vpRecord;
NulibState* pState;
Assert(pArchive != nil);
Assert(pArchive != NULL);
(void) NuGetExtraData(pArchive, (void**) &pState);
Assert(pState != nil);
Assert(pState != NULL);
if (!IsSpecified(pState, pRecord))
goto bail;
printf("%s\n",
pRecord->filename == nil ? "<unknown>":(const char*)pRecord->filename);
UNICHAR* filenameUNI = CopyMORToUNI(pRecord->filenameMOR);
printf("%s\n", filenameUNI == NULL ? "<unknown>" : filenameUNI);
free(filenameUNI);
bail:
return kNuOK;
@ -137,18 +135,22 @@ bail:
* a disk image thread, but it's a fair bet ShrinkIt would ignore one
* or the other.
*
* NOTE: we don't currently work around the GSHK zero-length file bug.
* Such records, which have a filename thread but no data threads at all,
* will be categorized as "unknown". We could detect the situation and
* correct it, but we might as well flag it in a user-visible way.
* NOTE: GSHK likes to omit the data threads for zero-length data and
* resource forks. That screws up analysis by scanning for threads. We
* can work around missing resource forks by simply checking the record's
* storage type. We could be clever and detect records that have no
* data-class threads at all, and no additional threads other than a
* comment and filename, but this is just for display. ShrinkIt doesn't
* handle these records correctly in all cases, so flagging them in a
* user-visible way seems reasonable.
*/
static NuError
AnalyzeRecord(const NuRecord* pRecord, enum RecordKind* pRecordKind,
ushort* pFormat, ulong* pTotalLen, ulong* pTotalCompLen)
static NuError AnalyzeRecord(const NuRecord* pRecord,
enum RecordKind* pRecordKind, uint16_t* pFormat, uint32_t* pTotalLen,
uint32_t* pTotalCompLen)
{
const NuThread* pThread;
NuThreadID threadID;
ulong idx;
uint32_t idx;
*pRecordKind = kRecordKindUnknown;
*pTotalLen = *pTotalCompLen = 0;
@ -156,7 +158,7 @@ AnalyzeRecord(const NuRecord* pRecord, enum RecordKind* pRecordKind,
for (idx = 0; idx < pRecord->recTotalThreads; idx++) {
pThread = NuGetThread(pRecord, idx);
Assert(pThread != nil);
Assert(pThread != NULL);
if (pThread->thThreadClass == kNuThreadClassData) {
/* replace what's there if this might be more interesting */
@ -179,6 +181,16 @@ AnalyzeRecord(const NuRecord* pRecord, enum RecordKind* pRecordKind,
}
}
/*
* Fix up the case where we have a forked file, but GSHK decided not
* to include a resource fork in the record.
*/
if (pRecord->recStorageType == kNuStorageExtended &&
*pRecordKind != kRecordKindForkedFile)
{
*pRecordKind = kRecordKindForkedFile;
}
return kNuErrNone;
}
@ -188,22 +200,21 @@ AnalyzeRecord(const NuRecord* pRecord, enum RecordKind* pRecordKind,
* This is intended to mimic the output of some old version of ProDOS 8
* ShrinkIt.
*/
static NuResult
ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
static NuResult ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
{
NuError err = kNuErrNone;
const NuRecord* pRecord = (NuRecord*) vpRecord;
enum RecordKind recordKind;
ulong totalLen, totalCompLen;
ushort format;
uint32_t totalLen, totalCompLen;
uint16_t format;
NulibState* pState;
char date1[kDateOutputLen];
char tmpbuf[16];
int len;
Assert(pArchive != nil);
Assert(pArchive != NULL);
(void) NuGetExtraData(pArchive, (void**) &pState);
Assert(pState != nil);
Assert(pState != NULL);
if (!IsSpecified(pState, pRecord))
goto bail;
@ -213,27 +224,45 @@ ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
if (err != kNuErrNone)
goto bail;
len = strlen(pRecord->filename);
/*
* Display the filename, truncating if it's longer than 27 characters.
*
* Attempting to do column layout with printf string formatting (e.g.
* "%-27s") doesn't really work for UTF-8 because printf() is
* operating on bytes, and the conversion to a Unicode code point
* is happening in the terminal. We need to do the spacing ourselves,
* using the fact that one MOR character turns into one Unicode character.
*
* If the display isn't converting multi-byte sequences to individual
* characters, this won't look right, but we can't make everybody happy.
*/
static const char kSpaces[27+1] = " ";
UNICHAR* filenameUNI;
len = strlen(pRecord->filenameMOR);
if (len <= 27) {
printf("%c%-27.27s ", IsRecordReadOnly(pRecord) ? '+' : ' ',
pRecord->filename);
filenameUNI = CopyMORToUNI(pRecord->filenameMOR);
printf("%c%s%s ", IsRecordReadOnly(pRecord) ? '+' : ' ',
filenameUNI, &kSpaces[len]);
} else {
printf("%c..%-25.25s ", IsRecordReadOnly(pRecord) ? '+' : ' ',
pRecord->filename + len - 25);
filenameUNI = CopyMORToUNI(pRecord->filenameMOR + len - 25);
printf("%c..%s ", IsRecordReadOnly(pRecord) ? '+' : ' ',
filenameUNI);
}
free(filenameUNI);
switch (recordKind) {
case kRecordKindUnknown:
printf("%s- $%04lX ",
printf("%s- $%04X ",
GetFileTypeString(pRecord->recFileType),
pRecord->recExtraType);
break;
case kRecordKindDisk:
sprintf(tmpbuf, "%ldk", totalLen / 1024);
sprintf(tmpbuf, "%dk", totalLen / 1024);
printf("Disk %-6s ", tmpbuf);
break;
case kRecordKindFile:
case kRecordKindForkedFile:
printf("%s%c $%04lX ",
printf("%s%c $%04X ",
GetFileTypeString(pRecord->recFileType),
recordKind == kRecordKindForkedFile ? '+' : ' ',
pRecord->recExtraType);
@ -262,7 +291,7 @@ ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
if (!totalLen && totalCompLen)
printf(" ????"); /* weird */
else
printf("%8ld", totalLen);
printf("%8u", totalLen);
printf("\n");
@ -270,8 +299,10 @@ ShowContentsVerbose(NuArchive* pArchive, void* vpRecord)
bail:
if (err != kNuErrNone) {
printf("(ERROR on '%s')\n", pRecord->filename == nil ?
"<unknown>" : (const char*)pRecord->filename);
filenameUNI = CopyMORToUNI(pRecord->filenameMOR);
printf("(ERROR on '%s')\n",
filenameUNI == NULL ? "<unknown>" : filenameUNI);
free(filenameUNI);
}
return kNuOK;
}
@ -279,13 +310,12 @@ bail:
/*
* Print a short listing of the contents of an archive.
*/
NuError
DoListShort(NulibState* pState)
NuError DoListShort(NulibState* pState)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
Assert(pState != nil);
Assert(pState != NULL);
if (NState_GetModBinaryII(pState))
return BNYDoListShort(pState);
@ -296,13 +326,13 @@ DoListShort(NulibState* pState)
if (err != kNuErrNone)
goto bail;
pArchive = NState_GetNuArchive(pState);
Assert(pArchive != nil);
Assert(pArchive != NULL);
err = NuContents(pArchive, ShowContentsShort);
/* fall through with err */
bail:
if (pArchive != nil)
if (pArchive != NULL)
(void) NuClose(pArchive);
return err;
}
@ -311,18 +341,17 @@ bail:
/*
* Print a more verbose listing of the contents of an archive.
*/
NuError
DoListVerbose(NulibState* pState)
NuError DoListVerbose(NulibState* pState)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
const NuMasterHeader* pHeader;
char date1[kDateOutputLen];
char date2[kDateOutputLen];
long totalLen, totalCompLen;
const char* cp;
Assert(pState != nil);
Assert(pState != NULL);
if (NState_GetModBinaryII(pState))
return BNYDoListVerbose(pState);
@ -333,7 +362,7 @@ DoListVerbose(NulibState* pState)
if (err != kNuErrNone)
goto bail;
pArchive = NState_GetNuArchive(pState);
Assert(pArchive != nil);
Assert(pArchive != NULL);
/*
* Try to get just the filename.
@ -348,7 +377,7 @@ DoListVerbose(NulibState* pState)
if (err != kNuErrNone)
goto bail;
printf(" %-15.15s Created:%s Mod:%s Recs:%5lu\n\n",
printf(" %-15.15s Created:%s Mod:%s Recs:%5u\n\n",
cp,
FormatDateShort(&pHeader->mhArchiveCreateWhen, date1),
FormatDateShort(&pHeader->mhArchiveModWhen, date2),
@ -384,7 +413,7 @@ DoListVerbose(NulibState* pState)
/*(void) NuDebugDumpArchive(pArchive);*/
bail:
if (pArchive != nil)
if (pArchive != NULL)
(void) NuClose(pArchive);
return err;
}
@ -394,8 +423,7 @@ bail:
/*
* Null callback, for those times when you don't really want to do anything.
*/
static NuResult
NullCallback(NuArchive* pArchive, void* vpRecord)
static NuResult NullCallback(NuArchive* pArchive, void* vpRecord)
{
return kNuOK;
}
@ -404,13 +432,12 @@ NullCallback(NuArchive* pArchive, void* vpRecord)
* Print very detailed output, suitable for debugging (requires that
* debug messages be enabled in nufxlib).
*/
NuError
DoListDebug(NulibState* pState)
NuError DoListDebug(NulibState* pState)
{
NuError err;
NuArchive* pArchive = nil;
NuArchive* pArchive = NULL;
Assert(pState != nil);
Assert(pState != NULL);
if (NState_GetModBinaryII(pState))
return BNYDoListDebug(pState);
@ -421,7 +448,7 @@ DoListDebug(NulibState* pState)
if (err != kNuErrNone)
goto bail;
pArchive = NState_GetNuArchive(pState);
Assert(pArchive != nil);
Assert(pArchive != NULL);
/* have to do something to force the library to scan the archive */
err = NuContents(pArchive, NullCallback);
@ -434,7 +461,7 @@ DoListDebug(NulibState* pState)
/* fall through with err */
bail:
if (pArchive != nil)
if (pArchive != NULL)
(void) NuClose(pArchive);
return err;
}

View File

@ -1,19 +1,19 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* Main entry point and shell command argument processing.
*/
#include "Nulib2.h"
#include "NuLib2.h"
#include <ctype.h>
/*
* Globals and constants.
*/
const char* gProgName = "Nulib2";
const char* gProgName = "NuLib2";
/*
@ -42,10 +42,9 @@ static const ValidCombo gValidCombos[] = {
/*
* Find an entry in the gValidCombos table matching the specified command.
*
* Returns nil if not found.
* Returns NULL if not found.
*/
static const ValidCombo*
FindValidComboEntry(Command cmd)
static const ValidCombo* FindValidComboEntry(Command cmd)
{
int i;
@ -54,21 +53,20 @@ FindValidComboEntry(Command cmd)
return &gValidCombos[i];
}
return nil;
return NULL;
}
/*
* Determine whether the specified modifier is valid when used with the
* current command.
*/
static Boolean
IsValidModifier(Command cmd, char modifier)
static Boolean IsValidModifier(Command cmd, char modifier)
{
const ValidCombo* pvc;
pvc = FindValidComboEntry(cmd);
if (pvc != nil) {
if (strchr(pvc->modifiers, modifier) == nil)
if (pvc != NULL) {
if (strchr(pvc->modifiers, modifier) == NULL)
return false;
else
return true;
@ -79,13 +77,12 @@ IsValidModifier(Command cmd, char modifier)
/*
* Determine whether the specified command can be used with stdin as input.
*/
static Boolean
IsValidOnPipe(Command cmd)
static Boolean IsValidOnPipe(Command cmd)
{
const ValidCombo* pvc;
pvc = FindValidComboEntry(cmd);
if (pvc != nil) {
if (pvc != NULL) {
return pvc->okayForPipe;
} else
return false;
@ -94,13 +91,12 @@ IsValidOnPipe(Command cmd)
/*
* Determine whether the specified command can be used with stdin as input.
*/
static Boolean
IsFilespecRequired(Command cmd)
static Boolean IsFilespecRequired(Command cmd)
{
const ValidCombo* pvc;
pvc = FindValidComboEntry(cmd);
if (pvc != nil) {
if (pvc != NULL) {
return pvc->filespecRequired;
} else {
/* command not found? warn about it here... */
@ -114,8 +110,7 @@ IsFilespecRequired(Command cmd)
/*
* Separate the program name out of argv[0].
*/
static const char*
GetProgName(const NulibState* pState, const char* argv0)
static const char* GetProgName(const NulibState* pState, const char* argv0)
{
const char* result;
char sep;
@ -124,7 +119,7 @@ GetProgName(const NulibState* pState, const char* argv0)
sep = NState_GetSystemPathSeparator(pState);
result = strrchr(argv0, sep);
if (result == nil)
if (result == NULL)
result = argv0;
else
result++; /* advance past the separator */
@ -136,20 +131,19 @@ GetProgName(const NulibState* pState, const char* argv0)
/*
* Print program usage.
*/
static void
Usage(const NulibState* pState)
static void Usage(const NulibState* pState)
{
long majorVersion, minorVersion, bugVersion;
int32_t majorVersion, minorVersion, bugVersion;
const char* nufxLibDate;
const char* nufxLibFlags;
(void) NuGetVersion(&majorVersion, &minorVersion, &bugVersion,
&nufxLibDate, &nufxLibFlags);
printf("\nNulib2 v%s, linked with NufxLib v%ld.%ld.%ld [%s]\n",
printf("\nNuLib2 v%s, linked with NufxLib v%d.%d.%d [%s]\n",
NState_GetProgramVersion(pState),
majorVersion, minorVersion, bugVersion, nufxLibFlags);
printf("Copyright (C) 2000-2014, Andy McFadden. All Rights Reserved.\n");
printf("Copyright (C) 2000-2017, Andy McFadden. All Rights Reserved.\n");
printf("This software is distributed under terms of the BSD License.\n");
printf("Visit http://www.nulib.com/ for source code and documentation.\n\n");
printf("Usage: %s -command[modifiers] archive [filename-list]\n\n",
@ -184,8 +178,7 @@ Usage(const NulibState* pState)
/*
* Handle the "-h" command.
*/
NuError
DoHelp(const NulibState* pState)
NuError DoHelp(const NulibState* pState)
{
static const struct {
Command cmd;
@ -273,7 +266,7 @@ DoHelp(const NulibState* pState)
int j;
pvc = FindValidComboEntry(help[i].cmd);
if (pvc == nil) {
if (pvc == NULL) {
fprintf(stderr, "%s: internal error: couldn't find vc for %d\n",
gProgName, help[i].cmd);
continue;
@ -315,8 +308,7 @@ DoHelp(const NulibState* pState)
/*
* Process the command-line options. The results are placed into "pState".
*/
static int
ProcessOptions(NulibState* pState, int argc, char* const* argv)
static int ProcessOptions(NulibState* pState, int argc, char* const* argv)
{
const char* cp;
int idx;
@ -328,7 +320,7 @@ ProcessOptions(NulibState* pState, int argc, char* const* argv)
if (argc == 2 && (tolower(argv[1][0]) == 'h' ||
(argv[1][0] == '-' && tolower(argv[1][1] == 'h')) ) )
{
DoHelp(nil);
DoHelp(NULL);
return -1;
}
@ -486,7 +478,7 @@ ProcessOptions(NulibState* pState, int argc, char* const* argv)
gProgName);
goto fail;
}
NState_SetFilespecPointer(pState, nil);
NState_SetFilespecPointer(pState, NULL);
NState_SetFilespecCount(pState, 0);
}
@ -511,8 +503,7 @@ fail:
*
* Returns 0 on success, 1 on error.
*/
int
DoWork(NulibState* pState)
int DoWork(NulibState* pState)
{
NuError err;
@ -558,17 +549,16 @@ DoWork(NulibState* pState)
/*
* Entry point.
*/
int
main(int argc, char** argv)
int main(int argc, char** argv)
{
NulibState* pState = nil;
long majorVersion, minorVersion, bugVersion;
NulibState* pState = NULL;
int32_t majorVersion, minorVersion, bugVersion;
int result = 0;
(void) NuGetVersion(&majorVersion, &minorVersion, &bugVersion, nil, nil);
(void) NuGetVersion(&majorVersion, &minorVersion, &bugVersion, NULL, NULL);
if (majorVersion != kNuVersionMajor || minorVersion < kNuVersionMinor) {
fprintf(stderr, "ERROR: wrong version of NufxLib --"
" wanted %d.%d.x, got %ld.%ld.%ld.\n",
" wanted %d.%d.x, got %d.%d.%d.\n",
kNuVersionMajor, kNuVersionMinor,
majorVersion, minorVersion, bugVersion);
goto bail;

View File

@ -44,15 +44,6 @@ OPT = @CFLAGS@
GCC_FLAGS = -Wall -Wwrite-strings -Wstrict-prototypes -Wpointer-arith -Wshadow
CFLAGS = @BUILD_FLAGS@ -I. -I$(NUFXSRCDIR) -I$(includedir) @DEFS@
#ifdef PURIFY_BUILD
# PURIFY = purify
# CFLAGS += -DPURIFY
#endif
#ifdef QUANTIFY_BUILD
# QUANTIFY = quantify
# CFLAGS += -DQUANTIFY
#endif
SRCS = Add.c ArcUtils.c Binary2.c Delete.c Extract.c Filename.c \
List.c Main.c MiscStuff.c MiscUtils.c State.c SysUtils.c
OBJS = Add.o ArcUtils.o Binary2.o Delete.o Extract.o Filename.o \
@ -72,10 +63,10 @@ all: $(PRODUCT)
@true
install: $(PRODUCT)
$(srcdir)/mkinstalldirs $(bindir)
$(INSTALL_PROGRAM) $(PRODUCT) $(bindir)
$(srcdir)/mkinstalldirs $(mandir)/man1
$(INSTALL_DATA) nulib2.1 $(mandir)/man1/
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) $(PRODUCT) $(DESTDIR)$(bindir)
$(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/man1
$(INSTALL_DATA) nulib2.1 $(DESTDIR)$(mandir)/man1/
install-shared:
LIB_PRODUCT="libnufx.so" $(MAKE) -e install
@ -87,16 +78,8 @@ install-shared:
shared::
LIB_PRODUCT="libnufx.so" $(MAKE) -e
quantify:
-rm -f $(PRODUCT)
@$(MAKE) QUANTIFY_BUILD=1
purify:
-rm -f $(PRODUCT)
@$(MAKE) PURIFY_BUILD=1
$(PRODUCT): $(OBJS) $(NUFXLIB)
$(PURIFY) $(QUANTIFY) $(CC) -o $@ $(OBJS) -L$(NUFXSRCDIR) -L$(libdir) -lnufx @LIBS@
$(CC) $(LDFLAGS) -o $@ $(OBJS) -L$(NUFXSRCDIR) -L$(libdir) -lnufx @LIBS@
clean:
-rm -f *.o core
@ -141,8 +124,19 @@ baktar:
@gzip -9 nulib2.tar
@mv -i nulib2.tar.gz /home/fadden/BAK/
depend:
makedepend -- $(CFLAGS) -- $(SRCS)
# DO NOT DELETE THIS LINE -- make depend depends on it.
# dependency info
COMMON_HDRS = NuLib2.h SysDefs.h State.h MiscStuff.h config.h \
$(NUFXSRCDIR)/NufxLib.h
Add.o: Add.c $(COMMON_HDRS)
ArcUtils.o: ArcUtils.c $(COMMON_HDRS)
Binary2.o: Binary2.c $(COMMON_HDRS)
Delete.o: Delete.c $(COMMON_HDRS)
Extract.o: Extract.c $(COMMON_HDRS)
Filename.o: Filename.c $(COMMON_HDRS)
List.o: List.c $(COMMON_HDRS)
Main.o: Main.c $(COMMON_HDRS)
MiscStuff.o: MiscStuff.c $(COMMON_HDRS)
MiscUtils.o: MiscUtils.c $(COMMON_HDRS)
State.o: State.c $(COMMON_HDRS)
SysUtils.o: SysUtils.c $(COMMON_HDRS)

View File

@ -16,8 +16,7 @@
* Return a pointer to the appropriate string in the system table, or NULL
* if the value is out of bounds.
*/
const char*
Nu_strerror(int errnum)
const char* Nu_strerror(int errnum)
{
extern int sys_nerr;
extern char *sys_errlist[];
@ -38,8 +37,7 @@ Nu_strerror(int errnum)
* from BSD, is available in the PGP 2.6.2 distribution, but this should
* suffice for those few systems that don't have memmove.
*/
void*
Nu_memmove(void* dst, const void* src, size_t n)
void* Nu_memmove(void* dst, const void* src, size_t n)
{
void* retval = dst;
char* srcp = (char*)src;
@ -80,8 +78,7 @@ Nu_memmove(void* dst, const void* src, size_t n)
* For our purposes here, strtol does all we need it to. Someday
* we should replace this with a "real" version.
*/
unsigned long
Nu_strtoul(const char *nptr, char **endptr, int base)
unsigned long Nu_strtoul(const char *nptr, char **endptr, int base)
{
return strtol(nptr, endptr, base);
}
@ -91,8 +88,7 @@ Nu_strtoul(const char *nptr, char **endptr, int base)
/*
* Compare two strings, case-insensitive.
*/
int
Nu_strcasecmp(const char *str1, const char *str2)
int Nu_strcasecmp(const char *str1, const char *str2)
{
while (*str1 && *str2 && toupper(*str1) == toupper(*str2))
str1++, str2++;
@ -105,8 +101,7 @@ Nu_strcasecmp(const char *str1, const char *str2)
/*
* Compare two strings, case-insensitive, stopping after "n" chars.
*/
int
Nu_strncasecmp(const char *str1, const char *str2, size_t n)
int Nu_strncasecmp(const char *str1, const char *str2, size_t n)
{
while (n && *str1 && *str2 && toupper(*str1) == toupper(*str2))
str1++, str2++, n--;

View File

@ -6,8 +6,8 @@
* Misc stuff (shared between nufxlib and nulib2). This is a collection
* of miscellaneous types and macros that I find generally useful.
*/
#ifndef __MiscStuff__
#define __MiscStuff__
#ifndef NULIB2_MISCSTUFF_H
#define NULIB2_MISCSTUFF_H
#define VALGRIND /* assume we're using it */
@ -42,11 +42,7 @@ int Nu_strncasecmp(const char *s1, const char *s2, size_t n);
* Misc types.
*/
#include <sys/types.h>
#define nil NULL /* I can't seem to stop typing 'nil' now */
typedef uchar Boolean;
typedef unsigned char Boolean;
#define false (0)
#define true (!false)
@ -63,7 +59,7 @@ typedef uchar Boolean;
(x) <= '9' ? (x) - '0' : toupper(x) +10 - 'A' )
/* convert number from 0-15 to hex digit */
#define HexConv(x) ( ((uint)(x)) <= 15 ? \
#define HexConv(x) ( ((unsigned int)(x)) <= 15 ? \
( (x) <= 9 ? (x) + '0' : (x) -10 + 'A') : -1 )
@ -106,4 +102,4 @@ typedef uchar Boolean;
#define kInvalidPtr ((void*)0xa3a3a3a3)
#endif /*__MiscStuff__*/
#endif /*NULIB2_MISCSTUFF_H*/

View File

@ -1,33 +1,31 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* Misc support functions.
*/
#define __MiscUtils_c__
#include "Nulib2.h"
#include "NuLib2.h"
/*
* Similar to perror(), but takes the error as an argument, and knows
* about NufxLib errors as well as system errors.
*
* If "format" is nil, just the error message itself is printed.
* If "format" is NULL, just the error message itself is printed.
*/
void
ReportError(NuError err, const char* format, ...)
void ReportError(NuError err, const char* format, ...)
{
const char* msg;
va_list args;
Assert(format != nil);
Assert(format != NULL);
va_start(args, format);
/* print the message, if any */
if (format != nil) {
if (format != NULL) {
fprintf(stderr, "%s: ERROR: ", gProgName);
vfprintf(stderr, format, args);
}
@ -36,16 +34,16 @@ ReportError(NuError err, const char* format, ...)
if (err == kNuErrNone)
fprintf(stderr, "\n");
else {
if (format != nil)
if (format != NULL)
fprintf(stderr, ": ");
msg = nil;
msg = NULL;
if (err >= 0)
msg = strerror(err);
if (msg == nil)
if (msg == NULL)
msg = NuStrError(err);
if (msg == nil)
if (msg == NULL)
fprintf(stderr, "(unknown err=%d)\n", err);
else
fprintf(stderr, "%s\n", msg);
@ -62,48 +60,44 @@ ReportError(NuError err, const char* format, ...)
*/
#ifndef USE_DMALLOC
void*
Malloc(size_t size)
void* Malloc(size_t size)
{
void* _result;
Assert(size > 0);
_result = malloc(size);
if (_result == nil) {
ReportError(kNuErrMalloc, "malloc(%u) failed", (uint) size);
if (_result == NULL) {
ReportError(kNuErrMalloc, "malloc(%u) failed", (unsigned int) size);
DebugAbort(); /* leave a core dump if we're built for it */
}
DebugFill(_result, size);
return _result;
}
void*
Calloc(size_t size)
void* Calloc(size_t size)
{
void* _cresult = Malloc(size);
memset(_cresult, 0, size);
return _cresult;
}
void*
Realloc(void* ptr, size_t size)
void* Realloc(void* ptr, size_t size)
{
void* _result;
Assert(ptr != nil); /* disallow this usage */
Assert(ptr != NULL); /* disallow this usage */
Assert(size > 0); /* disallow this usage */
_result = realloc(ptr, size);
if (_result == nil) {
ReportError(kNuErrMalloc, "realloc(%u) failed", (uint) size);
if (_result == NULL) {
ReportError(kNuErrMalloc, "realloc(%u) failed", (unsigned int) size);
DebugAbort(); /* leave a core dump if we're built for it */
}
return _result;
}
void
Free(void* ptr)
void Free(void* ptr)
{
if (ptr != nil)
if (ptr != NULL)
free(ptr);
}
#endif
@ -111,11 +105,34 @@ Free(void* ptr)
/*
* This gets called when a buffer DataSource is no longer needed.
*/
NuResult
FreeCallback(NuArchive* pArchive, void* args)
NuResult FreeCallback(NuArchive* pArchive, void* args)
{
DBUG(("+++ free callback 0x%08lx\n", (long) args));
Free(args);
return kNuOK;
}
/*
* Convert Mac OS Roman to Unicode. The caller must free the string
* returned.
*
* Returns NULL if stringMOR is NULL or if the conversion fails.
*/
UNICHAR* CopyMORToUNI(const char* stringMOR)
{
size_t uniLen;
UNICHAR* uniBuf;
if (stringMOR == NULL) {
return NULL;
}
uniLen = NuConvertMORToUNI(stringMOR, NULL, 0);
if (uniLen == (size_t) -1) {
return NULL;
}
uniBuf = (UNICHAR*) malloc(uniLen);
NuConvertMORToUNI(stringMOR, uniBuf, uniLen);
return uniBuf;
}

View File

@ -1,11 +1,11 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*/
#ifndef __Nulib2__
#define __Nulib2__
#ifndef NULIB2_NULIB2_H
#define NULIB2_NULIB2_H
#include "SysDefs.h" /* system-dependent defs; must come first */
#include <NufxLib.h>
@ -42,7 +42,7 @@ Boolean IsFilenameStdin(const char* archiveName);
Boolean IsSpecified(NulibState* pState, const NuRecord* pRecord);
NuError OpenArchiveReadOnly(NulibState* pState);
NuError OpenArchiveReadWrite(NulibState* pState);
const NuThread* GetThread(const NuRecord* pRecord, ulong idx);
const NuThread* GetThread(const NuRecord* pRecord, uint32_t idx);
Boolean IsRecordReadOnly(const NuRecord* pRecord);
/* Binary2.c */
@ -61,12 +61,12 @@ NuError DoExtractToPipe(NulibState* pState);
NuError DoTest(NulibState* pState);
/* Filename.c */
const char* GetFileTypeString(ulong fileType);
const char* GetFileTypeString(uint32_t fileType);
const char* NormalizePath(NulibState* pState, NuPathnameProposal* pathProposal);
void InterpretExtension(NulibState* pState, const char* pathName,
ulong* pFileType, ulong* pAuxType);
uint32_t* pFileType, uint32_t* pAuxType);
Boolean ExtractPreservationString(NulibState* pState, char* pathname,
ulong* pFileType, ulong* pAuxType, NuThreadID* pThreadID);
uint32_t* pFileType, uint32_t* pAuxType, NuThreadID* pThreadID);
void DenormalizePath(NulibState* pState, char* pathBuf);
const char* FilenameOnly(NulibState* pState, const char* pathname);
const char* FindExtension(NulibState* pState, const char* pathname);
@ -90,7 +90,7 @@ void ReportError(NuError err, const char* format, ...)
# define Malloc(size) malloc(size)
# define Calloc(size) calloc(1, size)
# define Realloc(ptr, size) realloc(ptr, size)
# define Free(ptr) (ptr != nil ? free(ptr) : (void)0)
# define Free(ptr) (ptr != NULL ? free(ptr) : (void)0)
#else
void* Malloc(size_t size);
void* Calloc(size_t size);
@ -98,6 +98,7 @@ void* Realloc(void* ptr, size_t size);
void Free(void* ptr);
#endif
NuResult FreeCallback(NuArchive* pArchive, void* args);
UNICHAR* CopyMORToUNI(const char* stringMOR);
/* SysUtils.c */
NuError NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
@ -105,9 +106,10 @@ NuError NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
NuError NormalizeDirectoryName(NulibState* pState, const char* srcp,
long srcLen, char fssep, char** pDstp, long dstLen);
char* MakeTempArchiveName(NulibState* pState);
NuError SetFinderInfo(int fd, uint8_t proType, uint16_t proAux);
NuError AddFile(NulibState* pState, NuArchive* pArchive,
const char* pathname);
NuError Mkdir(const char* dir);
NuError TestFileExistence(const char* fileName, Boolean* pIsDir);
#endif /*__Nulib2__*/
#endif /*NULIB2_NULIB2_H*/

View File

@ -1,9 +1,9 @@
NuLib2 README, updated 2004/03/10
NuLib2 README, updated 2015/01/03
http://www.nulib.com/
To build NuLib2, you will also need a copy of NufxLib. This may have come
in the same .tar.gz file. Build the nufxlib library first.
To build NuLib2, you will also need a copy of NufxLib. This should have come
in the same distribution file. Build the NufxLib library first.
UNIX
@ -59,10 +59,10 @@ If you're using BeOS/PPC, it will also do:
Mac OS X
========
This works just like the UNIX version. You'll see some warnings due to some
namespace collisions between nufxlib and Carbon, but everything will work
fine. The Carbon framework is used to enable support for filetypes and
resource forks.
This works just like the UNIX version, but includes support for resource
forks and Finder file/aux types.
Tested with Xcode v5.1.1 and Mac OS 10.8.5.
Win32
@ -71,23 +71,25 @@ Win32
If you're using an environment that supports "configure" scripts, such as
DJGPP, follow the UNIX instructions.
NuLib2 has been tested with Microsoft Visual C++ 6.0. To build NuLib2,
start up a DOS shell and run vcvars32.bat to set your environment. Run:
nmake -f makefile.msc
to build with debugging info, or
nmake -f makefile.msc nodebug=1
to build optimized.
NuLib2 has been tested with Microsoft Visual C++ 12 (Visual Studio 2013).
To build NuLib2, run the "Visual Studio 2013 x86 Native Tools Command
Prompt" shortcut to get a shell. Change to the nulib2 directory, then:
See the notes in Makefile.msc for building with zlib, libbz2, and when
NufxLib is in a DLL.
nmake -f makefile.msc
If you want to have zlib support enabled, you will need to have zlib.lib
copied into the directory. See "makefile.msc" for more details.
Unicode filename support has not been ported to Windows. Non-ASCII
characters will be interpreted as the default character set (CP1252).
This is the way NuLib2 has always worked in Windows, but it may not
match with the behavior of CiderPress. In any event, this only affects
files with non-ASCII filenames.
Other Notes
===========
All of the source code is now formatted with spaces instead of tabs.
Fun benchmark of the day:
Time to compress 1525 files, totaling 19942152 bytes, on an Apple IIgs
@ -140,7 +142,7 @@ Legalese
========
NuLib2, a NuFX and Binary II archive application.
Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
Copyright (C) 2000-2014 by Andy McFadden, All Rights Reserved.
See COPYING for license.

View File

@ -1,27 +1,26 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* Global-ish state object.
*/
#include "Nulib2.h"
#include "NuLib2.h"
static const char* gProgramVersion = "2.2.2";
static const char* gProgramVersion = "3.1.0";
/*
* Allocate and initialize the semi-global Nulib2 state object.
* Allocate and initialize the semi-global NuLib2 state object.
*/
NuError
NState_Init(NulibState** ppState)
NuError NState_Init(NulibState** ppState)
{
Assert(ppState != nil);
Assert(ppState != NULL);
*ppState = Calloc(sizeof(**ppState));
if (*ppState == nil)
if (*ppState == NULL)
return kNuErrMalloc;
/*
@ -41,8 +40,7 @@ NState_Init(NulibState** ppState)
/*
* A little extra initialization, performed after arguments are parsed.
*/
NuError
NState_ExtraInit(NulibState* pState)
NuError NState_ExtraInit(NulibState* pState)
{
NuError err;
NuValue convertEOL;
@ -74,25 +72,23 @@ NState_ExtraInit(NulibState* pState)
/*
* Free up the state structure and its contents.
*/
void
NState_Free(NulibState* pState)
void NState_Free(NulibState* pState)
{
if (pState == nil)
if (pState == NULL)
return;
Free(pState->renameToStr); /* ?? */
Free(pState->tempPathnameBuf);
if (pState->pPipeSink != nil)
if (pState->pPipeSink != NULL)
NuFreeDataSink(pState->pPipeSink);
if (pState->pCommentSink != nil)
if (pState->pCommentSink != NULL)
NuFreeDataSink(pState->pCommentSink);
Free(pState);
}
#ifdef DEBUG_MSGS
void
NState_DebugDump(const NulibState* pState)
void NState_DebugDump(const NulibState* pState)
{
/* this table will break if the code changes, but it's just for debugging */
static const char* kCommandNames[] = {
@ -108,7 +104,7 @@ NState_DebugDump(const NulibState* pState)
"help",
};
Assert(pState != nil);
Assert(pState != NULL);
printf("NState:\n");
printf(" programVersion: '%s'\n", pState->programVersion);
@ -162,153 +158,131 @@ NState_DebugDump(const NulibState* pState)
* ===========================================================================
*/
char
NState_GetSystemPathSeparator(const NulibState* pState)
char NState_GetSystemPathSeparator(const NulibState* pState)
{
return pState->systemPathSeparator;
}
char
NState_GetAltSystemPathSeparator(const NulibState* pState)
char NState_GetAltSystemPathSeparator(const NulibState* pState)
{
return pState->altSystemPathSeparator;
}
const char*
NState_GetProgramVersion(const NulibState* pState)
const char* NState_GetProgramVersion(const NulibState* pState)
{
return pState->programVersion;
}
NuArchive*
NState_GetNuArchive(const NulibState* pState)
NuArchive* NState_GetNuArchive(const NulibState* pState)
{
return pState->pArchive;
}
void
NState_SetNuArchive(NulibState* pState, NuArchive* pArchive)
void NState_SetNuArchive(NulibState* pState, NuArchive* pArchive)
{
pState->pArchive = pArchive;
}
Boolean
NState_GetSuppressOutput(const NulibState* pState)
Boolean NState_GetSuppressOutput(const NulibState* pState)
{
return pState->suppressOutput;
}
void
NState_SetSuppressOutput(NulibState* pState, Boolean doSuppress)
void NState_SetSuppressOutput(NulibState* pState, Boolean doSuppress)
{
pState->suppressOutput = doSuppress;
}
Boolean
NState_GetInputUnavailable(const NulibState* pState)
Boolean NState_GetInputUnavailable(const NulibState* pState)
{
return pState->inputUnavailable;
}
void
NState_SetInputUnavailable(NulibState* pState, Boolean isUnavailable)
void NState_SetInputUnavailable(NulibState* pState, Boolean isUnavailable)
{
pState->inputUnavailable = isUnavailable;
}
NuRecordIdx
NState_GetRenameFromIdx(const NulibState* pState)
NuRecordIdx NState_GetRenameFromIdx(const NulibState* pState)
{
return pState->renameFromIdx;
}
void
NState_SetRenameFromIdx(NulibState* pState, NuRecordIdx recordIdx)
void NState_SetRenameFromIdx(NulibState* pState, NuRecordIdx recordIdx)
{
pState->renameFromIdx = recordIdx;
}
char*
NState_GetRenameToStr(const NulibState* pState)
char* NState_GetRenameToStr(const NulibState* pState)
{
return pState->renameToStr;
}
void
NState_SetRenameToStr(NulibState* pState, char* str)
void NState_SetRenameToStr(NulibState* pState, char* str)
{
Free(pState->renameToStr);
pState->renameToStr = str;
}
NuDataSink*
NState_GetPipeSink(const NulibState* pState)
NuDataSink* NState_GetPipeSink(const NulibState* pState)
{
return pState->pPipeSink;
}
NuDataSink*
NState_GetCommentSink(const NulibState* pState)
NuDataSink* NState_GetCommentSink(const NulibState* pState)
{
return pState->pCommentSink;
}
long
NState_GetMatchCount(const NulibState* pState)
long NState_GetMatchCount(const NulibState* pState)
{
return pState->matchCount;
}
void
NState_SetMatchCount(NulibState* pState, long count)
void NState_SetMatchCount(NulibState* pState, long count)
{
pState->matchCount = count;
}
void
NState_IncMatchCount(NulibState* pState)
void NState_IncMatchCount(NulibState* pState)
{
pState->matchCount++;
}
void
NState_AddToTotals(NulibState* pState, long len, long compLen)
void NState_AddToTotals(NulibState* pState, long len, long compLen)
{
pState->totalLen += len;
pState->totalCompLen += compLen;
}
void
NState_GetTotals(NulibState* pState, long* pTotalLen, long* pTotalCompLen)
void NState_GetTotals(NulibState* pState, long* pTotalLen, long* pTotalCompLen)
{
*pTotalLen = pState->totalLen;
*pTotalCompLen = pState->totalCompLen;
}
long
NState_GetTempPathnameLen(NulibState* pState)
long NState_GetTempPathnameLen(NulibState* pState)
{
return pState->tempPathnameAlloc;
}
void
NState_SetTempPathnameLen(NulibState* pState, long len)
void NState_SetTempPathnameLen(NulibState* pState, long len)
{
char* newBuf;
len++; /* add one for the '\0' */
if (pState->tempPathnameAlloc < len) {
if (pState->tempPathnameBuf == nil)
if (pState->tempPathnameBuf == NULL)
newBuf = Malloc(len);
else
newBuf = Realloc(pState->tempPathnameBuf, len);
Assert(newBuf != nil);
if (newBuf == nil) {
Assert(newBuf != NULL);
if (newBuf == NULL) {
Free(pState->tempPathnameBuf);
pState->tempPathnameBuf = nil;
pState->tempPathnameBuf = NULL;
pState->tempPathnameAlloc = 0;
ReportError(kNuErrMalloc, "buf realloc failed (%ld)", len);
return;
@ -319,237 +293,198 @@ NState_SetTempPathnameLen(NulibState* pState, long len)
}
}
char*
NState_GetTempPathnameBuf(NulibState* pState)
char* NState_GetTempPathnameBuf(NulibState* pState)
{
return pState->tempPathnameBuf;
}
Command
NState_GetCommand(const NulibState* pState)
Command NState_GetCommand(const NulibState* pState)
{
return pState->command;
}
void
NState_SetCommand(NulibState* pState, Command cmd)
void NState_SetCommand(NulibState* pState, Command cmd)
{
pState->command = cmd;
}
const char*
NState_GetArchiveFilename(const NulibState* pState)
const char* NState_GetArchiveFilename(const NulibState* pState)
{
return pState->archiveFilename;
}
void
NState_SetArchiveFilename(NulibState* pState, const char* archiveFilename)
void NState_SetArchiveFilename(NulibState* pState, const char* archiveFilename)
{
pState->archiveFilename = archiveFilename;
}
char* const*
NState_GetFilespecPointer(const NulibState* pState)
char* const* NState_GetFilespecPointer(const NulibState* pState)
{
return pState->filespecPointer;
}
void
NState_SetFilespecPointer(NulibState* pState, char* const* filespecPointer)
void NState_SetFilespecPointer(NulibState* pState, char* const* filespecPointer)
{
pState->filespecPointer = filespecPointer;
}
long
NState_GetFilespecCount(const NulibState* pState)
long NState_GetFilespecCount(const NulibState* pState)
{
return pState->filespecCount;
}
void
NState_SetFilespecCount(NulibState* pState, long filespecCount)
void NState_SetFilespecCount(NulibState* pState, long filespecCount)
{
pState->filespecCount = filespecCount;
}
Boolean
NState_GetModUpdate(const NulibState* pState)
Boolean NState_GetModUpdate(const NulibState* pState)
{
return pState->modUpdate;
}
void
NState_SetModUpdate(NulibState* pState, Boolean val)
void NState_SetModUpdate(NulibState* pState, Boolean val)
{
pState->modUpdate = val;
}
Boolean
NState_GetModFreshen(const NulibState* pState)
Boolean NState_GetModFreshen(const NulibState* pState)
{
return pState->modFreshen;
}
void
NState_SetModFreshen(NulibState* pState, Boolean val)
void NState_SetModFreshen(NulibState* pState, Boolean val)
{
pState->modFreshen = val;
}
Boolean
NState_GetModRecurse(const NulibState* pState)
Boolean NState_GetModRecurse(const NulibState* pState)
{
return pState->modRecurse;
}
void
NState_SetModRecurse(NulibState* pState, Boolean val)
void NState_SetModRecurse(NulibState* pState, Boolean val)
{
pState->modRecurse = val;
}
Boolean
NState_GetModJunkPaths(const NulibState* pState)
Boolean NState_GetModJunkPaths(const NulibState* pState)
{
return pState->modJunkPaths;
}
void
NState_SetModJunkPaths(NulibState* pState, Boolean val)
void NState_SetModJunkPaths(NulibState* pState, Boolean val)
{
pState->modJunkPaths = val;
}
Boolean
NState_GetModNoCompression(const NulibState* pState)
Boolean NState_GetModNoCompression(const NulibState* pState)
{
return pState->modNoCompression;
}
void
NState_SetModNoCompression(NulibState* pState, Boolean val)
void NState_SetModNoCompression(NulibState* pState, Boolean val)
{
pState->modNoCompression = val;
}
Boolean
NState_GetModCompressDeflate(const NulibState* pState)
Boolean NState_GetModCompressDeflate(const NulibState* pState)
{
return pState->modCompressDeflate;
}
void
NState_SetModCompressDeflate(NulibState* pState, Boolean val)
void NState_SetModCompressDeflate(NulibState* pState, Boolean val)
{
pState->modCompressDeflate = val;
}
Boolean
NState_GetModCompressBzip2(const NulibState* pState)
Boolean NState_GetModCompressBzip2(const NulibState* pState)
{
return pState->modCompressBzip2;
}
void
NState_SetModCompressBzip2(NulibState* pState, Boolean val)
void NState_SetModCompressBzip2(NulibState* pState, Boolean val)
{
pState->modCompressBzip2 = val;
}
Boolean
NState_GetModComments(const NulibState* pState)
Boolean NState_GetModComments(const NulibState* pState)
{
return pState->modComments;
}
void
NState_SetModComments(NulibState* pState, Boolean val)
void NState_SetModComments(NulibState* pState, Boolean val)
{
pState->modComments = val;
}
Boolean
NState_GetModBinaryII(const NulibState* pState)
Boolean NState_GetModBinaryII(const NulibState* pState)
{
return pState->modBinaryII;
}
void
NState_SetModBinaryII(NulibState* pState, Boolean val)
void NState_SetModBinaryII(NulibState* pState, Boolean val)
{
pState->modBinaryII = val;
}
Boolean
NState_GetModConvertText(const NulibState* pState)
Boolean NState_GetModConvertText(const NulibState* pState)
{
return pState->modConvertText;
}
void
NState_SetModConvertText(NulibState* pState, Boolean val)
void NState_SetModConvertText(NulibState* pState, Boolean val)
{
pState->modConvertText = val;
}
Boolean
NState_GetModConvertAll(const NulibState* pState)
Boolean NState_GetModConvertAll(const NulibState* pState)
{
return pState->modConvertAll;
}
void
NState_SetModConvertAll(NulibState* pState, Boolean val)
void NState_SetModConvertAll(NulibState* pState, Boolean val)
{
pState->modConvertAll = val;
}
Boolean
NState_GetModOverwriteExisting(const NulibState* pState)
Boolean NState_GetModOverwriteExisting(const NulibState* pState)
{
return pState->modOverwriteExisting;
}
void
NState_SetModOverwriteExisting(NulibState* pState, Boolean val)
void NState_SetModOverwriteExisting(NulibState* pState, Boolean val)
{
pState->modOverwriteExisting = val;
}
Boolean
NState_GetModAddAsDisk(const NulibState* pState)
Boolean NState_GetModAddAsDisk(const NulibState* pState)
{
return pState->modAddAsDisk;
}
void
NState_SetModAddAsDisk(NulibState* pState, Boolean val)
void NState_SetModAddAsDisk(NulibState* pState, Boolean val)
{
pState->modAddAsDisk = val;
}
Boolean
NState_GetModPreserveType(const NulibState* pState)
Boolean NState_GetModPreserveType(const NulibState* pState)
{
return pState->modPreserveType;
}
void
NState_SetModPreserveType(NulibState* pState, Boolean val)
void NState_SetModPreserveType(NulibState* pState, Boolean val)
{
pState->modPreserveType = val;
}
Boolean
NState_GetModPreserveTypeExtended(const NulibState* pState)
Boolean NState_GetModPreserveTypeExtended(const NulibState* pState)
{
return pState->modPreserveTypeExtended;
}
void
NState_SetModPreserveTypeExtended(NulibState* pState, Boolean val)
void NState_SetModPreserveTypeExtended(NulibState* pState, Boolean val)
{
pState->modPreserveTypeExtended = val;
}

View File

@ -1,17 +1,17 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*/
#ifndef __State__
#define __State__
#ifndef NULIB2_STATE_H
#define NULIB2_STATE_H
#include "MiscStuff.h"
#include "NufxLib.h"
/*
* Things you can tell Nulib2 to do.
* Things you can tell NuLib2 to do.
*
* (Some debug code in NState_DebugDump() is sensitive to the order here.)
*/
@ -154,4 +154,4 @@ void NState_SetModPreserveType(NulibState* pState, Boolean val);
Boolean NState_GetModPreserveTypeExtended(const NulibState* pState);
void NState_SetModPreserveTypeExtended(NulibState* pState, Boolean val);
#endif /*__State__*/
#endif /*NULIB2_STATE_H*/

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING-LIB.
*
* This file was adapted from Devin Reade's "sunos4.h" in NuLib 3.2.5.
* It is provided for compilation under SunOS 4.x, when an ANSI compiler
* (such as gcc) is used. The system header files aren't quite sufficient
* to eliminate hordes of warnings.
*/
#ifndef __SunOS4__
#define __SunOS4__
#ifdef __GNUC__
extern int _flsbuf(int, FILE*);
extern int _filbuf(FILE*);
#endif
extern void bcopy(char*, char*, int);
extern int fclose(FILE*);
extern int fflush(FILE*);
extern int fprintf(FILE*, const char*, ...);
extern int fread(char*, int, int, FILE *);
extern int fseek(FILE*, long, int);
extern int ftruncate(int, off_t);
extern int fwrite(const char*, int, int, FILE*);
extern char* mktemp(char *template);
extern time_t mktime(struct tm*);
extern int perror(const char*);
extern int printf(const char*, ...);
extern int remove(const char*);
extern int rename(const char*, const char*);
extern int tolower(int);
extern int setvbuf(FILE*, char*, int, int);
extern int sscanf(char*, const char*, ...);
extern int strcasecmp(const char*, const char*);
extern int strncasecmp(const char*, const char*, size_t);
extern long strtol(const char *, char **, int);
extern int system(const char*);
extern time_t timelocal(struct tm*);
extern time_t time(time_t*);
extern int toupper(int);
extern int vfprintf(FILE*, const char *, va_list);
extern char* vsprintf(char *str, const char *format, va_list ap);
#endif /*__SunOS4__*/

View File

@ -1,13 +1,13 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* This was adapted from gzip's "tailor.h" and NuLib's "nudefs.h".
*/
#ifndef __SysDefs__
#define __SysDefs__
#ifndef NULIB2_SYSDEFS_H
#define NULIB2_SYSDEFS_H
#ifdef HAVE_CONFIG_H
# include <config.h>
@ -18,6 +18,7 @@
#endif
/* these should exist everywhere */
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
@ -55,10 +56,6 @@
# define SNPRINTF_DECLARED
# define VSNPRINTF_DECLARED
# define SPRINTF_RETURNS_INT
# define uchar unsigned char
# define ushort unsigned short
# define uint unsigned int
# define ulong unsigned long
# define inline /*Visual C++6.0 can't inline ".c" files*/
# define mode_t int
# endif
@ -67,8 +64,10 @@
# include <direct.h>
# define FOPEN_WANTS_B
# define HAVE_CHSIZE
# define snprintf _snprintf
# define vsnprintf _vsnprintf
# if _MSC_VER < 1900 /* no snprintf until Visual Studio 2015 */
# define snprintf _snprintf
# define vsnprintf _vsnprintf
# endif
#endif
@ -177,6 +176,16 @@
# define SYSTEM_DEFAULT_EOL "\r"
#endif
#if defined(__APPLE__) && defined(__MACH__) /* OS X */
# define MAC_LIKE
# define UNIX_LIKE
#endif
/* not currently using filesystem resource forks */
//#if defined(__ORCAC__) || defined(MAC_LIKE)
//# define HAS_RESOURCE_FORKS
//#endif
#if defined(APW) || defined(__ORCAC__)
# define __appleiigs__
# pragma lint -1
@ -195,10 +204,6 @@
# define HAS__FUNCTION__
#endif
#if defined(__sun__) && !defined(__SVR4)
# include "SunOS4.h"
#endif
/* general defaults, mainly for UNIX */
#ifndef PATH_SEP
@ -211,4 +216,4 @@
# define MAX_PATH_LEN 1024
#endif
#endif /*__SysDefs__*/
#endif /*NULIB2_SYSDEFS_H*/

View File

@ -1,16 +1,19 @@
/*
* Nulib2
* NuLib2
* Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the BSD License, see the file COPYING.
*
* System-dependent utility functions.
*/
#include "Nulib2.h"
#include "NuLib2.h"
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#ifdef MAC_LIKE
# include <sys/xattr.h>
#endif
/* get a grip on this opendir/readdir stuff */
#if defined(UNIX_LIKE)
@ -60,6 +63,7 @@
* ===========================================================================
*/
// 20150103: this makes me nervous
#define kTempFileNameLen 20
@ -71,9 +75,8 @@
* as well just let the filesystem truncate if it gets too long, rather
* than worry about truncating it cleverly.
*/
static NuError
UNIXNormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
char fssep, char** pDstp, long dstLen)
static NuError UNIXNormalizeFileName(NulibState* pState, const char* srcp,
long srcLen, char fssep, char** pDstp, long dstLen)
{
char* dstp = *pDstp;
@ -121,18 +124,17 @@ UNIXNormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
* The list comes from the Linux kernel's fs/msdos/namei.c.
*/
static const char* fatReservedNames3[] = {
"CON", "PRN", "NUL", "AUX", nil
"CON", "PRN", "NUL", "AUX", NULL
};
static const char* fatReservedNames4[] = {
"LPT1", "LPT2", "LPT3", "LPT4", "COM1", "COM2", "COM3", "COM4", nil
"LPT1", "LPT2", "LPT3", "LPT4", "COM1", "COM2", "COM3", "COM4", NULL
};
/*
* Filename normalization for Win32 filesystems. You can't use [ \/:*?"<>| ].
*/
static NuError
Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
char fssep, char** pDstp, long dstLen)
static NuError Win32NormalizeFileName(NulibState* pState, const char* srcp,
long srcLen, char fssep, char** pDstp, long dstLen)
{
char* dstp = *pDstp;
const char* startp = srcp;
@ -142,7 +144,7 @@ Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
if (srcLen >= 3) {
const char** ppcch;
for (ppcch = fatReservedNames3; *ppcch != nil; ppcch++) {
for (ppcch = fatReservedNames3; *ppcch != NULL; ppcch++) {
if (strncasecmp(srcp, *ppcch, 3) == 0 &&
srcp[3] == '.' || srcLen == 3)
{
@ -160,7 +162,7 @@ Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
if (srcLen >= 4) {
const char** ppcch;
for (ppcch = fatReservedNames4; *ppcch != nil; ppcch++) {
for (ppcch = fatReservedNames4; *ppcch != NULL; ppcch++) {
if (strncasecmp(srcp, *ppcch, 4) == 0 &&
srcp[4] == '.' || srcLen == 4)
{
@ -185,7 +187,7 @@ Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
if (NState_GetModPreserveType(pState))
*dstp++ = *srcp;
*dstp++ = *srcp++;
} else if (strchr(kInvalid, *srcp) != nil) {
} else if (strchr(kInvalid, *srcp) != NULL) {
/* change invalid char to "%2f" or '_' */
if (NState_GetModPreserveType(pState)) {
*dstp++ = kForeignIndic;
@ -219,17 +221,16 @@ Win32NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
*
* The output buffer must be able to hold 3x the original string length.
*/
NuError
NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
NuError NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
char fssep, char** pDstp, long dstLen)
{
NuError err;
Assert(srcp != nil);
Assert(srcp != NULL);
Assert(srcLen > 0);
Assert(dstLen > srcLen);
Assert(pDstp != nil);
Assert(*pDstp != nil);
Assert(pDstp != NULL);
Assert(*pDstp != NULL);
Assert(fssep > ' ' && fssep < 0x7f);
#if defined(UNIX_LIKE)
@ -247,9 +248,8 @@ NormalizeFileName(NulibState* pState, const char* srcp, long srcLen,
/*
* Normalize a directory name to local filesystem conventions.
*/
NuError
NormalizeDirectoryName(NulibState* pState, const char* srcp, long srcLen,
char fssep, char** pDstp, long dstLen)
NuError NormalizeDirectoryName(NulibState* pState, const char* srcp,
long srcLen, char fssep, char** pDstp, long dstLen)
{
/* in general, directories and filenames are the same */
return NormalizeFileName(pState, srcp, srcLen, fssep, pDstp, dstLen);
@ -265,19 +265,18 @@ NormalizeDirectoryName(NulibState* pState, const char* srcp, long srcLen,
* under GS/OS it has to be in the same directory. Not sure what Mac OS
* or Windows requires, so it's safest to just put it in the same dir.
*/
char*
MakeTempArchiveName(NulibState* pState)
char* MakeTempArchiveName(NulibState* pState)
{
const char* archivePathname;
char fssep;
const char* nameStart;
char* newName = nil;
char* newName = NULL;
char* namePtr;
char* resultName = nil;
char* resultName = NULL;
long len;
archivePathname = NState_GetArchiveFilename(pState);
Assert(archivePathname != nil);
Assert(archivePathname != NULL);
fssep = NState_GetSystemPathSeparator(pState);
Assert(fssep != 0);
@ -292,7 +291,7 @@ MakeTempArchiveName(NulibState* pState)
/* figure out where the filename ends */
nameStart = strrchr(archivePathname, fssep);
if (nameStart == nil) {
if (nameStart == NULL) {
/* nothing but a filename */
newName = Malloc(kTempFileNameLen +1);
namePtr = newName;
@ -302,7 +301,7 @@ MakeTempArchiveName(NulibState* pState)
strcpy(newName, archivePathname);
namePtr = newName + (nameStart - archivePathname);
}
if (newName == nil)
if (newName == NULL)
goto bail;
/*
@ -313,7 +312,7 @@ MakeTempArchiveName(NulibState* pState)
resultName = newName;
bail:
if (resultName == nil)
if (resultName == NULL)
Free(newName);
return resultName;
}
@ -353,17 +352,16 @@ bail:
*
* [ Someday we may want to modify this to handle symbolic links. ]
*/
NuError
CheckFileStatus(const char* pathname, struct stat* psb, Boolean* pExists,
Boolean* pIsReadable, Boolean* pIsDir)
NuError CheckFileStatus(const char* pathname, struct stat* psb,
Boolean* pExists, Boolean* pIsReadable, Boolean* pIsDir)
{
NuError err = kNuErrNone;
int cc;
Assert(pathname != nil);
Assert(pExists != nil);
Assert(pIsReadable != nil);
Assert(pIsDir != nil);
Assert(pathname != NULL);
Assert(pExists != NULL);
Assert(pIsReadable != NULL);
Assert(pIsDir != NULL);
*pExists = true;
*pIsReadable = true;
@ -398,13 +396,12 @@ bail:
/*
* Convert from time in seconds to DateTime format.
*/
static void
UNIXTimeToDateTime(const time_t* pWhen, NuDateTime *pDateTime)
static void UNIXTimeToDateTime(const time_t* pWhen, NuDateTime *pDateTime)
{
struct tm* ptm;
Assert(pWhen != nil);
Assert(pDateTime != nil);
Assert(pWhen != NULL);
Assert(pDateTime != NULL);
ptm = localtime(pWhen);
pDateTime->second = ptm->tm_sec;
@ -418,13 +415,187 @@ UNIXTimeToDateTime(const time_t* pWhen, NuDateTime *pDateTime)
}
#endif
#if defined(MAC_LIKE)
/*
* Due to historical reasons, the XATTR_FINDERINFO_NAME (defined to be
* ``com.apple.FinderInfo'') extended attribute must be 32 bytes; see the
* ATTR_CMN_FNDRINFO section in getattrlist(2).
*
* The FinderInfo block is the concatenation of a FileInfo structure
* and an ExtendedFileInfo (or ExtendedFolderInfo) structure -- see
* ATTR_CMN_FNDRINFO in getattrlist(2).
*
* All we're really interested in is the file type and creator code,
* which are stored big-endian in the first 8 bytes.
*/
static const int kFinderInfoSize = 32;
/*
* Obtains the creator and file type from the Finder info block, if any,
* and converts the types to ProDOS equivalents.
*
* If the attribute doesn't exist, this returns an error without modifying
* the output args.
*/
static NuError GetTypesFromFinder(const char* pathnameUNI, uint32_t* pFileType,
uint32_t* pAuxType)
{
uint8_t fiBuf[kFinderInfoSize];
size_t actual = getxattr(pathnameUNI, XATTR_FINDERINFO_NAME,
fiBuf, sizeof(fiBuf), 0, 0);
if (actual != kFinderInfoSize) {
return kNuErrNotFound;
}
uint32_t fileType, creator;
fileType = (fiBuf[0] << 24) | (fiBuf[1] << 16) | (fiBuf[2] << 8) |
fiBuf[3];
creator = (fiBuf[4] << 24) | (fiBuf[5] << 16) | (fiBuf[6] << 8) |
fiBuf[7];
Boolean found = false;
uint8_t proType;
uint16_t proAux;
/*
* Convert to ProDOS file/aux type.
*/
if (creator == 'pdos') {
/*
* TODO: handle conversion from 'pdos'/'XY ' to $XY/$0000.
* I think this conversion was deprecated and not widely used;
* the inability to retain the aux type renders it inapplicable
* to many files.
*/
if (fileType == 'PSYS') {
proType = 0xFF; // SYS
proAux = 0x0000;
found = true;
} else if (fileType == 'PS16') {
proType = 0xB3; // S16
proAux = 0x0000;
found = true;
} else {
if (((fileType >> 24) & 0xFF) == 'p') {
proType = (fileType >> 16) & 0xFF;
proAux = (uint16_t) fileType;
found = true;
}
}
} else if (creator == 'dCpy') {
if (fileType == 'dImg') {
proType = 0xE0; // LBR
proAux = 0x0005;
found = true;
}
}
if (!found) {
switch (fileType) {
case 'BINA':
proType = 0x06; // BIN
proAux = 0x0000;
break;
case 'TEXT':
proType = 0x04; // TXT
proAux = 0x0000;
break;
case 'MIDI':
proType = 0xD7; // MDI
proAux = 0x0000;
break;
case 'AIFF':
proType = 0xD8; // SND
proAux = 0x0000;
break;
case 'AIFC':
proType = 0xD8; // SND
proAux = 0x0001;
break;
default:
proType = 0x00; // NON
proAux = 0x0000;
break;
}
}
*pFileType = proType;
*pAuxType = proAux;
return kNuErrNone;
}
/*
* Set the file type and creator type, based on the ProDOS file type
* and aux type.
*
* This is a clone of the function in NufxLib; it exists for the
* benefit of the Binary ][ code.
*/
NuError SetFinderInfo(int fd, uint8_t proType, uint16_t proAux)
{
uint8_t fiBuf[kFinderInfoSize];
size_t actual = fgetxattr(fd, XATTR_FINDERINFO_NAME,
fiBuf, sizeof(fiBuf), 0, 0);
if (actual == (size_t) -1 && errno == ENOATTR) {
// doesn't yet have Finder info
memset(fiBuf, 0, sizeof(fiBuf));
} else if (actual != kFinderInfoSize) {
return kNuErrFile;
}
/*
* Attempt to use one of the convenience types. If nothing matches,
* use the generic pdos/pXYZ approach. Note that PSYS/PS16 will
* lose the file's aux type.
*
* I'm told this is from page 336 of _Programmer's Reference for
* System 6.0_.
*/
uint8_t* fileTypeBuf = fiBuf;
uint8_t* creatorBuf = fiBuf + 4;
memcpy(creatorBuf, "pdos", 4);
if (proType == 0x00 && proAux == 0x0000) {
memcpy(fileTypeBuf, "BINA", 4);
} else if (proType == 0x04 && proAux == 0x0000) {
memcpy(fileTypeBuf, "TEXT", 4);
} else if (proType == 0xff) {
memcpy(fileTypeBuf, "PSYS", 4);
} else if (proType == 0xb3 && (proAux & 0xff00) != 0xdb00) {
memcpy(fileTypeBuf, "PS16", 4);
} else if (proType == 0xd7 && proAux == 0x0000) {
memcpy(fileTypeBuf, "MIDI", 4);
} else if (proType == 0xd8 && proAux == 0x0000) {
memcpy(fileTypeBuf, "AIFF", 4);
} else if (proType == 0xd8 && proAux == 0x0001) {
memcpy(fileTypeBuf, "AIFC", 4);
} else if (proType == 0xe0 && proAux == 0x0005) {
memcpy(creatorBuf, "dCpy", 4);
memcpy(fileTypeBuf, "dImg", 4);
} else {
fileTypeBuf[0] = 'p';
fileTypeBuf[1] = proType;
fileTypeBuf[2] = (uint8_t) (proAux >> 8);
fileTypeBuf[3] = (uint8_t) proAux;
}
if (fsetxattr(fd, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf),
0, 0) != 0)
{
return kNuErrFile;
}
return kNuErrNone;
}
#endif /*MAC_LIKE*/
#if defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
/*
* Replace "oldc" with "newc". If we find an instance of "newc" already
* in the string, replace it with "newSubst".
*/
static void
ReplaceFssep(char* str, char oldc, char newc, char newSubst)
static void ReplaceFssep(char* str, char oldc, char newc, char newSubst)
{
while (*str != '\0') {
if (*str == oldc)
@ -439,9 +610,8 @@ ReplaceFssep(char* str, char oldc, char newc, char newSubst)
* Set the contents of a NuFileDetails structure, based on the pathname
* and characteristics of the file.
*/
static NuError
GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
NuFileDetails* pDetails)
static NuError GetFileDetails(NulibState* pState, const char* pathnameMOR,
struct stat* psb, NuFileDetails* pDetails)
{
Boolean wasPreserved;
Boolean doJunk = false;
@ -450,15 +620,15 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
char slashDotDotSlash[5] = "_.._";
time_t now;
Assert(pState != nil);
Assert(pathname != nil);
Assert(pDetails != nil);
Assert(pState != NULL);
Assert(pathnameMOR != NULL);
Assert(pDetails != NULL);
/* set up the pathname buffer; note pDetails->storageName is const */
NState_SetTempPathnameLen(pState, strlen(pathname) +1);
NState_SetTempPathnameLen(pState, strlen(pathnameMOR) +1);
livePathStr = NState_GetTempPathnameBuf(pState);
Assert(livePathStr != nil);
strcpy(livePathStr, pathname);
Assert(livePathStr != NULL);
strcpy(livePathStr, pathnameMOR);
/* under Win32, both '/' and '\' work... we want to settle on one */
if (NState_GetAltSystemPathSeparator(pState) != '\0') {
@ -471,8 +641,8 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
/* init to defaults */
memset(pDetails, 0, sizeof(*pDetails));
pDetails->threadID = kNuThreadIDDataFork;
pDetails->storageName = livePathStr; /* point at temp buffer */
pDetails->origName = nil;
pDetails->storageNameMOR = livePathStr; /* point at temp buffer */
pDetails->origName = NULL;
pDetails->fileSysID = kNuFileSysUnknown;
pDetails->fileSysInfo = kStorageFssep;
pDetails->fileType = 0;
@ -497,11 +667,20 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
}
}
now = time(nil);
now = time(NULL);
UNIXTimeToDateTime(&now, &pDetails->archiveWhen);
UNIXTimeToDateTime(&psb->st_mtime, &pDetails->modWhen);
UNIXTimeToDateTime(&psb->st_mtime, &pDetails->createWhen);
#ifdef MAC_LIKE
/*
* Retrieve the file/aux type from the Finder info. We want the
* type-preservation string to take priority, so get this first.
*/
(void) GetTypesFromFinder(livePathStr,
&pDetails->fileType, &pDetails->extraType);
#endif
/*
* Check for file type preservation info in the filename. If present,
* set the file type values and truncate the filename.
@ -576,7 +755,7 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
slashDotDotSlash[0] = NState_GetSystemPathSeparator(pState);
slashDotDotSlash[3] = NState_GetSystemPathSeparator(pState);
if ((livePathStr[0] == '.' && livePathStr[1] == '.') ||
(strstr(livePathStr, slashDotDotSlash) != nil))
(strstr(livePathStr, slashDotDotSlash) != NULL))
{
DBUG(("Found dot dot in '%s', keeping only filename\n", livePathStr));
doJunk = true;
@ -595,7 +774,7 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
if (NState_GetModJunkPaths(pState) || doJunk) {
char* lastFssep;
lastFssep = strrchr(livePathStr, NState_GetSystemPathSeparator(pState));
if (lastFssep != nil) {
if (lastFssep != NULL) {
Assert(*(lastFssep+1) != '\0'); /* should already have been caught*/
memmove(livePathStr, lastFssep+1, strlen(lastFssep+1)+1);
}
@ -621,9 +800,8 @@ GetFileDetails(NulibState* pState, const char* pathname, struct stat* psb,
* Do the system-independent part of the file add, including things like
* adding comments.
*/
NuError
DoAddFile(NulibState* pState, NuArchive* pArchive, const char* pathname,
const NuFileDetails* pDetails)
static NuError DoAddFile(NulibState* pState, NuArchive* pArchive,
const char* pathname, const NuFileDetails* pDetails)
{
NuError err;
NuRecordIdx recordIdx = 0;
@ -665,26 +843,26 @@ DoAddFile(NulibState* pState, NuArchive* pArchive, const char* pathname,
DBUG(("Preparing comment for recordIdx=%ld\n", recordIdx));
Assert(recordIdx != 0);
comment = GetSimpleComment(pState, pathname, kDefaultCommentLen);
if (comment != nil) {
if (comment != NULL) {
NuDataSource* pDataSource;
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
kDefaultCommentLen, (unsigned char*)comment, 0,
kDefaultCommentLen, (uint8_t*)comment, 0,
strlen(comment), FreeCallback, &pDataSource);
if (err != kNuErrNone) {
ReportError(err, "comment buffer create failed");
Free(comment);
err = kNuErrNone; /* oh well */
} else {
comment = nil; /* now owned by the data source */
comment = NULL; /* now owned by the data source */
err = NuAddThread(pArchive, recordIdx, kNuThreadIDComment,
pDataSource, nil);
pDataSource, NULL);
if (err != kNuErrNone) {
ReportError(err, "comment thread add failed");
NuFreeDataSource(pDataSource);
err = kNuErrNone; /* oh well */
} else {
pDataSource = nil; /* now owned by NufxLib */
pDataSource = NULL; /* now owned by NufxLib */
}
}
}
@ -707,24 +885,24 @@ static NuError UNIXAddFile(NulibState* pState, NuArchive* pArchive,
* If a subdirectory is found, follow it; otherwise, call UNIXAddFile to
* add the file.
*/
static NuError
UNIXAddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
static NuError UNIXAddDirectory(NulibState* pState, NuArchive* pArchive,
const char* dirName)
{
NuError err = kNuErrNone;
DIR* dirp = nil;
DIR* dirp = NULL;
DIR_TYPE* entry;
char nbuf[MAX_PATH_LEN]; /* malloc might be better; this soaks stack */
char fssep;
int len;
Assert(pState != nil);
Assert(pArchive != nil);
Assert(dirName != nil);
Assert(pState != NULL);
Assert(pArchive != NULL);
Assert(dirName != NULL);
DBUG(("+++ DESCEND: '%s'\n", dirName));
dirp = opendir(dirName);
if (dirp == nil) {
if (dirp == NULL) {
if (errno == ENOTDIR)
err = kNuErrNotDir;
else
@ -736,7 +914,7 @@ UNIXAddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
fssep = NState_GetSystemPathSeparator(pState);
/* could use readdir_r, but we don't care about reentrancy here */
while ((entry = readdir(dirp)) != nil) {
while ((entry = readdir(dirp)) != NULL) {
/* skip the dotsies */
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
@ -761,7 +939,7 @@ UNIXAddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
}
bail:
if (dirp != nil)
if (dirp != NULL)
(void)closedir(dirp);
return err;
}
@ -775,17 +953,17 @@ bail:
*
* Returns with an error if the file doesn't exist or isn't readable.
*/
static NuError
UNIXAddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
static NuError UNIXAddFile(NulibState* pState, NuArchive* pArchive,
const char* pathname)
{
NuError err = kNuErrNone;
Boolean exists, isDir, isReadable;
NuFileDetails details;
struct stat sb;
Assert(pState != nil);
Assert(pArchive != nil);
Assert(pathname != nil);
Assert(pState != NULL);
Assert(pArchive != NULL);
Assert(pathname != NULL);
err = CheckFileStatus(pathname, &sb, &exists, &isReadable, &isDir);
if (err != kNuErrNone) {
@ -848,17 +1026,16 @@ static const char* kWildMatchAll = "*.*";
/*
* Prepare a directory for reading.
*/
static Win32dirent*
OpenDir(const char* name)
static Win32dirent* OpenDir(const char* name)
{
Win32dirent* dir = nil;
char* tmpStr = nil;
Win32dirent* dir = NULL;
char* tmpStr = NULL;
char* cp;
WIN32_FIND_DATA fnd;
dir = Malloc(sizeof(*dir));
tmpStr = Malloc(strlen(name) + (2 + sizeof(kWildMatchAll)));
if (dir == nil || tmpStr == nil)
if (dir == NULL || tmpStr == NULL)
goto failed;
strcpy(tmpStr, name);
@ -878,7 +1055,7 @@ OpenDir(const char* name)
goto failed;
strcpy(dir->d_name, fnd.cFileName);
dir->d_attr = (uchar) fnd.dwFileAttributes;
dir->d_attr = (uint8_t) fnd.dwFileAttributes;
dir->d_first = 1;
bail:
@ -887,17 +1064,16 @@ bail:
failed:
Free(dir);
dir = nil;
dir = NULL;
goto bail;
}
/*
* Get an entry from an open directory.
*
* Returns a nil pointer after the last entry has been read.
* Returns a NULL pointer after the last entry has been read.
*/
static Win32dirent*
ReadDir(Win32dirent* dir)
static Win32dirent* ReadDir(Win32dirent* dir)
{
if (dir->d_first)
dir->d_first = 0;
@ -905,9 +1081,9 @@ ReadDir(Win32dirent* dir)
WIN32_FIND_DATA fnd;
if (!FindNextFile(dir->d_hFindFile, &fnd))
return nil;
return NULL;
strcpy(dir->d_name, fnd.cFileName);
dir->d_attr = (uchar) fnd.dwFileAttributes;
dir->d_attr = (uint8_t) fnd.dwFileAttributes;
}
return dir;
@ -916,10 +1092,9 @@ ReadDir(Win32dirent* dir)
/*
* Close a directory.
*/
static void
CloseDir(Win32dirent* dir)
static void CloseDir(Win32dirent* dir)
{
if (dir == nil)
if (dir == NULL)
return;
FindClose(dir->d_hFindFile);
@ -939,24 +1114,24 @@ static NuError Win32AddFile(NulibState* pState, NuArchive* pArchive,
* If a subdirectory is found, follow it; otherwise, call Win32AddFile to
* add the file.
*/
static NuError
Win32AddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
static NuError Win32AddDirectory(NulibState* pState, NuArchive* pArchive,
const char* dirName)
{
NuError err = kNuErrNone;
Win32dirent* dirp = nil;
Win32dirent* dirp = NULL;
Win32dirent* entry;
char nbuf[MAX_PATH_LEN]; /* malloc might be better; this soaks stack */
char fssep;
int len;
Assert(pState != nil);
Assert(pArchive != nil);
Assert(dirName != nil);
Assert(pState != NULL);
Assert(pArchive != NULL);
Assert(dirName != NULL);
DBUG(("+++ DESCEND: '%s'\n", dirName));
dirp = OpenDir(dirName);
if (dirp == nil) {
if (dirp == NULL) {
if (errno == ENOTDIR)
err = kNuErrNotDir;
else
@ -968,7 +1143,7 @@ Win32AddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
fssep = NState_GetSystemPathSeparator(pState);
/* could use readdir_r, but we don't care about reentrancy here */
while ((entry = ReadDir(dirp)) != nil) {
while ((entry = ReadDir(dirp)) != NULL) {
/* skip the dotsies */
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
@ -993,7 +1168,7 @@ Win32AddDirectory(NulibState* pState, NuArchive* pArchive, const char* dirName)
}
bail:
if (dirp != nil)
if (dirp != NULL)
(void)CloseDir(dirp);
return err;
}
@ -1005,17 +1180,17 @@ bail:
*
* Returns with an error if the file doesn't exist or isn't readable.
*/
static NuError
Win32AddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
static NuError Win32AddFile(NulibState* pState, NuArchive* pArchive,
const char* pathname)
{
NuError err = kNuErrNone;
Boolean exists, isDir, isReadable;
NuFileDetails details;
struct stat sb;
Assert(pState != nil);
Assert(pArchive != nil);
Assert(pathname != nil);
Assert(pState != NULL);
Assert(pArchive != NULL);
Assert(pathname != NULL);
err = CheckFileStatus(pathname, &sb, &exists, &isReadable, &isDir);
if (err != kNuErrNone) {
@ -1071,13 +1246,12 @@ bail_quiet:
*
* [ I figure the GS/OS version will want to pass a copy of the file
* info from the GSOSAddDirectory function back into GSOSAddFile, so we'd
* want to call it from here with a nil pointer indicating that we
* want to call it from here with a NULL pointer indicating that we
* don't yet have the file info. That way we can get the file info
* from the directory read call and won't have to check it again in
* GSOSAddFile. ]
*/
NuError
AddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
NuError AddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
{
#if defined(UNIX_LIKE)
return UNIXAddFile(pState, pArchive, pathname);
@ -1094,12 +1268,11 @@ AddFile(NulibState* pState, NuArchive* pArchive, const char* pathname)
*
* Currently only used by Binary2.c.
*/
NuError
Mkdir(const char* dir)
NuError Mkdir(const char* dir)
{
NuError err = kNuErrNone;
Assert(dir != nil);
Assert(dir != NULL);
#if defined(UNIX_LIKE)
if (mkdir(dir, S_IRWXU | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH) < 0) {
@ -1126,12 +1299,11 @@ bail:
*
* Currently only used by Binary2.c.
*/
NuError
TestFileExistence(const char* fileName, Boolean* pIsDir)
NuError TestFileExistence(const char* fileName, Boolean* pIsDir)
{
NuError err = kNuErrNone;
Assert(fileName != nil);
Assert(pIsDir != nil);
Assert(fileName != NULL);
Assert(pIsDir != NULL);
#if defined(UNIX_LIKE) || defined(WINDOWS_LIKE)
{
@ -1160,4 +1332,3 @@ bail:
return err;
}

1456
nulib2/config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -33,18 +33,6 @@
/* Define if your <sys/time.h> declares struct tm. */
#undef TM_IN_SYS_TIME
/* Define to `unsigned char' if <sys/types.h> doesn't define. */
#undef uchar
/* Define to `unsigned short' if <sys/types.h> doesn't define. */
#undef ushort
/* Define to `unsigned int' if <sys/types.h> doesn't define. */
#undef uint
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
#undef ulong
/* Define to `int' if <sys/types.h> doesn't define. */
#undef mode_t

2785
nulib2/config.sub vendored

File diff suppressed because it is too large Load Diff

50
nulib2/configure vendored
View File

@ -4001,50 +4001,6 @@ $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
fi
ac_fn_c_check_type "$LINENO" "uchar" "ac_cv_type_uchar" "$ac_includes_default"
if test "x$ac_cv_type_uchar" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define uchar unsigned char
_ACEOF
fi
ac_fn_c_check_type "$LINENO" "ushort" "ac_cv_type_ushort" "$ac_includes_default"
if test "x$ac_cv_type_ushort" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define ushort unsigned short
_ACEOF
fi
ac_fn_c_check_type "$LINENO" "uint" "ac_cv_type_uint" "$ac_includes_default"
if test "x$ac_cv_type_uint" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define uint unsigned int
_ACEOF
fi
ac_fn_c_check_type "$LINENO" "ulong" "ac_cv_type_ulong" "$ac_includes_default"
if test "x$ac_cv_type_ulong" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define ulong unsigned long
_ACEOF
fi
@ -4156,12 +4112,6 @@ if test "$host_os" = "beos"; then
fi
fi
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
echo "checking for Mac OS X... yes, adding -framework Carbon"
LIBS="$LIBS -framework Carbon"
fi
if test "$host_cpu" = "powerpc" -a "$host_os" = "beos"; then
CC=cc
GCC=

View File

@ -47,7 +47,7 @@ if test $enable_deflate = "yes"; then
fi
if $got_zlibh; then
echo " (found libz and zlib.h, enabling deflate)"
AC_DEFINE(ENABLE_DEFLATE)
AC_DEFINE(ENABLE_DEFLATE, [], [Define to include deflate (zlib) compresion (also need -l in Makefile).])
else
echo " (couldn't find libz and zlib.h, not enabling deflate)"
fi
@ -67,7 +67,7 @@ if test $enable_bzip2 = "yes"; then
fi
if $got_bzlibh; then
echo " (found libbz2 and bzlib.h, enabling bzip2)"
AC_DEFINE(ENABLE_BZIP2)
AC_DEFINE(ENABLE_BZIP2, [], [Define to include bzip2 (libbz2) compression (also need -l in Makefile).])
else
echo " (couldn't find libbz2 and bzlib.h, not enabling bzip2)"
fi
@ -79,10 +79,6 @@ AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_STRUCT_TM
AC_CHECK_TYPE(uchar, unsigned char)
AC_CHECK_TYPE(ushort, unsigned short)
AC_CHECK_TYPE(uint, unsigned int)
AC_CHECK_TYPE(ulong, unsigned long)
dnl Checks for library functions.
dnl AC_FUNC_SETVBUF_REVERSED
@ -129,13 +125,6 @@ if test "$host_os" = "beos"; then
fi
fi
dnl Mac OS X (powerpc-apple-darwin6.6) needs an extra flag.
if test "$host_vendor" = "apple" -a ${host_os:0:6} = "darwin"; then
echo "checking for Mac OS X... yes, adding -framework Carbon"
LIBS="$LIBS -framework Carbon"
fi
dnl Figure out what the build and link flags should be
if test "$host_cpu" = "powerpc" -a "$host_os" = "beos"; then
dnl BeOS/PPC with Metrowerks compiler
@ -149,6 +138,6 @@ AC_SUBST(BUILD_FLAGS)
AC_ARG_ENABLE(dmalloc, [ --enable-dmalloc do dmalloc stuff], \
[ echo "--- enabling dmalloc";
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC) ])
LIBS="$LIBS -L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC, [], [Define if we want to use the dmalloc library (also need -l in Makefile).]) ])
AC_OUTPUT(Makefile)