A C Adventure: your comments are welcome

S

spinoza1111

[snip]
and this persecution of dissidents and writers like Navia and Schildt
Jacob gets picked on because he's a drama queen.  
Much of what passes for technical programming comment is actually ugly
sexual and racial politics. You clowns hate Navia and Schildt because
they both did something you cannot and this was write a compiler. You
clowns hate Navia because he's apparently a French guy. And it is to
me paradoxical and sad that you young punks now think that to defend
oneself like a man is to be a drama queen.

Jacob's smart, and I admire the fact that he has developed a compiler,
but he confuses technical criticisms and disagreements for personal
attacks and, much like you, writes wild diatribes because someone
dared to disagree with a dearly held position of his.  Hence the title
"drama queen", which has nothing to do with sexuality or
nationality.

I would say that "drama queen" has plenty to do with sexuality. Again,
the irony is that in modern male technical environments, what used to
be known in the 1960s at NASA and IBM as "pushback", standing up
against coworkers and management on a safety or other technical issue,
was NOT labeled with feminizing adjectives such as "prima donna" or
"drama queen".

Being a man reversed its polarity. By the time of the Challenger
disaster (1986) it meant "thinking like a [man]ager and not an
engineer", and, unlike a traditional male ready to get into a
fistfight in a factory if the issue were critical enough, being a
feminized and subordinated "team player".

Navia was brutally attacked by Richard Heathfield who is NOT QUALIFIED
to speak about Navia's work, since Richard Heathfield HAS NOT written
a compiler, and betrays no knowledge of language design independent of
his knowledge of one language. Navia fought back and was bullied,
teased and mocked, not only by Heathfield but by ignorant posters who
are enabled by Heathfield and who read one or two responses from
victims, refuse to identify with the victim because of their own
actual subordination and consequent sexual confusion, and in this
refusal, turn upon the victim.
His book wasn't titled "C: The Complete Reference If You're Writing
For DOS (or Windows after 1989)".

Most programmers write for Windows. I know this irritates the slashdot
crowd. They attacked my editor at Apress, Dan Appleman, a prolific
author on Windows and VB because of the perverted fashion that has
always existed outside IBM and Microsoft: the belief that not being
IBM or Microsoft, IN ITSELF, means one is intelligent: a belief so
Fundamentalist that it betrays ignorance. Dan's a real nice guy as is
Kathy Sierra, and Herb, and this irritates incompetents with serious
personality defects.
His examples had numerous syntax errors and runtime problems that had
nothing to do with platform.  Closing a file and then attempting to
write to it is an error, regardless of platform.  Dereferencing
invalid or null pointers is an error, regardless of platform.  Making
his examples DOS-centric was annoying enough for someone who was
learning C under VAX/VMS, since the student didn't have a clear idea
of where the language ended and the platform-specific extensions
began. But it didn't matter, because the examples were crap anyway. I
didn't know a lot, but I knew basic errors in logic when I saw them.

Unsubstantiated and probably lies, at third hand. Furthermore, any
computer book contains errors. Although Herb's were not as serious as
you here imply, "use every man according to his deserts, and none
should 'scape whipping". Good programmers, in fact, test each and
every code fragment they get in computer books.
What compiler has Schildt written?- Hide quoted text -

Tiny C.

Actual creation here attracts destructive, nihilistic, and Fascistic
hatred here from people who don't create and are for this reason
anxious to destroy people who do. The ability to write also attracts
this Fascistic hatred.
 
S

spinoza1111

...
 > Oh, blow me. I was formatting code beautifully in 1971, using punched
 > bloody cards. What were you doing in 1971?

Oh well, at that time I was formatting beautifully in 1971, using punched
bloody tape.  So, no line numbers at the end...

Lucky you. The Registrar at my uni recommended I get into DEC hardware
and study at the Univ of Illinois in Champaign-Urbana, but I was
chasing this girl, see, and wound up with kids by 1979, wedded to
Cobol. But I was able to get into compilers...on IBM mainframes.

There are Two Cultures in computing. Having been in both, I find that
the most intolerant people are on the DEC/C/Web/Java/unix side, not
the IBM or Microsoft side. They've created an urban legend that they
are Luke Skywalker fighting Evil, and it's hooey.
 
S

spinoza1111

spinoza1111said:



I commend this strategy to you.

Inviting people to go **** themselves is venial. Posting false claims
about their competence in a medium available to their employers is
mortal. I am past caring since I'm employable in many fields, but I
don't know whether Navia, Schildt, or your other victims are. You are
a vicious twat who likes to sit on his undoubtedly fat ass sniping at
people instead of coding, and as far as I'm concerned, foul language
actually clears the air.
 
S

spinoza1111

The code you posted had three uses of ERRORHANDLER.  Two had a
trailing semicolon.  The fact that you can't follow the rule you set
yourself is a string argument in favour of avoiding the need for it.

I have switched over to the Bacarisse Backwards rule although it gives
one a *frisson* since one has to realize that you're just kidding
about the while, and that the code is executed once. I agree that
macro calls should have final semicolons.

Here is the code as of today, Tue 18 Aug. I spent both of my 30 mn
commutes making improvements and desk checking before I submit it for
a compile again, so there will be errors, in all probability. And
after it compiles the first time, I need to instrument it with
routines to display the rope and inspect it for errors.

// ***************************************************************
// * *
// * Rope implementation *
// * *
// * This program implements strings, called ropes, which can *
// * contain any character and can be of any length.
*
// * *
// * This code is best viewed using a monospace font such as *
// * Courier New, in a line length of 67 characters. *
// * *
// * The rest of this header addresses these topics: *
// * *
// * *
// * * The "rope" as represented in this code *
// * * Configuring this code for testing *
// * *
// * *
// * Note that the contributions of the following people are *
// * acknowledged: *
// * *
// * *
// * * Ben Bacarisse *
// * * Richard Heathfield *
// * *
// * *
// * THE "ROPE" AS REPRESENTED IN THIS CODE -------------------- *
// * *
// * The rope is defined as the binary tree of its nodes, where *
// * each node points to up to SEGMENT_MAX_LENGTH characters of *
// * the string. Each node of the binary tree contains: *
// * *
// * *
// * * A pointer to the start of the segment *
// * *
// * * The node type: *
// * *
// * + ENUnodeType.child indicates that the node is a *
// * child node of another node.
*
// * *
// * + ENUnodeType.ancestor indicates that the node is *
// * not a child of another node *
// * *
// * * The node length type: *
// * *
// * + ENUnodeLengthType.known indicates that the length *
// * (of the ancestor's complete string or the child *
// * subtree's substring) is known *
// * *
// * + ENUnodeLengthType.tooLarge indicates that the *
// * length exceeds the maximum value and is unknown. *
// * *
// * By default, this maximum value is 2^63-1, the *
// * maximum length of an unsigned "long long" less a *
// * margin to allow for testing the length. The *
// * maximum value, however, can be set to smaller *
// * values for testing. *
// * *
// * * The 64 bit unsigned string length. Note that this *
// * value may be unusable because the length may exceed *
// * the max value: here the node length type will be *
// * ENUnodeLengthType.unknown. *
// * *
// * * The start index of the rope segment (substring) *
// * within the full string; note that in rare cases this*
// * is unknown when the string is longer than 2^64-1 *
// * characters, and the segment is located on the right *
// * of the string, this value may also be unknown. Here *
// * it is set to -1. *
// * *
// * * The length of the rope segment (substring) *
// * *
// * * The address of the parent of the node or NULL *
// * *
// * * The address of the left child of the node (holding *
// * characters to the left of the segment) or NULL *
// * *
// * * The address of the right child of the node (holding *
// * characters to the right of the segment) or NULL *
// * *
// * *
// * CONFIGURING THIS CODE FOR TESTING ------------------------- *
// * *
// * The following symbols may be set to configure a test of this*
// * code. *
// * *
// * *
// * * SEGMENT_MAX_LENGTH: maximum length of a rope string *
// * segment *
// * *
// * * STRING_MAX_RECORDABLE_LENGTH: maximum recordable *
// * length of a string, beyond which the string length *
// * is officially "unknown". *
// * *
// * To test strings whose lengths are not known without *
// * having to generate oodlemegaterabytes of data, this *
// * value can be set to a small value. For actual use, a*
// * recommended value is 2^63-1. *
// * *
// * *
// * C H A N G E R E C O R D --------------------------------- *
// * DATE PROGRAMMER DESCRIPTION OF CHANGE *
// * -------- ---------- --------------------------------- *
// * 08 14 09 Nilges Started version 1 *
// * *
// * 08 18 09 Nilges 1. Revised implementation of *
// * statement macros per *
// * Bacarisse *
// * 2. Using typedef instead of *
// * #define per Heathfield *
// * 3. Using typename in cast in *
// * place of length per Heathfield*
// * *
// * I S S U E S ----------------------------------------------- *
// * DATE POSTER DESCRIPTION AND RESOLUTION *
// * -------- ---------- --------------------------------- *
// * 08 18 09 Nilges To be implemented: rope names and *
// * Dewey decimal numbers of rope *
// * nodes. Routines for inspection and*
// * display of ropes. Code *
// * instrumentation of debug displays.*
// * *
// * 08 14 09 Nilges To be implemented: use extra *
// * precision arithmetic for unbounded*
// * strings, representing big nums as *
// * big strings but in a big base such*
// * as 256 for chars & 32768 for *
// * wchars. *
// * *
// * *
// * ----------------------------------------------------------- *
// * *
// * The scientific industry has its exact counterpart in the *
// * kind of minds it harnesses: they no longer need to do *
// * themselves any violence in becoming their own voluntary and *
// * zealous overseers. Even if they show themselves, outside *
// * their official capacity, to be quite human and sensible *
// * being, they are paralysed by pathic stupidity the moment *
// * they begin to think professionally. *
// * *
// * - T. W. Adorno, Minima Moralia, 1948 *
// * *
// * *
// ***************************************************************

// ***** Standard includes ***************************************

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <stddef.h>

// ***** Configuration *******************************************

#define SEGMENT_MAX_LENGTH 32
#define STRING_MAX_RECORDABLE_LENGTH 1024 // Set to 2^63-1 for
// actual use
#define UNKNOWN_START_INDEX -1

// ***** Macros **************************************************
// * *
// * Macros are of two types: *
// * *
// * *
// * * Statement macros can be used anywhere a C statement *
// * is valid. They are surrounded by curly braces, prefixed*
// * with do, and suffixed with while(0). When used, *
// * statement macros must be followed with a semicolon. *
// * Their names are suffixed with _STMT. *
// * *
// * This is the Bacarisse Backward method, since you need *
// * to look at the while and then go backward to realize *
// * that the body of the macro definition will be executed *
// * once. *
// * *
// * * Expression macros can be used anywhere a C expression *
// * is valid. Their definitions are surrounded by round *
// * parentheses. Their names are suffixed with _EXP. *
// * *
// * *
// ***************************************************************
// --- Statement macro to handle errors
#define ERRORHANDLER_STMT(strMessage) \
do { \
printf("%s\n", (strMessage)); abort(); \
} while(0)

// --- Expression macro to return smaller value
#define MIN_EXP(value1, value2) \
( (value1) < (value2) ? (value1) : (value2) )

// --- Expression macro to perform malloc
#define MALLOC_EXP(typeName) \
( (typeName)(malloc(sizeof(typeName))) )

// --- Statement macros to perform malloc with error checking
// Allocate using a type
#define MALLOCTYPE_STMT(ptr, mallocType, mallocPurpose)
do { \
MALLOCSIZE_STMT(ptr, \
mallocType, \
sizeof(mallocType), \
mallocPurpose); \
} \
} while(0)
// Allocate using a size
#define MALLOCSIZE_STMT(ptr, \
mallocType, \
mallocSize, \
mallocPurpose)
do { \
if (((ptr) = MALLOC_EXP(mallocType) == NULL)) \
{ \
printf \
("Can't get %d bytes of storage\n", mallocSize); \
printf \
("Trying to allocate type %s\n", (mallocType)); \
printf \
("My purpose was: %s...sorry it didn't work out\n",
(mallocPurpose)); \
ERRORHANDLER_STMT("Malloc failed"); \
} \
} while(0)

// ***** Rope definition *****************************************

enum ENUnodeType { child, ancestor };

enum ENUnodeLengthType
{
known, tooLarge
};

typedef struct TYPropeNode ROPE;
typedef ROPE * Rope;

struct TYPropeNode
{
enum ENUnodeType enuNodeType;
enum ENUnodeLengthType enuNodeLengthType;
char * ptrNodeCharacters;
unsigned long long ulngStringLength;
unsigned long long lngSegmentStartIndex;
unsigned int uintSegmentLength;
Rope ptrParent;
Rope ptrLeft;
Rope ptrRight;
};

// ***** Procedures **********************************************

// ---------------------------------------------------------------
// Create a rope node
//
//
Rope mkRopeNode
(char * ptrNodeCharacters,
long long lngSegmentStartIndex,
unsigned int uintSegmentLength,
Rope ptrParent,
Rope ptrLeft,
Rope ptrRight)
{
Rope ptrNewNode;
(*ptrNewNode).ptrNodeCharacters = ptrNodeCharacters;
(*ptrNewNode).enuNodeType =
ptrParent == NULL
?
ENUnodeType.ancestor
:
ENUnodeType.child;
(*ptrNewNode).lngSegmentStartIndex = lngSegmentStartIndex;
(*ptrNewNode).uintSegmentLength = uintSegmentLength;
(*ptrNewNode).ptrParent = ptrParent;
(*ptrNewNode).ptrLeft = ptrLeft;
(*ptrNewNode).ptrRight = ptrRight;
(*ptrNewNode).ulngStringLength =
ulngSegmentLength
+
(ptrLeft != NULL ? (*ptrLeft).ulngStringLength : 0)
+
(ptrRight != NULL ? (*ptrRight).ulngStringLength : 0);
return ptrNewNode;
}

// ---------------------------------------------------------------
// Make rope
//
//
Rope mkRope
(Rope ptrParent,
char * ptrSourceChars,
long long lngStartIndex,
unsigned long long ulngStringLength)
{
Rope ptrLeft = NULL;
Rope ptrRight = NULL;
unsigned int uintNodes;
unsigned int uintDoubleSegmentLength;
if (uintStringLength <= SEGMENT_MAX_LENGTH)
uintNodes = 1;
else
{
if (ulngStringLength
<=
(uintDoubleSegmentLength = SEGMENT_MAX_LENGTH << 1))
uintNodes = 2;
else
uintNodes = 3;
}
Rope ptrRopeNode =
mkRopeNode
(// ----- Pointer to source chars -----------------------
(uintNodes > 1
?
ptrSourceChars + SEGMENT_MAX_LENGTH
:
ptrSourceChars),
// ----- Parent segment start index --------------------
(mkRope_calcStartIndex
(lngStartIndex,
uintNodes > 1 ? SEGMENT_MAX_LENGTH : 0)),
// ----- Parent segment length (screw you Heathfield) --
(uintNodes > 1
?
MIN_EXP((uintSegmentLength - SEGMENT_MAX_LENGTH),
(uintSegmentLength))
:
uintSegmentLength),
// ----- Parent's own parent or null -------------------
ptrParent,
// ----- Left child node exists when segments > 1 ------
(uintNodes > 1
?
(ptrLeft = mkRopeNode
(ptrSourceChars,
lngStartIndex,
SEGMENT_MAX_LENGTH,
NULL, NULL, NULL))
:
NULL),
// ----- Right child node exists when segments > 1 ----
(uintNodes > 2
?
(ptrRight = mkRope
(NULL,
ptrSourceChars
+
uintDoubleSegmentLength,
mkRope_calcStartIndex
(lngStartIndex, uintDoubleSegmentLength),
uintSegmentLength
-
uintDoubleSegmentLength))
:
NULL);
if (ptrRopeNode != NULL)
{
(*ptrRopeNode).ptrLeft = ptrLeft;
(*ptrRopeNode).ptrRight = ptrRight;
if (ptrLeft != NULL)
(*((*ptrRopeNode).ptrLeft)).ptrParent =
ptrRopeNode;
if (ptrRight != NULL)
(*((*ptrRopeNode).ptrRight)).ptrParent =
ptrRopeNode;
(*ptrRopeNode).ulngStringLength =
ulngStringLength;
}
return ptrRopeNode;
}

// ---------------------------------------------------------------
// Calculate next start index on behalf of mkRope()
//
//
long long mkRope_calcStartIndex(long long lngOld,
unsigned int uintOffset)
{
if (lngOld == UNKNOWN_START_INDEX)
return UNKNOWN_START_INDEX;
unsigned long long ulngNew = lngOld + uintOffset;
if (ulngNew <= STRING_MAX_RECORDABLE_LENGTH)
return (long long)ulngNew;
return UNKNOWN_START_INDEX;
}

int main()
{
printf("Unlimited strings in basic C");
// ***** Insert test code *****
return 0;
}
 
S

spinoza1111

spinoza1111said:



It is, however, incivil, and betrays a lack of imagination on the part
of the author.

Oh, I think I've established that I have a lot of imagination, dear
boy. I can insult you in iambic pentameters, and I can call you on
your bullshit in limericks, so I'm not worried 'bout any lack of
creativity on my part. In fact, I feel my muse right now...

There is a Limey creep named Dickie
Who pretends about code to be picky
But no code does he post
He's scared it we'll roast
That cowardly Briton, named Dickie.

Or would you prefer a more Shakespearean style?

You cannot code nor can you write, oh toad:
Perjurious wight, of thee I'll indite this day,
Thou hast not learning thou hast not learning's savor,
Which is gentle wit, without which man is a shit,
A beast and not a man, baying chansons to the wand'ring moon.
Thou'rt clerk, thou'rt a jerk, thou mars our work
Get thee below lest we split in twain,
And give our souls unto the billowing main.
How do you feel about true claims?

If made with malice, they are an invasion of privacy and add to your
libelous conduct.
 
T

Tom St Denis

Invisible tabs in the Microsoft C++ code editor, which I'm using to
edit this code, cause occasional problems in formatting. Competent and
well-intentioned programmers will easily spot these and repair them if
they wish to download this code (which I am checking prior to
compiling, and getting rid of compiler bugs).

Why isn't this code just in a CVS so you can properly version control
it?

Where is your test code?

Why not package it up a bit more maturely with documentation?

:)

Tom
 
N

Nick Keighley

Nick Keighley said:

Step quietly around (), ,, all the arithmetic and logical operators,
and all the assignment operators.

perhaps I should have left the smiley in
 
B

Ben Bacarisse

spinoza1111 said:
// * Note that the contributions of the following people are *
// * acknowledged: *
// * *
// * *
// * * Ben Bacarisse *
// * This is the Bacarisse Backward method, since you need *

I'd be very grateful if you would remove any reference to my name from
the source. Thank you.

<snip code>
It is hard to comment on because we can't assume that any of the
identifiers mean what they seem to mean. At least that is how I read
the conclusion in another thread.
 
J

John Bode

Most programmers write for Windows.

So what? If you're claiming to teach the C language, you could at
least point out in the example code what parts are common to the
language and what parts are specific to the implementation. Otherwise
those non-windows programmers are going to get frustrated and throw
the whole thing in the wastebasket (which is pretty much what happened
with me).

[snip]
Unsubstantiated and probably lies, at third hand.

I had a copy of the first edition while in college and tried to run
the examples. Most of them wouldn't compile because they used DOS-
specific extensions and I was working on VMS, and the ones I could get
to run had numerous logic errors. I showed some of the example code
to my professors, asking if it looked as wrong to them as it did to me
(hey, I was just a student, what did I know), and they agreed that it
was crap.

By contrast, I could always get the examples from K&R or H&S to run
without any problems.
Furthermore, any
computer book contains errors. Although Herb's were not as serious as
you here imply, "use every man according to his deserts, and none
should 'scape whipping". Good programmers, in fact, test each and
every code fragment they get in computer books.





Tiny C.

Interesting. Did not know that.
Actual creation here attracts destructive, nihilistic, and Fascistic
hatred here from people who don't create and are for this reason
anxious to destroy people who do. The ability to write also attracts
this Fascistic hatred.

How, exactly, does the adjective "fascistic" apply here? You sound
like a goddamned birther. Or a drama queen.
 
W

Walter Banks

spinoza1111 said:

Fabrice Bellard wrote Tiny C.

Schildt wrote a interpreter parser for a subset of C called Little C. He is not credited with anything compiler related.

w..
 
S

spinoza1111

John Bode said:



Neither did I, and I still don't. I await independent verification of
the fact. I can see no mention of Schildt's name on the Tiny C Web
site.

I am aware that Schildt /attempted/ to write an /interpreter/ for a
/subset/ of C.

You're scum, Heathfield. It's impossible to write an interpreter
without writing the front end of a compiler. Stop using this newsgroup
to destroy people, you Limey scumbag.
 
S

spinoza1111

spinoza1111said:



It is certainly true that you think so, yes.



If you don't want your "privacy" "invaded", why post it on Usenet?

If I were your father, I'd kick your ass. Schildt has NEVER
participated and you are always attacking him.
 
S

spinoza1111

spinoza1111said:



There are several. Ignoring yet more comment-wrapping, we find, for
example, the following:

#define MALLOCTYPE_STMT(ptr, mallocType, mallocPurpose)
do { \
        MALLOCSIZE_STMT(ptr, \
                                mallocType, \
                                                sizeof(mallocType), \
                                                mallocPurpose); \
    } \

} while(0)

which is missing a linesplice on the first line.

Someone with a conforming C99 implementation (if there is such a
person here) will be able to give you better help.

Can't you read? I told you I was desk-checking this code in
preparation to compile it, and I posted it for intelligent comments.
Either restrict your comments to technical remarks of the sort you are
qualified to make or get out.
 
S

spinoza1111

What are you publishing?

In May 2004 Apress published my book "Build Your Own .Net Language and
Compiler", which describes the building of an interpretive compiler
with demo-only object code generation using VB.Net. This book has
ranked in the top ten compiler books at Apress, despite anti-VB
snobbery on the part of most compiler developers.
 
S

spinoza1111

spinoza1111wrote:


Fabrice Bellard wrote Tiny C.

Schildt wrote a interpreter parser for a subset of C called Little C. He is not credited with anything compiler related.

I stand corrected on the name, but an "interpreter parser" is a
compiler.
 
S

spinoza1111

I'd be very grateful if you would remove any reference to my name from
the source.  Thank you.

Grow up. But I will.
<snip code>
It is hard to comment on because we can't assume that any of the
identifiers mean what they seem to mean.  At least that is how I read
the conclusion in another thread.

Oh, grow up.
 
B

bartc

spinoza1111 said:
... It's impossible to write an interpreter
without writing the front end of a compiler....

It depends on exactly how the interpreter works but in my current project
the compiler and the interpreter are completely separate; one generates
bytecode and the other runs, ie. interprets, the bytecode (and the two are
in different languages).

In a simpler form an interpreter could work directly from source and do
everything in one pass, but that would be difficult when interpreting C.
 
S

spinoza1111

Here is the program, which now compiles with no errors or warnings
using Microsoft C++ .Net Express. The next step is to add functions to
print and inspect ropes, although I do not need heavy instrumentation
since Microsoft C++ Express provides a debugger.

Although I am using a C++ compiler, this code is C. Later on I will
use Navia and another free C compiler to verify that I have not used C+
+ features unintentionally.

I have used Notepad to remove tabs and spaces on the right side of
lines that were disrupting the view of the code here.

Ben B's name has been removed. He is now anon. Ben, are you still
sulking?


// cStringsCPP.cpp : main project file.

#include "stdafx.h"

using namespace System;

// ***************************************************************
// * *
// * Rope implementation *
// * *
// * This program implements strings, called ropes, which can *
// * contain any character and can be of any length. *
// * *
// * This code is best viewed using a monospace font such as *
// * Courier New, in a line length of 67 characters. *
// * *
// * The rest of this header addresses these topics: *
// * *
// * *
// * * The "rope" as represented in this code *
// * * Configuring this code for testing *
// * *
// * *
// * Note that the contributions of the following people are *
// * acknowledged: *
// * *
// * *
// * * Anonymous usenet posters *
// * * Richard Heathfield *
// * *
// * *
// * THE "ROPE" AS REPRESENTED IN THIS CODE -------------------- *
// * *
// * The rope is defined as the binary tree of its nodes, where *
// * each node points to up to SEGMENT_MAX_LENGTH characters of *
// * the string. Each node of the binary Ftree contains: *
// * *
// * *
// * * A pointer to the start of the segment *
// * *
// * * The node type: *
// * *
// * + ENUnodeType.child indicates that the node is a *
// * child node of another node. *
// * *
// * + ENUnodeType.ancestor indicates that the node is *
// * not a child of another node *
// * *
// * * The node length type: *
// * *
// * + ENUnodeLengthType.known indicates that the length *
// * (of the ancestor's complete string or the child *
// * subtree's substring) is known *
// * *
// * + ENUnodeLengthType.tooLarge indicates that the *
// * length exceeds the maximum value and is unknown. *
// * *
// * By default, this maximum value is 2^63-1, the *
// * maximum length of an unsigned "long long" less a *
// * margin to allow for testing the length. The *
// * maximum value, however, can be set to smaller *
// * values for testing. *
// * *
// * * The 64 bit unsigned string length. Note that this *
// * value may be unusable because the length may exceed *
// * the max value: here the node length type will be *
// * ENUnodeLengthType.unknown. *
// * *
// * * The start index of the rope segment (substring) *
// * within the full string; note that in rare cases this*
// * is unknown when the string is longer than 2^64-1 *
// * characters, and the segment is located on the right *
// * of the string, this value may also be unknown. Here *
// * it is set to -1. *
// * *
// * * The length of the rope segment (substring) *
// * *
// * * The address of the parent of the node or NULL *
// * *
// * * The address of the left child of the node (holding *
// * characters to the left of the segment) or NULL *
// * *
// * * The address of the right child of the node (holding *
// * characters to the right of the segment) or NULL *
// * *
// * *
// * CONFIGURING THIS CODE FOR TESTING ------------------------- *
// * *
// * The following symbols may be set to configure a test of this*
// * code. *
// * *
// * *
// * * SEGMENT_MAX_LENGTH: maximum length of a rope string *
// * segment *
// * *
// * * STRING_MAX_RECORDABLE_LENGTH: maximum recordable *
// * length of a string, beyond which the string length *
// * is officially "unknown". *
// * *
// * To test strings whose lengths are not known without *
// * having to generate oodlemegaterabytes of data, this *
// * value can be set to a small value. For actual use, a*
// * recommended value is 2^63-1. *
// * *
// * *
// * C H A N G E R E C O R D --------------------------------- *
// * DATE PROGRAMMER DESCRIPTION OF CHANGE *
// * -------- ---------- --------------------------------- *
// * 08 14 09 Nilges Started version 1 *
// * *
// * 08 18 09 Nilges 1. Revised implementation of *
// * statement macros per *
// * anon. *
// * 2. Using typedef instead of *
// * #define per Heathfield *
// * 3. Using typename in cast in *
// * place of length per Heathfield*
// * *
// * I S S U E S ----------------------------------------------- *
// * DATE POSTER DESCRIPTION AND RESOLUTION *
// * -------- ---------- --------------------------------- *
// * 08 18 09 Nilges To be implemented: rope names and *
// * Dewey decimal numbers of rope *
// * nodes. Routines for inspection and*
// * display of ropes. Code *
// * instrumentation of debug displays.*
// * *
// * 08 14 09 Nilges To be implemented: use extra *
// * precision arithmetic for unbounded*
// * strings, representing big nums as *
// * big strings but in a big base such*
// * as 256 for chars & 32768 for *
// * wchars. *
// * *
// * *
// * ----------------------------------------------------------- *
// * *
// * The scientific industry has its exact counterpart in the *
// * kind of minds it harnesses: they no longer need to do *
// * themselves any violence in becoming their own voluntary and *
// * zealous overseers. Even if they show themselves, outside *
// * their official capacity, to be quite human and sensible *
// * being, they are paralysed by pathic stupidity the moment *
// * they begin to think professionally. *
// * *
// * - T. W. Adorno, Minima Moralia, 1948 *
// * *
// * *
// ***************************************************************

// ***** Standard includes ***************************************

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <stddef.h>

// ***** Configuration *******************************************

#define SEGMENT_MAX_LENGTH 32
#define STRING_MAX_RECORDABLE_LENGTH 1024 // Set to 2^63-1 for
// actual use
#define UNKNOWN_START_INDEX -1

// ***** Macros **************************************************
// * *
// * Macros are of two types: *
// * *
// * *
// * * Statement macros can be used anywhere a C statement *
// * is valid. They are surrounded by curly braces, prefixed*
// * with do, and suffixed with while(0). When used, *
// * statement macros must be followed with a semicolon. *
// * Their names are suffixed with _STMT. *
// * *
// * * Expression macros can be used anywhere a C expression *
// * is valid. Their definitions are surrounded by round *
// * parentheses. Their names are suffixed with _EXP. *
// * *
// * *
// ***************************************************************
// --- Statement macro to handle errors
#define ERRORHANDLER_STMT(strMessage) \
do { \
printf("%s\n", (strMessage)); abort(); \
} while(0)

// --- Expression macro to return smaller value
#define MIN_EXP(value1, value2) \
( (value1) < (value2) ? (value1) : (value2) )

// --- Expression macro to perform malloc
#define MALLOC_EXP(typeName, mallocSize) \
( (typeName)(malloc(mallocSize)) )

// --- Statement macros to perform malloc with error checking
// Allocate using a type
#define MALLOCTYPE_STMT(ptr, mallocType, mallocPurpose) \
do { \
MALLOCSIZE_STMT(ptr, \
mallocType, \
sizeof(mallocType), \
mallocPurpose); \
} while(0)
// Allocate using a size
#define MALLOCSIZE_STMT(ptr, \
mallocType, \
mallocSize, \
mallocPurpose) \
do { \
if (((ptr) = MALLOC_EXP(mallocType, mallocSize)) \
== \
NULL) \
{ \
printf \
("Can't get %d bytes of storage\n", (mallocSize)); \
printf \
("My purpose was: %s...sorry it didn't work out\n", \
(mallocPurpose)); \
ERRORHANDLER_STMT("Malloc failed"); \
} \
} while(0)

// ***** Rope definition *****************************************

enum ENUnodeType { child, ancestor };

enum ENUnodeLengthType
{
known, tooLarge
};

typedef struct TYPropeNode ROPE;
typedef ROPE * Rope;

struct TYPropeNode
{
enum ENUnodeType enuNodeType;
enum ENUnodeLengthType enuNodeLengthType;
char * ptrNodeCharacters;
unsigned long long ulngStringLength;
unsigned long long lngSegmentStartIndex;
unsigned int uintSegmentLength;
Rope ptrParent;
Rope ptrLeft;
Rope ptrRight;
};

// ***** Procedures **********************************************

// ---------------------------------------------------------------
// Create a rope node
//
//
Rope mkRopeNode
(char * ptrNodeCharacters,
long long lngSegmentStartIndex,
unsigned int uintSegmentLength,
Rope ptrParent,
Rope ptrLeft,
Rope ptrRight)
{
Rope ptrNewNode = (Rope)NULL;
MALLOCTYPE_STMT(ptrNewNode, Rope, "Allocate a rope node");
(*ptrNewNode).ptrNodeCharacters = ptrNodeCharacters;
(*ptrNewNode).enuNodeType =
ptrParent == NULL
?
ancestor
:
child;
(*ptrNewNode).lngSegmentStartIndex = lngSegmentStartIndex;
(*ptrNewNode).uintSegmentLength = uintSegmentLength;
(*ptrNewNode).ptrParent = ptrParent;
(*ptrNewNode).ptrLeft = ptrLeft;
(*ptrNewNode).ptrRight = ptrRight;
(*ptrNewNode).ulngStringLength =
uintSegmentLength
+
(ptrLeft != NULL ? (*ptrLeft).ulngStringLength : 0)
+
(ptrRight != NULL ? (*ptrRight).ulngStringLength : 0);
return ptrNewNode;
}

// ---------------------------------------------------------------
// Calculate next start index on behalf of mkRope()
//
//
long long mkRope_calcStartIndex(long long lngOld,
unsigned int uintOffset)
{
if (lngOld == UNKNOWN_START_INDEX)
return UNKNOWN_START_INDEX;
unsigned long long ulngNew = lngOld + uintOffset;
if (ulngNew <= STRING_MAX_RECORDABLE_LENGTH)
return (long long)ulngNew;
return UNKNOWN_START_INDEX;
}

// ---------------------------------------------------------------
// Make rope
//
//
Rope mkRope
(Rope ptrParent,
char * ptrSourceChars,
long long lngStartIndex,
unsigned long long ulngStringLength)
{
Rope ptrLeft = NULL;
Rope ptrRight = NULL;
unsigned int uintNodes;
unsigned int uintDoubleSegmentLength;
if (ulngStringLength <= SEGMENT_MAX_LENGTH)
uintNodes = 1;
else
{
if (ulngStringLength
<=
(uintDoubleSegmentLength = SEGMENT_MAX_LENGTH << 1))
uintNodes = 2;
else
uintNodes = 3;
}
Rope ptrRopeNode =
mkRopeNode
(// ----- Pointer to source chars -----------------------
(uintNodes > 1
?
ptrSourceChars + SEGMENT_MAX_LENGTH
:
ptrSourceChars),
// ----- Parent segment start index --------------------
(mkRope_calcStartIndex
(lngStartIndex,
uintNodes > 1 ? SEGMENT_MAX_LENGTH : 0)),
// ----- Parent segment length (screw you Heathfield) --
(unsigned int)
(uintNodes > 1
?
MIN_EXP((ulngStringLength - SEGMENT_MAX_LENGTH),
(SEGMENT_MAX_LENGTH))
:
ulngStringLength),
// ----- Parent's own parent or null -------------------
ptrParent,
// ----- Left child node exists when segments > 1 ------
(uintNodes > 1
?
(ptrLeft = mkRopeNode
(ptrSourceChars,
lngStartIndex,
SEGMENT_MAX_LENGTH,
NULL, NULL, NULL))
:
NULL),
// ----- Right child node exists when segments > 1 ----
(uintNodes > 2
?
(ptrRight = mkRope
(NULL,
ptrSourceChars
+
uintDoubleSegmentLength,
mkRope_calcStartIndex
(lngStartIndex, uintDoubleSegmentLength),
SEGMENT_MAX_LENGTH
-
uintDoubleSegmentLength))
:
NULL));
if (ptrRopeNode != NULL)
{
(*ptrRopeNode).ptrLeft = ptrLeft;
(*ptrRopeNode).ptrRight = ptrRight;
if (ptrLeft != NULL)
(*((*ptrRopeNode).ptrLeft)).ptrParent =
ptrRopeNode;
if (ptrRight != NULL)
(*((*ptrRopeNode).ptrRight)).ptrParent =
ptrRopeNode;
(*ptrRopeNode).ulngStringLength = ulngStringLength;
}
return ptrRopeNode;
}

int main()
{
printf("Unlimited strings in basic C");
// ***** Insert test code *****
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,217
Latest member
IRMNikole

Latest Threads

Top