mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
Removed unused files.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2547 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
fa8b25fe97
commit
cd1c0e3508
52 changed files with 25 additions and 9338 deletions
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
Fri Oct 24 14:36:23 1997 Adam Fedor <fedor@oc.com>
|
||||
|
||||
* Removed unused files.
|
||||
* checks/beh.m, checks/float.c: Removed
|
||||
* examples/nx-client.m, examples/nx-server.m,
|
||||
examples/port-client.m, examples/port-server.m: Likewise.
|
||||
* src/AutoreleasePool.m, src/AutoreleaseStack.m,
|
||||
src/BinaryTreeEltNode.m, src/ConstantString.m,
|
||||
src/EltNodeCollector.m, src/LinkedListEltNode.m,
|
||||
src/Makefile.sed.nt, src/MethodSignature.m, src/NXConnection.m,
|
||||
src/NXProtocolChecker.m, src/NXProxy.m, src/NotificationQueue.m,
|
||||
src/ObjectRetaining.m, src/ProtocolEnforcer.m, src/RBTreeEltNode.m,
|
||||
src/ReleasePool.m, src/RetainingNotifier.m, src/Ring.m,
|
||||
src/RunLoop.m, src/SocketPort.m, src/SunRpcPort.m, src/Thread.m,
|
||||
src/Tree.m, src/TreeNode.m, src/argframe.m, src/data.m,
|
||||
src/eltfuncs.m, src/gnu4next.m, src/gnu4nextrt.m,
|
||||
src/o_vprintf.c, src/vfscanf.c: Likewise.
|
||||
* src/include/AutoreleasePool.h, src/include/AutoreleaseStack.h,
|
||||
src/include/BinaryTreeEltNode.h, src/include/LinkedListEltNode.h,
|
||||
src/include/RBTreeEltNode.h, src/include/SmallInt.h,
|
||||
src/include/SocketPort.h, src/include/abort.h,
|
||||
src/include/allocs.h, src/include/atoz.h, src/include/bitops.h,
|
||||
src/include/data.h, src/include/magic.h, src/include/minmax.h,
|
||||
src/include/number.h: Likewise.
|
||||
|
||||
Fri Oct 24 20:16:14 1997 Yoo C. Chung <wacko@laplace.snu.ac.kr>
|
||||
|
||||
* src/StdioStream.m ([StdioStream -dealloc]): Check fp before
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
#include <remote/NXConnection.h>
|
||||
#include <remote/NXProxy.h>
|
||||
#include <objc/List.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
id s;
|
||||
|
||||
s = [NXConnection connectToName:"nxserver"];
|
||||
|
||||
printf("Server has class name `%s'\n",
|
||||
[s name]);
|
||||
printf("First object in server has class name `%s'\n",
|
||||
[[s objectAt:0] name]);
|
||||
|
||||
/* Be nice and shut down the connection */
|
||||
[[s connectionForProxy] free];
|
||||
|
||||
exit(0);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#include <remote/NXConnection.h>
|
||||
#include <objc/List.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
id s = [[List alloc] init];
|
||||
id c;
|
||||
|
||||
[s addObject:[Object new]];
|
||||
|
||||
c = [NXConnection registerRoot:s withName:"nxserver"];
|
||||
[c run];
|
||||
|
||||
exit(0);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <gnustep/base/SocketPort.h>
|
||||
#include <gnustep/base/String.h>
|
||||
|
||||
#define MSG "Hello from a client SocketPort."
|
||||
#define BUFFER_SIZE 80
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char b[BUFFER_SIZE];
|
||||
int len;
|
||||
id remotePort;
|
||||
id localPort = [SocketPort newLocal];
|
||||
id rp;
|
||||
|
||||
if (argc > 1)
|
||||
remotePort = [SocketPort newRemoteWithNumber:3
|
||||
onHost:[String stringWithCString:argv[1]]];
|
||||
else
|
||||
remotePort = [SocketPort newRemoteWithNumber:3 onHost:@""];
|
||||
|
||||
strcpy(b, MSG);
|
||||
[localPort sendPacket:b length:strlen(b)
|
||||
toPort:remotePort
|
||||
timeout: 15000];
|
||||
len = [localPort receivePacket:b length:BUFFER_SIZE
|
||||
fromPort:&rp
|
||||
timeout:15000];
|
||||
|
||||
if (len == -1)
|
||||
{
|
||||
fprintf(stderr, "receive from SocketPort timed out\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
b[len] = '\0';
|
||||
printf("(length %d): %s\n", len, b);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <gnustep/base/SocketPort.h>
|
||||
|
||||
#define MSG "Hello back to you, from a server SocketPort"
|
||||
|
||||
int main()
|
||||
{
|
||||
id packet;
|
||||
id p = [TcpPort newLocalWithNumber:3];
|
||||
id rp;
|
||||
int len;
|
||||
char *buf;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
packet = [p receivePacketWithTimeout: -1];
|
||||
len = [p streamBufferLength];
|
||||
buf = [p streamBuffer];
|
||||
if (len >= 0 && len < 32)
|
||||
buf[l] = '\0';
|
||||
printf("(length %d): %s\n", len, buf);
|
||||
|
||||
[p sendPacket:MSG length:strlen(MSG)
|
||||
toPort:rp
|
||||
timeout:15000];
|
||||
}
|
||||
exit(0);
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/* Interface for relase pools for delayed disposal
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __AutoreleasePool_m_GNUSTEP_BASE_INCLUDE
|
||||
#define __AutoreleasePool_m_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/ObjectRetaining.h>
|
||||
|
||||
@interface AutoreleasePool : Object
|
||||
{
|
||||
AutoreleasePool *parent;
|
||||
unsigned released_count;
|
||||
unsigned released_size;
|
||||
id *released;
|
||||
}
|
||||
|
||||
+ currentPool;
|
||||
+ (void) autoreleaseObject: anObj;
|
||||
- (void) autoreleaseObject: anObj;
|
||||
|
||||
- init;
|
||||
|
||||
@end
|
||||
|
||||
@interface Object (Retaining) <Retaining>
|
||||
@end
|
||||
|
||||
void objc_retain_object (id anObj);
|
||||
void objc_release_object (id anObj);
|
||||
unsigned objc_retain_count (id anObj);
|
||||
|
||||
#endif /* __AutoreleasePool_m_GNUSTEP_BASE_INCLUDE */
|
|
@ -1,122 +0,0 @@
|
|||
/* Interface to release stack for delayed disposal
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __AutoreleaseStack_m_GNUSTEP_BASE_INCLUDE
|
||||
#define __AutoreleaseStack_m_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/ObjectRetaining.h>
|
||||
|
||||
@interface AutoreleaseStack : Object
|
||||
{
|
||||
}
|
||||
|
||||
+ (void) autoreleaseObject: anObj;
|
||||
- (void) autoreleaseObject: anObj;
|
||||
|
||||
- init;
|
||||
|
||||
@end
|
||||
|
||||
void objc_release_stack_objects();
|
||||
|
||||
/*
|
||||
Use of this autorelease class gives -autorelease the following semantics:
|
||||
|
||||
- autorelease;
|
||||
|
||||
Use this message when the sender is done with this object, but the
|
||||
sender doesn't want the object to be deallocated immediately
|
||||
because the function that sends this message will use this object
|
||||
as its return value. The object will be queued to receive the
|
||||
actual "release" message only after the caller's caller returns.
|
||||
(Well, not "queued", "stacked" actually.)
|
||||
|
||||
Due to this delayed release, the function that receives the object
|
||||
as a return value will have the opportunity to retain the object
|
||||
before the "release" instigated by the "autorelease" actually
|
||||
takes place.
|
||||
|
||||
IMPORTANT PROGRAMMING CONVENTION: Since a autoreleased object may
|
||||
be freed in the caller's caller's frame, a function must be careful
|
||||
when returning an object that has been been autoreleased to it
|
||||
(i.e. returning the object to the autorelease caller's caller's
|
||||
caller). Since you cannot always know which objects returned to
|
||||
the current function have been autoreleased by their returners,
|
||||
you must use the following rule to insure safety for these
|
||||
situations:
|
||||
|
||||
When returning an object that has been allocated, copied or
|
||||
retained by the returner, return the object as usual. If
|
||||
returning an object that has been received in this function by
|
||||
another function, always retain and autorelease the object
|
||||
before returning it. (Unless, of course, the returner still
|
||||
needs to keep a reference to the object, in which case the final
|
||||
autorelease should be omitted.)
|
||||
|
||||
The autorelease mechanism works as follows: The implementation of
|
||||
the "autorelease" method pushes the receiver and the caller's
|
||||
caller's frame address onto an internally maintained stack. But,
|
||||
before pushing the reciever, the implementation checks the entries
|
||||
already on the stack, popping elements off the stack until the
|
||||
recorded frame address is less than the caller's caller's frame
|
||||
address. Each object popped off the stack is sent a "release"
|
||||
message. The stack capacity grows automatically if necessary.
|
||||
|
||||
This mechanism ensures that not too many autoreleased objects can
|
||||
be stacked before we check to see what objects can be released
|
||||
(i.e. no objects). It also ensures that objects which have been
|
||||
autoreleased are released as soon as we autorelease any other
|
||||
object in a lower stack frame.
|
||||
|
||||
The only way to build up an unnecessarily large collection of
|
||||
autoreleased objects is by calling functions that autorelease an
|
||||
object, and by repeatedly calling those functions from functions
|
||||
with equal or increasingly higher frame addresses.
|
||||
|
||||
Any time that you suspect that you may be creating an unnecessarily
|
||||
large number of autoreleased objects in a function, (e.g. the
|
||||
function contains a loop that creates many autoreleased objects
|
||||
that the function doesn't need), you can always release all the
|
||||
releasable autoreleased objects for this frame by calling
|
||||
objc_release_stack_objects(). Be warned that calling this function
|
||||
will release all objects that have been autoreleased to this
|
||||
function; if you still need to use some of them, you will have to
|
||||
retain them beforehand, and release or autorelease them
|
||||
afterwards.
|
||||
|
||||
If desired, you can also use objc_release_stack_objects() at the
|
||||
top of an event loop, a guaranteed "catch-all" coding practise
|
||||
similar to the creation and destruction of AutoreleasePool objects
|
||||
in the event loop.
|
||||
|
||||
As an alternative to calling objc_release_stack_objects() you can
|
||||
also use the same scheme for forcing autorelease's as used for
|
||||
AutoreleasePool's: s = [[AutoreleaseStack alloc] init], ... code
|
||||
that autoreleases a bunch of objects to the same stack level ...,
|
||||
[s release]. It has the same effect.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#endif /* __AutoreleaseStack_m_GNUSTEP_BASE_INCLUDE */
|
|
@ -1,36 +0,0 @@
|
|||
/* Interface for Objective-C BinaryTreeEltNode object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __BinaryTreeEltNode_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __BinaryTreeEltNode_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/BinaryTreeNode.h>
|
||||
#include <gnustep/base/EltNodeCollector.h>
|
||||
|
||||
@interface BinaryTreeEltNode : BinaryTreeNode
|
||||
#include <gnustep/base/EltNode-h>
|
||||
@end
|
||||
|
||||
|
||||
#endif /* __BinaryTreeEltNode_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -1,35 +0,0 @@
|
|||
/* Interface for Objective-C LinkedListEltNode object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __LinkedListEltNode_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __LinkedListEltNode_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/LinkedListNode.h>
|
||||
#include <gnustep/base/EltNodeCollector.h>
|
||||
|
||||
@interface LinkedListEltNode : LinkedListNode
|
||||
#include <gnustep/base/EltNode-h>
|
||||
@end
|
||||
|
||||
#endif /* __LinkedListEltNode_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -1,35 +0,0 @@
|
|||
/* Interface for Objective-C RBTreeEltNode object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __RBTreeEltNode_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __RBTreeEltNode_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/RBTreeNode.h>
|
||||
#include <gnustep/base/EltNodeCollector.h>
|
||||
|
||||
@interface RBTreeEltNode : RBTreeNode
|
||||
#include <gnustep/base/EltNode-h>
|
||||
@end
|
||||
|
||||
#endif /* __RBTreeEltNode_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -1,39 +0,0 @@
|
|||
/* Interface for Objective-C efficient small integers
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Created: Sep 1995
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SmallInt_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __SmallInt_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
|
||||
#define IS_SMALLINT(OBJ) (((void*)OBJ) & 0x1)
|
||||
#define ID2INT(OBJ) ((IS_SMALLINT(OBJ)) ? (((int)OBJ) >> 1):[OBJ intValue])
|
||||
#define INT2ID(I) ((id)((I << 1) & 0x1))
|
||||
|
||||
@interface SmallInt : NSObject
|
||||
|
||||
-
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SmallInt_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -1,60 +0,0 @@
|
|||
/* Interface for socket-based port object for use with Connection
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: July 1994
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SocketPort_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __SocketPort_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/Port.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef WIN32
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
#endif /* !WIN32 */
|
||||
|
||||
typedef struct sockaddr_in sockport_t;
|
||||
|
||||
@interface SocketPort : Port
|
||||
{
|
||||
sockport_t sockPort;
|
||||
int sock; /* socket if local, 0 if remote */
|
||||
BOOL close_on_dealloc;
|
||||
}
|
||||
|
||||
|
||||
+ newForSockPort: (sockport_t)s close: (BOOL)f;
|
||||
+ newForSockPort: (sockport_t)s;
|
||||
+ newLocalWithNumber: (int)n;
|
||||
+ newLocal;
|
||||
+ newRemoteWithNumber: (int)n onHost: (NSString*)h;
|
||||
|
||||
- (sockport_t) sockPort;
|
||||
|
||||
- (int) socket;
|
||||
- (int) socketPortNumber;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SocketPort_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -1,52 +0,0 @@
|
|||
/* Handling the interface between allocs and zones.
|
||||
* Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Albin L. Jones <Albin.L.Jones@Dartmouth.EDU>
|
||||
* Created: Sat Oct 15 10:40:40 EDT 1994
|
||||
* Updated: Sat Feb 10 15:11:01 EST 1996
|
||||
* Serial: 96.02.10.03
|
||||
*
|
||||
* This file is part of the GNUstep Base Library.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/**** Included Headers *******************************************************/
|
||||
|
||||
#include <gnustep/base/callbacks.h>
|
||||
|
||||
/**** Type, Constant, and Macro Definitions **********************************/
|
||||
|
||||
/**** Function Implementations ***********************************************/
|
||||
|
||||
#ifndef __atoz_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __atoz_h_GNUSTEP_BASE_INCLUDE 1
|
||||
|
||||
/**** Included Headers *******************************************************/
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <gnustep/base/allocs.h>
|
||||
#include <gnustep/base/callbacks.h>
|
||||
|
||||
/**** Function Prototypes ****************************************************/
|
||||
|
||||
/** Translating from Zones to Allocs **/
|
||||
|
||||
o_allocs_t
|
||||
o_allocs_for_zone (NSZone * zone);
|
||||
|
||||
#endif /* __atoz_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -1,239 +0,0 @@
|
|||
/* A modular data encapsulator for use with Libobjects.
|
||||
* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Albin L. Jones <Albin.L.Jones@Dartmouth.EDU>
|
||||
* Created: Fri Nov 24 21:50:01 EST 1995
|
||||
* Updated: Sat Feb 10 15:40:21 EST 1996
|
||||
* Serial: 96.02.10.01
|
||||
*
|
||||
* This file is part of the GNUstep Base Library.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef __data_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __data_h_GNUSTEP_BASE_INCLUDE 1
|
||||
|
||||
/**** Included Headers *******************************************************/
|
||||
|
||||
#include <gnustep/base/allocs.h>
|
||||
#include <gnustep/base/callbacks.h>
|
||||
|
||||
/**** Type, Constant, and Macro Definitions **********************************/
|
||||
|
||||
typedef enum _o_data_encoding o_data_encoding_t;
|
||||
|
||||
enum _o_data_encoding
|
||||
{
|
||||
o_data_encoding_unknown = -1,
|
||||
o_data_encoding_binary,
|
||||
o_data_encoding_7bit,
|
||||
o_data_encoding_8bit,
|
||||
o_data_encoding_base64,
|
||||
o_data_encoding_quoted_printable,
|
||||
o_data_encoding_x_uuencode
|
||||
};
|
||||
|
||||
typedef struct _o_data o_data_t;
|
||||
|
||||
struct _o_data
|
||||
{
|
||||
int magic;
|
||||
size_t number;
|
||||
const char *name;
|
||||
const void *extra;
|
||||
o_callbacks_t extra_callbacks;
|
||||
o_allocs_t allocs;
|
||||
|
||||
/* Necessary information about the data. */
|
||||
void *buffer; /* Where the stuff really is. */
|
||||
size_t length; /* How much stuff there is. */
|
||||
size_t capacity; /* How much room for stuff there is. */
|
||||
};
|
||||
|
||||
/* Creating temporary data. This is *so* cool. GCC is awesome! */
|
||||
#define OBJECTS_DATA(P, L) \
|
||||
(o_data_t *(&({OBJECTS_MAGIC_DATA, (size_t) -1, 0, \
|
||||
0, 0, __o_callbacks_standard, 0, 0, 0, \
|
||||
__o_allocs_standard, (P), (L), (L)})))
|
||||
|
||||
/**** Function Prototypes ****************************************************/
|
||||
|
||||
/** Basics **/
|
||||
|
||||
#include <gnustep/base/data-bas.h>
|
||||
|
||||
/** Hashing **/
|
||||
|
||||
size_t o_data_hash (o_data_t * data);
|
||||
|
||||
/** Creating **/
|
||||
|
||||
o_data_t * o_data_alloc (void);
|
||||
|
||||
o_data_t * o_data_alloc_with_allocs (o_allocs_t allocs);
|
||||
|
||||
o_data_t * o_data_new (void);
|
||||
|
||||
o_data_t * o_data_new_with_allocs (o_allocs_t allocs);
|
||||
|
||||
o_data_t * _o_data_with_allocs_with_contents_of_file (o_allocs_t allocs, const char *file);
|
||||
|
||||
o_data_t * _o_data_with_contents_of_file (const char *file);
|
||||
|
||||
o_data_t * o_data_with_buffer_of_length (void *buffer, size_t length);
|
||||
|
||||
o_data_t * o_data_with_allocs_with_buffer_of_length (o_allocs_t allocs, void *buffer, size_t length);
|
||||
|
||||
/** Initializing **/
|
||||
|
||||
o_data_t * o_data_init (o_data_t * data);
|
||||
|
||||
o_data_t * _o_data_init_with_contents_of_file (o_data_t * data, const char *file);
|
||||
|
||||
o_data_t * o_data_init_with_buffer_of_length (o_data_t * data, void *buffer, size_t length);
|
||||
|
||||
/** Statistics **/
|
||||
|
||||
size_t o_data_capacity (o_data_t * data);
|
||||
|
||||
/* Obtain DATA's length. */
|
||||
size_t o_data_length (o_data_t * data);
|
||||
|
||||
/* Obtain a read-only copy of DATA's buffer. */
|
||||
const void *o_data_buffer (o_data_t * data);
|
||||
|
||||
/* Obtain DATA's capacity through reference. */
|
||||
size_t o_data_get_capacity (o_data_t * data, size_t * capacity);
|
||||
|
||||
/* Obtain DATA's length through reference. */
|
||||
size_t o_data_get_length (o_data_t * data, size_t * length);
|
||||
|
||||
/* Copy DATA's buffer into BUFFER. It is assumed that BUFFER is large
|
||||
* enough to contain DATA's buffer. */
|
||||
size_t o_data_get_buffer (o_data_t * data, void *buffer);
|
||||
|
||||
/* Copy no more that LENGTH of DATA's buffer into BUFFER. Returns the
|
||||
* amount actually copied. */
|
||||
size_t o_data_get_buffer_of_length (o_data_t * data, void *buffer, size_t length);
|
||||
|
||||
/* Copy a subrange of DATA's buffer into BUFFER. As always, it is
|
||||
* assumed that BUFFER is large enough to contain everything. We
|
||||
* return the size of the data actually copied into BUFFER. */
|
||||
size_t o_data_get_buffer_of_subrange (o_data_t * data, void *buffer, size_t location, size_t length);
|
||||
|
||||
size_t o_data_set_capacity (o_data_t * data, size_t capacity);
|
||||
|
||||
size_t o_data_increase_capacity (o_data_t * data, size_t capacity);
|
||||
|
||||
size_t o_data_decrease_capacity (o_data_t * data, size_t capacity);
|
||||
|
||||
size_t o_data_set_length (o_data_t * data, size_t length);
|
||||
|
||||
size_t o_data_set_buffer_of_subrange (o_data_t * data, void *buffer, size_t location, size_t length);
|
||||
|
||||
size_t o_data_set_buffer_of_length (o_data_t * data, void *buffer, size_t length);
|
||||
|
||||
void o_data_get_md5_checksum (o_data_t * data, char *buffer);
|
||||
|
||||
/** Copying **/
|
||||
|
||||
o_data_t * o_data_copy (o_data_t * data);
|
||||
|
||||
o_data_t * o_data_copy_of_subrange (o_data_t * data, size_t location, size_t length);
|
||||
|
||||
o_data_t * o_data_copy_with_allocs (o_data_t * data, o_allocs_t allocs);
|
||||
|
||||
o_data_t * o_data_copy_of_subrange_with_allocs (o_data_t * data, size_t location, size_t length, o_allocs_t allocs);
|
||||
|
||||
/** Replacing **/
|
||||
|
||||
/* Note that we cannot do any bounds checking on BUFFER. */
|
||||
o_data_t * o_data_replace_subrange_with_subrange_of_buffer (o_data_t * data, size_t location, size_t length, size_t buf_location, size_t buf_length, void *buffer);
|
||||
|
||||
o_data_t * o_data_replace_subrange_with_subrange_of_data (o_data_t * data, size_t location, size_t length, size_t other_location, size_t other_length, o_data_t * other_data);
|
||||
|
||||
o_data_t * o_data_replace_subrange_with_data (o_data_t * data, size_t location, size_t length, o_data_t * other_data);
|
||||
|
||||
/** Appending **/
|
||||
|
||||
o_data_t * o_data_append_data (o_data_t * data, o_data_t * other_data);
|
||||
|
||||
o_data_t * o_data_append_subrange_of_data (o_data_t * data, size_t location, size_t length, o_data_t * other_data);
|
||||
|
||||
o_data_t * o_data_append_data_repeatedly (o_data_t * data, o_data_t * other_data, size_t num_times);
|
||||
|
||||
o_data_t * o_data_append_subrange_of_data_repeatedly (o_data_t * data, size_t location, size_t length, o_data_t * other_data, size_t num_times);
|
||||
|
||||
/** Prepending **/
|
||||
|
||||
o_data_t * o_data_prepend_data (o_data_t * data, o_data_t * other_data);
|
||||
|
||||
o_data_t * o_data_prepend_subrange_of_data (o_data_t * data, size_t location, size_t length, o_data_t * other_data);
|
||||
|
||||
o_data_t * o_data_prepend_data_repeatedly (o_data_t * data, o_data_t * other_data, size_t num_times);
|
||||
|
||||
o_data_t * o_data_prepend_subrange_of_data_repeatedly (o_data_t * data, size_t location, size_t length, o_data_t * other_data, size_t num_times);
|
||||
|
||||
/** Concatenating **/
|
||||
|
||||
o_data_t * o_data_concatenate_data (o_data_t * data, o_data_t * other_data);
|
||||
|
||||
o_data_t * o_data_concatenate_data_with_allocs (o_data_t * data, o_data_t * other_data, o_allocs_t allocs);
|
||||
|
||||
o_data_t * o_data_concatenate_subrange_of_data (o_data_t * data, size_t location, size_t length, o_data_t * other_data);
|
||||
|
||||
o_data_t * o_data_concatenate_subrange_of_data_with_allocs (o_data_t * data, size_t location, size_t length, o_data_t * other_data, o_allocs_t allocs);
|
||||
|
||||
/** Reversing **/
|
||||
|
||||
o_data_t * o_data_reverse_with_granularity (o_data_t * data, size_t granularity);
|
||||
|
||||
o_data_t * o_data_reverse_by_int (o_data_t * data);
|
||||
|
||||
o_data_t * o_data_reverse_by_char (o_data_t * data);
|
||||
|
||||
o_data_t * o_data_reverse_by_void_p (o_data_t * data);
|
||||
|
||||
/** Permuting **/
|
||||
|
||||
o_data_t * o_data_permute_with_granularity (o_data_t * data, size_t granularity);
|
||||
|
||||
o_data_t * o_data_permute_with_no_fixed_points_with_granularity (o_data_t * data, size_t granularity);
|
||||
|
||||
/** Writing **/
|
||||
|
||||
int _o_data_write_to_file (o_data_t * data, const char *file);
|
||||
|
||||
/** Encoding **/
|
||||
|
||||
o_data_encoding_t o_data_guess_data_encoding (o_data_t * data);
|
||||
|
||||
o_data_t * _o_data_encode_with_base64 (o_data_t * data);
|
||||
|
||||
o_data_t * _o_data_encode_with_quoted_printable (o_data_t * data);
|
||||
|
||||
o_data_t * _o_data_encode_with_x_uuencode (o_data_t * data);
|
||||
|
||||
o_data_t * o_data_encode_with_encoding (o_data_t * data, o_data_encoding_t enc);
|
||||
|
||||
o_data_t * _o_data_decode_with_base64 (o_data_t * data);
|
||||
|
||||
o_data_t * _o_data_decode_with_quoted_printable (o_data_t * data);
|
||||
|
||||
o_data_t * _o_data_decode_with_x_uuencode (o_data_t * data);
|
||||
|
||||
o_data_t * o_data_decode_with_encoding (o_data_t * data, o_data_encoding_t enc);
|
||||
|
||||
#endif /* __data_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -1,111 +0,0 @@
|
|||
/* Implementation of release pools for delayed disposal
|
||||
Copyright (C) 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/AutoreleasePool.h>
|
||||
#include <gnustep/base/ObjectRetaining.h>
|
||||
|
||||
/* Doesn't handle multi-threaded stuff.
|
||||
Doesn't handle exceptions. */
|
||||
|
||||
/* Put the stuff from initialize into a runtime init function.
|
||||
This class should be made more efficient, especially:
|
||||
[[Autorelease alloc] init]
|
||||
[current_pool addObject:o] (REALLOC-case)
|
||||
*/
|
||||
|
||||
static AutoreleasePool *current_pool = nil;
|
||||
|
||||
#define DEFAULT_SIZE 64
|
||||
|
||||
@implementation AutoreleasePool
|
||||
|
||||
+ initialize
|
||||
{
|
||||
if (self == [AutoreleasePool class])
|
||||
autorelease_class = self;
|
||||
return self;
|
||||
}
|
||||
|
||||
+ currentPool
|
||||
{
|
||||
return current_pool;
|
||||
}
|
||||
|
||||
+ (void) autoreleaseObject: anObj
|
||||
{
|
||||
[current_pool autoreleaseObject:anObj];
|
||||
}
|
||||
|
||||
- (void) autoreleaseObject: anObj
|
||||
{
|
||||
released_count++;
|
||||
if (released_count == released_size)
|
||||
{
|
||||
released_size *= 2;
|
||||
OBJC_REALLOC(released, id, released_size);
|
||||
}
|
||||
released[released_count] = anObj;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
parent = current_pool;
|
||||
current_pool = self;
|
||||
OBJC_MALLOC(released, id, DEFAULT_SIZE);
|
||||
released_size = DEFAULT_SIZE;
|
||||
released_count = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) retain
|
||||
{
|
||||
[self error:"Don't call `-retain' on a AutoreleasePool"];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (oneway void) release
|
||||
{
|
||||
[self dealloc];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
int i;
|
||||
if (parent)
|
||||
current_pool = parent;
|
||||
else
|
||||
current_pool = [[AutoreleasePool alloc] init];
|
||||
for (i = 0; i < released_count; i++)
|
||||
[released[i] release];
|
||||
OBJC_FREE(released);
|
||||
object_dispose(self);
|
||||
}
|
||||
|
||||
- autorelease
|
||||
{
|
||||
[self error:"Don't call `-autorelease' on a AutoreleasePool"];
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,156 +0,0 @@
|
|||
/* Implementation of release stack for delayed disposal
|
||||
Copyright (C) 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/AutoreleaseStack.h>
|
||||
#include <gnustep/base/ObjectRetaining.h>
|
||||
#include <gnustep/base/collhash.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* The initial size of the released_objects array */
|
||||
#define DEFAULT_SIZE 64
|
||||
|
||||
/* Array of objects to be released later */
|
||||
static unsigned released_capacity = 0;
|
||||
static unsigned released_index = 0;
|
||||
static id *released_objects = NULL;
|
||||
static void **released_frame_pointers = NULL;
|
||||
|
||||
static inline void
|
||||
grow_released_arrays()
|
||||
{
|
||||
assert(released_objects);
|
||||
if (released_index == released_capacity)
|
||||
{
|
||||
released_capacity *= 2;
|
||||
OBJC_REALLOC(released_objects, id, released_capacity);
|
||||
OBJC_REALLOC(released_frame_pointers, void*, released_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
objc_release_stack_o_to_frame_address(void *frame_address)
|
||||
{
|
||||
assert(released_objects);
|
||||
/* xxx This assumes stack grows up */
|
||||
while ((released_frame_pointers[released_index]
|
||||
> frame_address)
|
||||
&& released_index)
|
||||
{
|
||||
[released_objects[released_index] release];
|
||||
released_index--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
objc_release_stack_objects()
|
||||
{
|
||||
assert(released_objects);
|
||||
objc_release_stack_o_to_frame_address(__builtin_frame_address(1));
|
||||
}
|
||||
|
||||
void
|
||||
objc_stack_release_object_with_address (id o, void *a)
|
||||
{
|
||||
released_index++;
|
||||
grow_released_arrays();
|
||||
released_objects[released_index] = o;
|
||||
released_frame_pointers[released_index] = a;
|
||||
}
|
||||
|
||||
/* The object will not be released until after the function that is 3
|
||||
stack frames up exits. One frame for this function, one frame for
|
||||
the "stackRelease" method that calls this, and one for the method
|
||||
that called "stackRelease".
|
||||
Careful, if you try to call this too few stack frames away from main,
|
||||
you get a seg fault
|
||||
*/
|
||||
void
|
||||
objc_stack_release_object(id anObj)
|
||||
{
|
||||
void *s;
|
||||
|
||||
/* assert(__builtin_frame_address(2)); */
|
||||
s = __builtin_frame_address(3);
|
||||
|
||||
/* Do the pending releases of other objects */
|
||||
objc_release_stack_o_to_frame_address(s);
|
||||
|
||||
/* Queue this object for later release */
|
||||
objc_stack_release_object_with_address(anObj, s);
|
||||
}
|
||||
|
||||
unsigned
|
||||
objc_stack_release_count()
|
||||
{
|
||||
return released_index;
|
||||
}
|
||||
|
||||
@implementation AutoreleaseStack
|
||||
|
||||
+ initialize
|
||||
{
|
||||
static init_done = 0;
|
||||
|
||||
/* Initialize if we haven't done it yet */
|
||||
if (!init_done)
|
||||
{
|
||||
init_done = 1;
|
||||
|
||||
autorelease_class = self;
|
||||
|
||||
released_capacity = DEFAULT_SIZE;
|
||||
OBJC_MALLOC(released_objects, id, released_capacity);
|
||||
OBJC_MALLOC(released_frame_pointers, void*, released_capacity);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
objc_stack_release_object_with_address(self, 0);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
while (released_objects[released_index] != self)
|
||||
{
|
||||
[released_objects[released_index] release];
|
||||
released_index--;
|
||||
}
|
||||
released_index--;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) autoreleaseObject: anObject
|
||||
{
|
||||
objc_stack_release_object(anObject);
|
||||
}
|
||||
|
||||
+ (void) autoreleaseObject: anObject
|
||||
{
|
||||
objc_stack_release_object(anObject);
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,38 +0,0 @@
|
|||
/* Implementation for Objective-C BinaryTreeEltNode object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/BinaryTreeEltNode.h>
|
||||
|
||||
@implementation BinaryTreeEltNode
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [BinaryTreeEltNode class])
|
||||
[self setVersion:0]; /* beta release */
|
||||
}
|
||||
|
||||
#include <gnustep/base/EltNode-m>
|
||||
|
||||
@end
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
/* Implementation for GNU Objective-C ConstantString object
|
||||
Copyright (C) 1993,1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: July 1994
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/String.h>
|
||||
#include <gnustep/base/IndexedCollectionPrivate.h>
|
||||
|
||||
@implementation ConstantString
|
||||
|
||||
// INITIALIZING;
|
||||
|
||||
/* This must work without sending any messages to content objects */
|
||||
- (void) empty
|
||||
{
|
||||
[self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
// REPLACING;
|
||||
|
||||
- replaceAllStrings: (String*)oldString with: (String*)newString
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- replaceFirstString: (String*)oldString with: (String*)newString
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- replaceFirstString: (String*)oldString
|
||||
afterIndex: (unsigned)index
|
||||
with: (String*)newString
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- setToAllCapitals
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- setToInitialCapitals
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- setToLowerCase
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- trimBlanks
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
|
||||
// SETTING VALUES;
|
||||
|
||||
- setIntValue: (int)anInt
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- setFloatValue: (float)aFloat
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- setDoubleValue: (double)aDouble
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- setCStringValue: (const char *)aCString
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
- setStringValue: (String*)aString
|
||||
{
|
||||
return [self shouldNotImplement:_cmd];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#if 0 /* Moved to NSString.m */
|
||||
@implementation NXConstantString
|
||||
@end
|
||||
#endif
|
|
@ -1,464 +0,0 @@
|
|||
/* Implementation for Objective-C EltNodeCollector collection object
|
||||
Copyright (C) 1993,1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* This is class works in conjunction with all classes that require
|
||||
content objects conforming to some <...Comprising> protocol
|
||||
i.e. LinkedList, BinaryTree, RBTree, etc.
|
||||
It provides a interface for holding non-object elt's.
|
||||
*/
|
||||
|
||||
/* I should override a few more methods to increase efficiency. */
|
||||
|
||||
#include <gnustep/base/EltNodeCollector.h>
|
||||
#include <gnustep/base/IndexedCollectionPrivate.h>
|
||||
#include <gnustep/base/LinkedListEltNode.h>
|
||||
#include <gnustep/base/Coder.h>
|
||||
|
||||
#define DEFAULT_ELT_NODE_CLASS LinkedListEltNode
|
||||
#define DEFAULT_NODE_COLLECTOR_CLASS LinkedList
|
||||
|
||||
@implementation EltNodeCollector
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [EltNodeCollector class])
|
||||
[self setVersion:0]; /* beta release */
|
||||
}
|
||||
|
||||
+ defaultEltNodeClass
|
||||
{
|
||||
return [DEFAULT_ELT_NODE_CLASS class];
|
||||
}
|
||||
|
||||
+ defaultNodeCollectorClass
|
||||
{
|
||||
return [DEFAULT_NODE_COLLECTOR_CLASS class];
|
||||
}
|
||||
|
||||
// INITIALIZING AND FREEING;
|
||||
|
||||
/* This is the designated initializer of this class */
|
||||
- initWithType: (const char *)contentEncoding
|
||||
nodeCollector: aCollector
|
||||
nodeClass: aNodeClass
|
||||
{
|
||||
[super initWithType:contentEncoding];
|
||||
_comparison_function = elt_get_comparison_function(contentEncoding);
|
||||
// This actually checks that instances conformTo: ??? ;
|
||||
/*
|
||||
if (![aNodeClass conformsTo:@protocol(EltHolding)])
|
||||
[self error:"in %s, 2nd arg, %s, does not conform to @protocol(%s)",
|
||||
sel_get_name(_cmd), [nodeClass name], [@protocol(EltHolding) name]];
|
||||
*/
|
||||
_node_class = aNodeClass;
|
||||
/* We could check to make sure that any objects already in aCollector
|
||||
conform to @protocol(EltHolding) and that their encoding matches
|
||||
contentEncoding. */
|
||||
_contents_collector = aCollector;
|
||||
return self;
|
||||
}
|
||||
|
||||
// remove this;
|
||||
/*
|
||||
- initWithType: (const char *)contentEncoding
|
||||
nodeClass: aNodeClass
|
||||
{
|
||||
return [self initWithType:contentEncoding
|
||||
nodeCollector:[[[_node_class nodeCollectorClass] alloc] init]
|
||||
nodeClass:aNodeClass];
|
||||
}
|
||||
*/
|
||||
|
||||
/* Archiving must mimic the above designated initializer */
|
||||
|
||||
- (void) _encodeCollectionWithCoder: aCoder
|
||||
{
|
||||
const char *encoding = [self contentType];
|
||||
|
||||
[super _encodeCollectionWithCoder:aCoder];
|
||||
[aCoder encodeValueOfObjCType:@encode(char*) at:&encoding
|
||||
withName:@"EltNodeCollector Content Type Encoding"];
|
||||
[aCoder encodeValueOfObjCType:"#" at:&_node_class
|
||||
withName:@"EltNodeCollector Content Node Class"];
|
||||
}
|
||||
|
||||
- _initCollectionWithCoder: aCoder
|
||||
{
|
||||
char *encoding;
|
||||
|
||||
[super _initCollectionWithCoder:aCoder];
|
||||
[aCoder decodeValueOfObjCType:@encode(char*) at:&encoding withName:NULL];
|
||||
_comparison_function = elt_get_comparison_function(encoding);
|
||||
[aCoder decodeValueOfObjCType:"#" at:&_node_class withName:NULL];
|
||||
_contents_collector = nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) _encodeContentsWithCoder: (Coder*)aCoder
|
||||
{
|
||||
[aCoder encodeObject:_contents_collector
|
||||
withName:@"EltNodeCollector Contents Collector"];
|
||||
}
|
||||
|
||||
- (void) _decodeContentsWithCoder: (Coder*)aCoder
|
||||
{
|
||||
[aCoder decodeObjectAt:&_contents_collector withName:NULL];
|
||||
}
|
||||
|
||||
/* Old-style archiving */
|
||||
|
||||
- _writeInit: (TypedStream*)aStream
|
||||
{
|
||||
const char *encoding = [self contentType];
|
||||
|
||||
[super _writeInit:aStream];
|
||||
objc_write_type(aStream, @encode(char*), &encoding);
|
||||
objc_write_type(aStream, "#", &_node_class);
|
||||
return self;
|
||||
}
|
||||
|
||||
- _readInit: (TypedStream*)aStream
|
||||
{
|
||||
char *encoding;
|
||||
|
||||
[super _readInit:aStream];
|
||||
objc_read_type(aStream, @encode(char*), &encoding);
|
||||
_comparison_function = elt_get_comparison_function(encoding);
|
||||
objc_read_type(aStream, "#", &_node_class);
|
||||
_contents_collector = nil; /* taken care of in _readContents: */
|
||||
return self;
|
||||
}
|
||||
|
||||
- _writeContents: (TypedStream*)aStream
|
||||
{
|
||||
objc_write_object(aStream, _contents_collector);
|
||||
return self;
|
||||
}
|
||||
|
||||
- _readContents: (TypedStream*)aStream
|
||||
{
|
||||
objc_read_object(aStream, &_contents_collector);
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Empty copy must empty an allocCopy'ed version of self */
|
||||
- emptyCopy
|
||||
{
|
||||
EltNodeCollector *copy = [super emptyCopy];
|
||||
copy->_contents_collector = [_contents_collector emptyCopy];
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* This must work without sending any messages to content objects */
|
||||
- _empty
|
||||
{
|
||||
[_contents_collector empty];
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Override designated initializer for superclass */
|
||||
- initWithType: (const char *)contentEncoding
|
||||
{
|
||||
return [self initWithType:contentEncoding
|
||||
nodeCollector:[[self class] defaultNodeCollectorClass]
|
||||
nodeClass:[[self class] defaultEltNodeClass]];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[_contents_collector release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
// DETERMINING CLASS OF AUTOCREATED NODES;
|
||||
- eltNodeClass
|
||||
{
|
||||
return _node_class;
|
||||
}
|
||||
|
||||
// GETTING THE UNDERLYING COLLECTOR;
|
||||
- contentsCollector
|
||||
{
|
||||
return _contents_collector;
|
||||
}
|
||||
|
||||
// ADDING;
|
||||
|
||||
- makeEltNodeWithElement: (elt)newElement
|
||||
{
|
||||
return [[[self eltNodeClass] alloc]
|
||||
initElement:newElement
|
||||
encoding:[self contentType]];
|
||||
}
|
||||
|
||||
- insertElement: (elt)newElement atIndex: (unsigned)index
|
||||
{
|
||||
unsigned count = [_contents_collector count];
|
||||
CHECK_INDEX_RANGE_ERROR(index, count+1);
|
||||
if (index == count)
|
||||
[_contents_collector
|
||||
appendElement:[self makeEltNodeWithElement:newElement]];
|
||||
else
|
||||
[_contents_collector
|
||||
insertElement:[self makeEltNodeWithElement:newElement]
|
||||
before:[_contents_collector elementAtIndex:index]];
|
||||
return self;
|
||||
}
|
||||
|
||||
- insertElement: (elt)newElement before: (elt)oldElement
|
||||
{
|
||||
id node = [self eltNodeWithElement:oldElement];
|
||||
if (!node)
|
||||
ELEMENT_NOT_FOUND_ERROR(oldElement);
|
||||
[_contents_collector
|
||||
insertElement:[self makeEltNodeWithElement:newElement]
|
||||
before:node];
|
||||
return self;
|
||||
}
|
||||
|
||||
- insertElement: (elt)newElement after: (elt)oldElement
|
||||
{
|
||||
id node = [self eltNodeWithElement:oldElement];
|
||||
if (!node)
|
||||
ELEMENT_NOT_FOUND_ERROR(oldElement);
|
||||
[_contents_collector
|
||||
insertElement:[self makeEltNodeWithElement:newElement]
|
||||
after:node];
|
||||
return self;
|
||||
}
|
||||
|
||||
- appendElement: (elt)newElement
|
||||
{
|
||||
[_contents_collector
|
||||
appendElement:[self makeEltNodeWithElement:newElement]];
|
||||
return self;
|
||||
}
|
||||
|
||||
- prependElement: (elt)newElement
|
||||
{
|
||||
[_contents_collector
|
||||
prependElement:[self makeEltNodeWithElement:newElement]];
|
||||
return self;
|
||||
}
|
||||
|
||||
- addElement: (elt)newElement
|
||||
{
|
||||
[_contents_collector
|
||||
addElement:[self makeEltNodeWithElement:newElement]];
|
||||
return self;
|
||||
}
|
||||
|
||||
// REMOVING SWAPING AND REPLACING;
|
||||
|
||||
- swapAtIndeces: (unsigned)index1 : (unsigned)index2;
|
||||
{
|
||||
CHECK_INDEX_RANGE_ERROR(index1, [_contents_collector count]);
|
||||
CHECK_INDEX_RANGE_ERROR(index2, [_contents_collector count]);
|
||||
[_contents_collector
|
||||
swapAtIndeces:index1 :index2];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (elt) removeElementAtIndex: (unsigned)index
|
||||
{
|
||||
id node;
|
||||
elt ret;
|
||||
|
||||
CHECK_INDEX_RANGE_ERROR(index, [_contents_collector count]);
|
||||
node = [_contents_collector removeElementAtIndex:index].id_u;
|
||||
ret = [node elementData];
|
||||
[node release];
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (elt) removeElement: (elt)oldElement
|
||||
{
|
||||
id aNode = [self eltNodeWithElement:oldElement];
|
||||
elt ret;
|
||||
|
||||
if (!aNode)
|
||||
return ELEMENT_NOT_FOUND_ERROR(oldElement);
|
||||
ret = [aNode elementData];
|
||||
[_contents_collector removeElement:aNode];
|
||||
[aNode release];
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (elt) removeFirstElement
|
||||
{
|
||||
id aNode = [_contents_collector firstElement].id_u;
|
||||
elt ret;
|
||||
|
||||
if (!aNode)
|
||||
return NO_ELEMENT_FOUND_ERROR();
|
||||
ret = [aNode elementData];
|
||||
[_contents_collector removeElement:aNode];
|
||||
[aNode release];
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (elt) removeLastElement
|
||||
{
|
||||
id aNode = [_contents_collector lastElement].id_u;
|
||||
elt ret;
|
||||
|
||||
if (!aNode)
|
||||
return NO_ELEMENT_FOUND_ERROR();
|
||||
ret = [aNode elementData];
|
||||
[_contents_collector removeElement:aNode];
|
||||
[aNode release];
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (elt) replaceElement: (elt)oldElement with: (elt)newElement
|
||||
{
|
||||
id aNode = [self eltNodeWithElement:oldElement];
|
||||
elt ret;
|
||||
|
||||
if (!aNode)
|
||||
return ELEMENT_NOT_FOUND_ERROR(oldElement);
|
||||
ret = [aNode elementData];
|
||||
[_contents_collector replaceElement:aNode
|
||||
with:[self makeEltNodeWithElement:newElement]];
|
||||
[aNode release];
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (elt) replaceElementAtIndex: (unsigned)index with: (elt)newElement
|
||||
{
|
||||
elt ret;
|
||||
elt oldNode;
|
||||
|
||||
CHECK_INDEX_RANGE_ERROR(index, [_contents_collector count]);
|
||||
oldNode = [_contents_collector
|
||||
replaceElementAtIndex:index
|
||||
with:[self makeEltNodeWithElement:newElement]];
|
||||
ret = [oldNode.id_u elementData];
|
||||
[oldNode.id_u release];
|
||||
return ret;
|
||||
}
|
||||
|
||||
// GETTING ELEMENTS BY INDEX;
|
||||
|
||||
- (elt) elementAtIndex: (unsigned)index
|
||||
{
|
||||
CHECK_INDEX_RANGE_ERROR(index, [_contents_collector count]);
|
||||
return [[_contents_collector elementAtIndex:index].id_u elementData];
|
||||
}
|
||||
|
||||
// TESTING;
|
||||
|
||||
- eltNodeWithElement: (elt)anElement
|
||||
{
|
||||
int (*cf)(elt,elt) = [self comparisonFunction];
|
||||
elt err_ret;
|
||||
elt err(arglist_t argFrame)
|
||||
{
|
||||
return err_ret;
|
||||
}
|
||||
BOOL test(elt node)
|
||||
{
|
||||
if (!((*cf)([node.id_u elementData], anElement)))
|
||||
return YES;
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
err_ret.id_u = nil;
|
||||
return [_contents_collector detectElementByCalling:test
|
||||
ifNoneCall:err].id_u;
|
||||
}
|
||||
|
||||
- (unsigned) count
|
||||
{
|
||||
return [_contents_collector count];
|
||||
}
|
||||
|
||||
|
||||
// ENUMERATING;
|
||||
|
||||
- (BOOL) getNextElement:(elt *)anElementPtr withEnumState: (void**)enumState
|
||||
{
|
||||
elt node;
|
||||
BOOL flag;
|
||||
|
||||
flag = [_contents_collector getNextElement:&node withEnumState:enumState];
|
||||
if (flag)
|
||||
*anElementPtr = [node.id_u elementData];
|
||||
return flag;
|
||||
}
|
||||
|
||||
- (void*) newEnumState
|
||||
{
|
||||
return [_contents_collector newEnumState];
|
||||
}
|
||||
|
||||
- freeEnumState: (void**)enumState
|
||||
{
|
||||
[_contents_collector freeEnumState:enumState];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) getPrevElement:(elt *)anElementPtr withEnumState: (void**)enumState
|
||||
{
|
||||
elt node;
|
||||
BOOL flag;
|
||||
|
||||
flag = [_contents_collector getPrevElement:&node withEnumState:enumState];
|
||||
if (flag)
|
||||
*anElementPtr = [node.id_u elementData];
|
||||
return flag;
|
||||
}
|
||||
|
||||
- withElementsCall: (void(*)(elt))aFunc whileTrue:(BOOL *)flag
|
||||
{
|
||||
void doIt(elt node)
|
||||
{
|
||||
(*aFunc)([node.id_u elementData]);
|
||||
}
|
||||
[_contents_collector withElementsCall:doIt whileTrue:flag];
|
||||
return self;
|
||||
}
|
||||
|
||||
- withElementsInReverseCall: (void(*)(elt))aFunc whileTrue:(BOOL *)flag
|
||||
{
|
||||
void doIt(elt node)
|
||||
{
|
||||
(*aFunc)([node.id_u elementData]);
|
||||
}
|
||||
[_contents_collector withElementsInReverseCall:doIt whileTrue:flag];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (const char *) contentType
|
||||
{
|
||||
return elt_get_encoding(_comparison_function);
|
||||
}
|
||||
|
||||
- (int(*)(elt,elt)) comparisonFunction
|
||||
{
|
||||
return _comparison_function;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/* Implementation for Objective-C LinkedListEltNode object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/LinkedListEltNode.h>
|
||||
#include <gnustep/base/Coder.h>
|
||||
|
||||
@implementation LinkedListEltNode
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [LinkedListEltNode class])
|
||||
[self setVersion:0]; /* beta release */
|
||||
}
|
||||
|
||||
#include <gnustep/base/EltNode-m>
|
||||
|
||||
@end
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
#include <remote/MethodSignature.h>
|
||||
|
||||
static int
|
||||
types_get_size_of_arguments(const char *types)
|
||||
{
|
||||
const char* type = objc_skip_typespec (types);
|
||||
return atoi (type);
|
||||
}
|
||||
|
||||
static int
|
||||
types_get_number_of_arguments (const char *types)
|
||||
{
|
||||
int i = 0;
|
||||
const char* type = types;
|
||||
while (*type)
|
||||
{
|
||||
type = objc_skip_argspec (type);
|
||||
i += 1;
|
||||
}
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
|
||||
@implementation MethodSignature
|
||||
|
||||
+ fromDescription:(struct objc_method_description *)omd
|
||||
fromZone:(NXZone *)aZone
|
||||
{
|
||||
MethodSignature *newMs = [[MethodSignature alloc] init];
|
||||
newMs->sig = *omd;
|
||||
newMs->selName = (char*)sel_get_name(omd->name);
|
||||
newMs->nargs = types_get_number_of_arguments(omd->types);
|
||||
newMs->sizeofParams = types_get_size_of_arguments(omd->types);
|
||||
return newMs;
|
||||
}
|
||||
|
||||
- encodeMethodParams:(arglist_t)argFrame onto:(id <NXEncoding>)portal
|
||||
{
|
||||
char *datum;
|
||||
const char *type;
|
||||
unsigned flags;
|
||||
|
||||
for (type = sig.types;
|
||||
(datum = method_get_next_argument(argFrame, &type));)
|
||||
{
|
||||
flags = objc_get_type_qualifiers(type);
|
||||
type = objc_skip_type_qualifiers(type);
|
||||
[portal encodeData:datum ofType:type];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (arglist_t) decodeMethodParamsFrom: (id <NXDecoding>)portal
|
||||
{
|
||||
arglist_t argFrame = 0; //(marg_list) malloc(sizeofParams);
|
||||
char *datum;
|
||||
const char *type;
|
||||
unsigned flags;
|
||||
|
||||
for (type = sig.types;
|
||||
(datum = method_get_next_argument(argFrame, &type));)
|
||||
{
|
||||
flags = objc_get_type_qualifiers(type);
|
||||
type = objc_skip_type_qualifiers(type);
|
||||
[portal decodeData:datum ofType:type];
|
||||
}
|
||||
return argFrame;
|
||||
}
|
||||
|
||||
#define ENCODE_RET(RETVAL,TYPE) \
|
||||
do { \
|
||||
TYPE __r (void* __rf) {__builtin_return(__rf);} \
|
||||
TYPE __tmp = __r(RETVAL); \
|
||||
[portal encodeData:&__tmp ofType:sig.types]; \
|
||||
} while(0);
|
||||
|
||||
/* Note: NeXT's direct passing of the ret value instead of a
|
||||
pointer to the ret value means we can't return doubles.
|
||||
I'm improving on this by passing a pointer what's
|
||||
returns from __builtin_apply() */
|
||||
- encodeMethodRet: retframe
|
||||
withargs:(void *)argFrame
|
||||
onto:(id <NXEncoding>)portal
|
||||
{
|
||||
/* NOTE: we don't yet handle changing values passed by reference */
|
||||
switch (*sig.types)
|
||||
{
|
||||
case _C_CHR:
|
||||
case _C_UCHR:
|
||||
ENCODE_RET(retframe, char);
|
||||
break;
|
||||
case _C_SHT:
|
||||
case _C_USHT:
|
||||
ENCODE_RET(retframe, short);
|
||||
break;
|
||||
case _C_INT:
|
||||
case _C_UINT:
|
||||
ENCODE_RET(retframe, int);
|
||||
break;
|
||||
case _C_LNG:
|
||||
case _C_ULNG:
|
||||
ENCODE_RET(retframe, int);
|
||||
break;
|
||||
case _C_FLT:
|
||||
ENCODE_RET(retframe, float);
|
||||
break;
|
||||
case _C_DBL:
|
||||
ENCODE_RET(retframe, double);
|
||||
break;
|
||||
default:
|
||||
[self error:"Can't handle type %s", sig.types];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/* In my version this actually returns the void* to be given to
|
||||
__builtin_return. I'm not sure what NeXT's version does */
|
||||
|
||||
- decodeMethodRetFrom:(id <NXDecoding>)portal
|
||||
withargs:(void *)aVoidPtr
|
||||
{
|
||||
//#warning this should be sizeof return
|
||||
void *datum = malloc(32); /* this should be sizeof return */
|
||||
[portal decodeData:datum ofType:sig.types];
|
||||
return datum;
|
||||
}
|
||||
|
||||
- (BOOL) isOneway
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -1,356 +0,0 @@
|
|||
/* Implementation of Objective-C method-name-compatible NXConnection
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <remote/NXConnection.h>
|
||||
#include <remote/NXProxy.h>
|
||||
#include <gnustep/base/ConnectedCoder.h>
|
||||
#include <assert.h>
|
||||
|
||||
static Class NXConnectionProxyClass;
|
||||
|
||||
/* Just to make -encodeRemotelyFor:... work */
|
||||
@interface NXConnectedCoder : ConnectedCoder
|
||||
- (void) _doEncodeObject: anObj;
|
||||
@end
|
||||
|
||||
@implementation NXConnection
|
||||
|
||||
+ initialize
|
||||
{
|
||||
if ([self class] == [NXConnection class])
|
||||
NXConnectionProxyClass = [NXProxy class];
|
||||
return self;
|
||||
}
|
||||
|
||||
+ connections: aList
|
||||
{
|
||||
id cs = [Connection allConnections];
|
||||
void add_to_aList(id c)
|
||||
{
|
||||
[aList addObject:c];
|
||||
}
|
||||
[cs withObjectsCall:add_to_aList];
|
||||
[cs release];
|
||||
return self;
|
||||
}
|
||||
|
||||
+ setDefaultProxyClass: (Class)aClass
|
||||
{
|
||||
NXConnectionProxyClass = aClass;
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (Class) defaultProxyClass
|
||||
{
|
||||
return NXConnectionProxyClass;
|
||||
}
|
||||
|
||||
+ (NXZone*) defaultZone
|
||||
{
|
||||
return NX_NOZONE;
|
||||
}
|
||||
|
||||
+ setDefaultZone: (NXZone *)z
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (int) defaultTimeout
|
||||
{
|
||||
/* not correct, but it will do for now. */
|
||||
return [self defaultInTimeout];
|
||||
}
|
||||
|
||||
+ setDefaultTimeout: (int)to
|
||||
{
|
||||
/* not correct, but it will do for now. */
|
||||
return [self setDefaultInTimeout:to];
|
||||
}
|
||||
|
||||
+ registerRoot: anObj fromZone: (NXZone*)z
|
||||
{
|
||||
return [Connection newWithRootObject:anObj];
|
||||
}
|
||||
|
||||
+ registerRoot: anObj
|
||||
{
|
||||
return [self registerRoot:anObj fromZone:NX_NOZONE];
|
||||
}
|
||||
|
||||
+ registerRoot: anObj withName: (char*)n fromZone: (NXZone*)z
|
||||
{
|
||||
return [Connection newRegisteringAtName:n withRootObject:anObj];
|
||||
}
|
||||
|
||||
+ registerRoot: anObj withName: (char*)n
|
||||
{
|
||||
return [self registerRoot:anObj withName:n fromZone:NX_NOZONE];
|
||||
}
|
||||
|
||||
+ connectToPort: aPort fromZone: (NXZone*)z
|
||||
{
|
||||
return [Connection rootProxyAtPort:aPort];
|
||||
}
|
||||
|
||||
+ connectToPort: aPort
|
||||
{
|
||||
return [self connectToPort:aPort fromZone:NX_NOZONE];
|
||||
}
|
||||
|
||||
+ connectToPort: aPort withInPort: anInPort fromZone: (NXZone*)z
|
||||
{
|
||||
return [Connection rootProxyAtPort:aPort withInPort:anInPort];
|
||||
}
|
||||
|
||||
+ connectToPort: aPort withInPort: anInPort
|
||||
{
|
||||
return [self connectToPort:aPort withInPort:anInPort fromZone:NX_NOZONE];
|
||||
}
|
||||
|
||||
+ connectToName: (char*)n onHost: (char*)h fromZone: (NXZone*)z
|
||||
{
|
||||
return [Connection rootProxyAtName:n onHost:h];
|
||||
}
|
||||
|
||||
+ connectToName: (char*)n fromZone: (NXZone*)z
|
||||
{
|
||||
return [Connection rootProxyAtName:n];
|
||||
}
|
||||
|
||||
+ connectToName: (char*)n onHost: (char*)h
|
||||
{
|
||||
return [self connectToName:n onHost:h fromZone:NX_NOZONE];
|
||||
}
|
||||
|
||||
+ connectToName: (char*)n
|
||||
{
|
||||
return [self connectToName:n fromZone:NX_NOZONE];
|
||||
}
|
||||
|
||||
+ (unsigned) count
|
||||
{
|
||||
return [Connection connectionsCount];
|
||||
}
|
||||
|
||||
- runInNewThread
|
||||
{
|
||||
return [self notImplemented:_cmd];
|
||||
}
|
||||
|
||||
- removeLocal: anObj
|
||||
{
|
||||
return [self removeLocalObject:anObj];
|
||||
}
|
||||
|
||||
- removeRemote: anObj
|
||||
{
|
||||
return [self removeProxy:anObj];
|
||||
}
|
||||
|
||||
- (List*) localObjects
|
||||
{
|
||||
id aList = [[List alloc] init];
|
||||
id cs = [self localObjects];
|
||||
void add_to_aList(id c)
|
||||
{
|
||||
[aList addObject:c];
|
||||
}
|
||||
[cs withObjectsCall:add_to_aList];
|
||||
[cs release];
|
||||
return aList;
|
||||
}
|
||||
|
||||
- (List*) remoteObjects
|
||||
{
|
||||
id aList = [[List alloc] init];
|
||||
id cs = [self proxies];
|
||||
void add_to_aList(id c)
|
||||
{
|
||||
[aList addObject:c];
|
||||
}
|
||||
[cs withObjectsCall:add_to_aList];
|
||||
[cs release];
|
||||
return aList;
|
||||
}
|
||||
|
||||
- getLocal: anObj
|
||||
{
|
||||
return [self notImplemented:_cmd];
|
||||
}
|
||||
|
||||
- getRemote: (unsigned)aName
|
||||
{
|
||||
return [self proxyForTarget:aName];
|
||||
}
|
||||
|
||||
- newLocal: anObj
|
||||
{
|
||||
return [self notImplemented:_cmd];
|
||||
}
|
||||
|
||||
- newRemote: (unsigned)r withProtocol: aProtocol
|
||||
{
|
||||
return [[self proxyClass] newForRemote:r connection:self];
|
||||
}
|
||||
|
||||
- insertProxy: anObj
|
||||
{
|
||||
return [self addProxy:anObj];
|
||||
}
|
||||
|
||||
- setRoot: anObj
|
||||
{
|
||||
return [self setRootObject:anObj];
|
||||
}
|
||||
|
||||
- (Class) proxyClass
|
||||
{
|
||||
/* we might replace this with a per-Connection proxy class. */
|
||||
return NXConnectionProxyClass;
|
||||
}
|
||||
|
||||
- (Class) coderClass
|
||||
{
|
||||
return [NXConnectedCoder class];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation Object (NXConnectionCompatibility)
|
||||
|
||||
- encodeRemotelyFor: (NXConnection*)conn
|
||||
freeAfterEncoding: (BOOL*)fp
|
||||
isBycopy: (BOOL)f;
|
||||
{
|
||||
if (f)
|
||||
return self;
|
||||
return [[conn proxyClass] newBogusLocal:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NXConnectedCoder
|
||||
|
||||
- encodeData:(void *)data ofType:(const char *)type
|
||||
{
|
||||
[self encodeValueOfObjCType:type at:data withName:NULL];
|
||||
return self;
|
||||
}
|
||||
|
||||
- encodeBytes:(const void *)bytes count:(int)count
|
||||
{
|
||||
char types[16];
|
||||
sprintf(types, "[%dc]", count);
|
||||
[self encodeValueOfObjCType:types at:bytes withName:NULL];
|
||||
return self;
|
||||
}
|
||||
|
||||
- encodeVM:(const void *)bytes count:(int)count
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return self;
|
||||
}
|
||||
|
||||
- encodeMachPort:(port_t)port
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return self;
|
||||
}
|
||||
|
||||
- encodeObject:anObject
|
||||
{
|
||||
[self encodeObject:anObject withName:NULL];
|
||||
return self;
|
||||
}
|
||||
|
||||
- encodeObjectBycopy:anObject
|
||||
{
|
||||
[self encodeObjectBycopy:anObject withName:NULL];
|
||||
return self;
|
||||
}
|
||||
|
||||
- decodeData:(void *)d ofType:(const char *)t
|
||||
{
|
||||
[self decodeValueOfObjCType:t at:d withName:NULL];
|
||||
return self;
|
||||
}
|
||||
|
||||
- decodeBytes:(void *)bytes count:(int)count
|
||||
{
|
||||
char types[16];
|
||||
sprintf(types, "[%dc]", count);
|
||||
[self decodeValueOfObjCType:types at:bytes withName:NULL];
|
||||
return self;
|
||||
}
|
||||
|
||||
- decodeVM:(void **)bytes count:(int *)count
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return self;
|
||||
}
|
||||
|
||||
- decodeMachPort:(port_t *)pp
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return self;
|
||||
}
|
||||
|
||||
/* WARNING: This won't work if the object is a GNU forward object reference */
|
||||
- (id) decodeObject
|
||||
{
|
||||
id o;
|
||||
[self decodeObjectAt:&o withName:NULL];
|
||||
return o;
|
||||
}
|
||||
|
||||
- (void) _doEncodeObject: anObj isByCopy: (BOOL)bc
|
||||
{
|
||||
BOOL f = NO;
|
||||
Class *c;
|
||||
id o;
|
||||
|
||||
assert([[self connection] class] == [NXConnection class]);
|
||||
o = [anObj encodeRemotelyFor:(NXConnection*)[self connection]
|
||||
freeAfterEncoding:&f
|
||||
isBycopy:bc];
|
||||
c = [o classForConnectedCoder:self];
|
||||
[self encodeClass:c];
|
||||
[c encodeObject:o withConnectedCoder:self];
|
||||
if (f)
|
||||
[anObj free];
|
||||
[o free];
|
||||
}
|
||||
|
||||
- (void) _doEncodeBycopyObject: anObj
|
||||
{
|
||||
[self _doEncodeObject:anObj isByCopy:YES];
|
||||
}
|
||||
|
||||
- (void) _doEncodeObject: anObj
|
||||
{
|
||||
[self _doEncodeObject:anObj isByCopy:NO];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,59 +0,0 @@
|
|||
/* Implementation of Objective-C NeXT-compatible NXProtocolChecker object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@cs.rochester.edu>
|
||||
Dept. of Computer Science, U. of Rochester, Rochester, NY 14627
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <machkit/NXProtocolChecker.h>
|
||||
|
||||
@implementation NXProtocolChecker
|
||||
{
|
||||
id target;
|
||||
id protocol;
|
||||
}
|
||||
|
||||
- initWithObject: anObj forProtocol: aProtocol
|
||||
{
|
||||
[super init];
|
||||
target = anObj;
|
||||
protocol = aProtocol;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) conformsTo: aProtocol
|
||||
{
|
||||
return [protocol conformsTo:aProtocol];
|
||||
}
|
||||
|
||||
- (struct objc_method_description *) descriptionForMethod: (SEL)aSel
|
||||
{
|
||||
return [protocol descriptionForMethod:aSel];
|
||||
}
|
||||
|
||||
- forward: (SEL)aSel :(arglist_t)frame
|
||||
{
|
||||
if ([protocol descriptionForMethod:aSel])
|
||||
return [target performv:aSel :frame];
|
||||
/* Fix this */
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,83 +0,0 @@
|
|||
/* Implementation of Objective-C method-name-compatible NXProxy
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <remote/NXProxy.h>
|
||||
#include <objc/objc-api.h>
|
||||
#include <assert.h>
|
||||
|
||||
@implementation NXProxy
|
||||
|
||||
- addReference
|
||||
{
|
||||
[self retain];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (unsigned) references
|
||||
{
|
||||
return [self retainCount] + 1;
|
||||
}
|
||||
|
||||
- (unsigned) nameForProxy
|
||||
{
|
||||
return [self targetForProxy];
|
||||
}
|
||||
|
||||
- freeProxy
|
||||
{
|
||||
[self dealloc];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- free
|
||||
{
|
||||
/* xxx Is this what we want? */
|
||||
return [self freeProxy];
|
||||
}
|
||||
|
||||
- setProtocolForProxy: (Protocol*)aProtocol
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- encodeRemotelyFor: (NXConnection*)conn
|
||||
freeAfterEncoding: (BOOL*)fp
|
||||
isBycopy: (BOOL)f;
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
/* GNU Connection doesn't use local proxies, but in order for us to have
|
||||
compatibility with NeXT's -encodeRemotelyFor:freeAfterEncoding:isBycopy
|
||||
we have to do this ugly thing. */
|
||||
+ newBogusLocal: (id)anObject
|
||||
{
|
||||
NXProxy *newProxy = class_create_instance([NXProxy class]);
|
||||
newProxy->target = PTR2LONG(anObject);
|
||||
return newProxy;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
/* Implementation of object for queuing Notification objects
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Created: March 1996
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* The implementation for NotificationDispatcher. */
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/NotificationQueue.h>
|
||||
#include <gnustep/base/Notification.h>
|
||||
#include <gnustep/base/LinkedListNode.h>
|
||||
#include <gnustep/base/Array.h>
|
||||
#include <gnustep/base/Invocation.h>
|
||||
#include <Foundation/NSException.h>
|
||||
|
||||
@implementation NotificationQueue
|
||||
|
||||
/* This is the default initialzer. */
|
||||
- initWithNotificationDistributor: nd
|
||||
{
|
||||
[super init];
|
||||
_notification_distributor = nd;
|
||||
_asap_queue = [Queue new];
|
||||
_idle_queue = [Queue new];
|
||||
return self;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
return [self initWithNotificationDistributor:
|
||||
[NotificationDistributor defaultInstance]];
|
||||
}
|
||||
|
||||
- (void) dequeueNotificationsMatching: notification
|
||||
coalesceMask: (unsigned)mask
|
||||
{
|
||||
/* Remove from the queues notifications that match NOTIFICATION, according
|
||||
the the MASK. */
|
||||
/* xxx This method should be made much more efficient. Currently, it
|
||||
could be a big bottleneck. */
|
||||
void remove_matching_from_queue (Queue *q)
|
||||
{
|
||||
int i;
|
||||
for (i = [q count] - 1; i >= 0; i--)
|
||||
{
|
||||
id n = [q objectAtIndex: i];
|
||||
/* If the aspects that need to match do match... */
|
||||
if (( !(mask & NSNotificationCoalescingOnName)
|
||||
|| [[notification name] isEqual: [n name]])
|
||||
&&
|
||||
( !(mask & NSNotificationCoalescingOnSender)
|
||||
|| [[notification object] isEqual: [n object]]))
|
||||
/* ...then remove it. */
|
||||
[q removeObjectAtIndex: i];
|
||||
}
|
||||
}
|
||||
remove_matching_from_queue (_asap_queue);
|
||||
remove_matching_from_queue (_idle_queue);
|
||||
}
|
||||
|
||||
- (void) enqueueNotification: notification
|
||||
postingStyle: (NSPostingStyle)style
|
||||
coalesceMask: (unsigned)mask
|
||||
forModes: (id <ConstantCollecting>)modes
|
||||
{
|
||||
[self dequeueNotificationsMatching: notification
|
||||
coalesceMask: mask];
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case NSPostIdle:
|
||||
[_idle_queue enqueueObject: notification];
|
||||
break;
|
||||
case NSPostASAP:
|
||||
[_asap_queue enqueueObject: notification];
|
||||
break;
|
||||
case NSPostNow:
|
||||
if ([modes containsObject: [RunLoop mode]])
|
||||
[_notification_distributor postNotification: notification];
|
||||
else
|
||||
/* xxx This is the correct behavior? */
|
||||
[_asap_queue enqueueObject: notification];
|
||||
break;
|
||||
default:
|
||||
[self error: "Bad posting style."];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) enqueueNotification: notification
|
||||
postingStyle: (NSPostingStyle)style
|
||||
{
|
||||
[self enqueueNotification: notification
|
||||
postingStyle: style
|
||||
coalesceMask: (NSNotificationCoalescingOnName
|
||||
| NSNotificationCoalescingOnSender)
|
||||
modes: nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) postNotificationsWithASAPStyle
|
||||
{
|
||||
id n;
|
||||
int i, c = [_asap_queue count];
|
||||
|
||||
for (i = 0; i < c; i++)
|
||||
[_notification_dispatcher postNotification:
|
||||
[_idle_queue objectAtIndex: i]];
|
||||
[_asap_queue empty];
|
||||
}
|
||||
|
||||
- (void) postNotificationWithIdleStyle
|
||||
{
|
||||
id n = [_idle_queue dequeueObject];
|
||||
[_notification_dispatcher postNotification: n];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,127 +0,0 @@
|
|||
/* Implementation of retaining/releasing for object disposal and ref counting
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: August 1994
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/ObjectRetaining.h>
|
||||
#include <gnustep/base/collhash.h>
|
||||
#include <gnustep/base/eltfuncs.h>
|
||||
#include <gnustep/base/objc-malloc.h>
|
||||
#include <gnustep/base/AutoreleasePool.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* Doesn't handle multi-threaded stuff.
|
||||
Doesn't handle exceptions. */
|
||||
|
||||
/* The hashtable of retain counts on objects */
|
||||
static coll_cache_ptr retain_counts = NULL;
|
||||
|
||||
/* The Class responsible for handling autorelease's */
|
||||
id autorelease_class = nil;
|
||||
|
||||
static void
|
||||
init_retain_counts_if_necessary()
|
||||
{
|
||||
/* Initialize if we haven't done it yet */
|
||||
if (!retain_counts)
|
||||
{
|
||||
retain_counts = coll_hash_new(64,
|
||||
(coll_hash_func_type)
|
||||
elt_hash_void_ptr,
|
||||
(coll_compare_func_type)
|
||||
elt_compare_void_ptrs);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
objc_retain_object (id anObj)
|
||||
{
|
||||
coll_node_ptr n;
|
||||
|
||||
init_retain_counts_if_necessary();
|
||||
n = coll_hash_node_for_key(retain_counts, anObj);
|
||||
if (n)
|
||||
(n->value.unsigned_int_u)++;
|
||||
else
|
||||
coll_hash_add(&retain_counts, anObj, (unsigned)1);
|
||||
}
|
||||
|
||||
void
|
||||
objc_release_object (id anObj)
|
||||
{
|
||||
coll_node_ptr n;
|
||||
|
||||
init_retain_counts_if_necessary();
|
||||
n = coll_hash_node_for_key(retain_counts, anObj);
|
||||
if (n)
|
||||
{
|
||||
(n->value.unsigned_int_u)--;
|
||||
if (n->value.unsigned_int_u)
|
||||
return;
|
||||
coll_hash_remove(retain_counts, anObj);
|
||||
}
|
||||
[anObj dealloc];
|
||||
}
|
||||
|
||||
/* Careful, this doesn't include autoreleases */
|
||||
unsigned
|
||||
objc_retain_count (id anObj)
|
||||
{
|
||||
coll_node_ptr n;
|
||||
|
||||
init_retain_counts_if_necessary();
|
||||
n = coll_hash_node_for_key(retain_counts, anObj);
|
||||
if (n)
|
||||
return n->value.unsigned_int_u;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@implementation Object (RetainingObject)
|
||||
|
||||
- retain
|
||||
{
|
||||
objc_retain_object(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (oneway void) release
|
||||
{
|
||||
objc_release_object(self);
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
object_dispose(self);
|
||||
}
|
||||
|
||||
- (unsigned) retainCount
|
||||
{
|
||||
return objc_retain_count(self);
|
||||
}
|
||||
|
||||
- autorelease
|
||||
{
|
||||
[autorelease_class autoreleaseObject:self];
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,43 +0,0 @@
|
|||
|
||||
@interface ProtocolEnforcer
|
||||
{
|
||||
id target;
|
||||
Protocol *protocol;
|
||||
}
|
||||
|
||||
- initWithProtocol: aProtocol target: anObj;
|
||||
|
||||
- (BOOL) conformsTo: aProtocol;
|
||||
- forward: (SEL)sel :(arglist_t)frame;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ProtocolEnforcer
|
||||
|
||||
- initWithProtocol: aProtocol target: anObj
|
||||
{
|
||||
[super init];
|
||||
protocol = aProtocol;
|
||||
target = anObj;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) conformsTo: aProtocol
|
||||
{
|
||||
if (aProtocol == protocol)
|
||||
return YES;
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (retval_t) forward: (SEL)sel :(arglist_t)frame
|
||||
{
|
||||
if ([protocol descriptionForInstanceMethod:sel])
|
||||
return [target performv:sel :frame];
|
||||
else
|
||||
#warning Fix this
|
||||
return
|
||||
[self error:"We should punish the remote connection not the local one"];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,36 +0,0 @@
|
|||
/* Implementation for Objective-C RBTreeEltNode objects
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/RBTreeEltNode.h>
|
||||
|
||||
@implementation RBTreeEltNode
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [RBTreeEltNode class])
|
||||
[self setVersion:0]; /* beta release */
|
||||
}
|
||||
|
||||
#include <gnustep/base/EltNode-m>
|
||||
|
||||
@end
|
|
@ -1,76 +0,0 @@
|
|||
|
||||
static unsigned released_capacity = 0;
|
||||
static unsigned released_index = 0;
|
||||
static id *released_objects = NULL;
|
||||
static void **released_stack_pointers = NULL;
|
||||
|
||||
#define DEFAULT_SIZE 64
|
||||
|
||||
static void *s1, *s2;
|
||||
static void unsigned stack_release_offset;
|
||||
static void init_stack_release()
|
||||
{
|
||||
s1 = get_stack();
|
||||
[Object _stackReleaseTest];
|
||||
stack_release_offset = s2 - s1;
|
||||
released_capacity = DEFAULT_SIZE;
|
||||
OBJC_MALLOC(released_objects, id, released_capacity);
|
||||
OBJC_MALLOC(released_stack_pointers, void*, released_capacity);
|
||||
}
|
||||
|
||||
static void*
|
||||
get_stack()
|
||||
{
|
||||
int i;
|
||||
return &i;
|
||||
}
|
||||
|
||||
static inline void
|
||||
grow_released_arrays()
|
||||
{
|
||||
if (index == released_capacity)
|
||||
{
|
||||
released_capacity *= 2;
|
||||
OBJC_REALLOC(released_objects, id, released_capacity);
|
||||
OBJC_REALLOC(released_stack_pointers, void*, released_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
@implementation Object (Releasing)
|
||||
|
||||
+ _stackReleaseTest
|
||||
{
|
||||
s2 = get_stack();
|
||||
}
|
||||
|
||||
- stackRelease
|
||||
/* - releaseLater */
|
||||
{
|
||||
static init_done = 0;
|
||||
|
||||
/* Initialize if we haven't done it yet */
|
||||
if (!init_done)
|
||||
{
|
||||
init_stack_release();
|
||||
init_done = 1;
|
||||
}
|
||||
|
||||
/* Do the pending releases of other objects */
|
||||
/* xxx This assumes stack grows up */
|
||||
while ((released_stack_pointers[released_index]
|
||||
> (get_stack() - stack_release_offset))
|
||||
&& released_index)
|
||||
{
|
||||
[released_objects[released_index] release];
|
||||
released_index--;
|
||||
}
|
||||
|
||||
/* Queue this object for later release */
|
||||
released_index++;
|
||||
grow_released_arrays();
|
||||
released_objects[released_index] = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,138 +0,0 @@
|
|||
/* Implementation of reference-counted invalidation notifer object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: July 1994
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Reference Counted object with invalidation notification
|
||||
This object is just temporary. Eventually, we should separate
|
||||
reference counting functionality from notification functionality */
|
||||
|
||||
#include <gnustep/base/RetainingNotifier.h>
|
||||
#include <gnustep/base/InvalidationListening.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Use this for now, but GNU should switch to a GC pool
|
||||
and separate notification. */
|
||||
|
||||
/* I really need to check the use of locks here */
|
||||
|
||||
@implementation RetainingNotifier
|
||||
|
||||
- init
|
||||
{
|
||||
retain_count = 0;
|
||||
isValid = YES;
|
||||
refGate = [[Lock alloc] init];
|
||||
notificationList = [[List alloc] init];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[refGate release];
|
||||
[notificationList free];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (oneway void) release
|
||||
{
|
||||
[refGate lock];
|
||||
if (retain_count--)
|
||||
{
|
||||
[refGate unlock];
|
||||
return;
|
||||
}
|
||||
[refGate unlock];
|
||||
[self dealloc];
|
||||
return;
|
||||
}
|
||||
|
||||
- (id) retain
|
||||
{
|
||||
[refGate lock];
|
||||
retain_count++;
|
||||
[refGate unlock];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (unsigned) retainCount
|
||||
{
|
||||
return retain_count;
|
||||
}
|
||||
|
||||
/* xxx Deal with this. */
|
||||
- autorelease
|
||||
{
|
||||
return [super autorelease];
|
||||
}
|
||||
|
||||
- registerForInvalidationNotification: (id <InvalidationListening>)anObject
|
||||
{
|
||||
assert(refGate);
|
||||
[refGate lock];
|
||||
[notificationList addObjectIfAbsent: anObject];
|
||||
[refGate unlock];
|
||||
return self;
|
||||
}
|
||||
|
||||
- unregisterForInvalidationNotification: (id <InvalidationListening>)anObject
|
||||
{
|
||||
assert(refGate);
|
||||
[refGate lock];
|
||||
[notificationList removeObject: anObject];
|
||||
[refGate unlock];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) isValid
|
||||
{
|
||||
return isValid;
|
||||
}
|
||||
|
||||
/* change name to -postInvalidation */
|
||||
- invalidate
|
||||
{
|
||||
if (isValid == NO)
|
||||
return nil;
|
||||
[refGate lock];
|
||||
isValid = NO;
|
||||
[notificationList makeObjectsPerform:@selector(senderIsInvalid:) with:self];
|
||||
[refGate unlock];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- copy
|
||||
{
|
||||
RetainingNotifier *newCopy = nil;
|
||||
|
||||
if (isValid)
|
||||
{
|
||||
[refGate lock];
|
||||
newCopy = [[[self class] alloc] init];
|
||||
[newCopy->notificationList appendList:notificationList];
|
||||
newCopy->retain_count = retain_count;
|
||||
[refGate unlock];
|
||||
}
|
||||
return newCopy;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,5 +0,0 @@
|
|||
/* Ring.m - a fixed-length circular array */
|
||||
|
||||
@implementation Ring
|
||||
|
||||
@end
|
1023
Source/RunLoop.m
1023
Source/RunLoop.m
File diff suppressed because it is too large
Load diff
|
@ -1,469 +0,0 @@
|
|||
/* Implementation of socket-based port object for use with Connection
|
||||
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: July 1994
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/SocketPort.h>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <netdb.h>
|
||||
#include <sys/time.h>
|
||||
#endif /* !WIN32 */
|
||||
|
||||
#include <objc/o_hash.h>
|
||||
#include <gnustep/base/Lock.h>
|
||||
#include <objc/List.h>
|
||||
#include <gnustep/base/Connection.h>
|
||||
#include <gnustep/base/Coder.h>
|
||||
#include <gnustep/base/ConnectedCoder.h>
|
||||
#include <gnustep/base/String.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if _AIX
|
||||
#include <sys/select.h>
|
||||
#endif /* _AIX */
|
||||
|
||||
/* Deal with bcopy: */
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
#include <string.h>
|
||||
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
|
||||
#if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#define bcopy(s, d, n) memcpy ((d), (s), (n))
|
||||
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
|
||||
#define bzero(s, n) memset ((s), 0, (n))
|
||||
#else /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
#include <strings.h>
|
||||
/* memory.h and strings.h conflict on some systems. */
|
||||
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
|
||||
/* Make this a hashtable? */
|
||||
static List* socketPortList;
|
||||
static Lock* socketPortListGate;
|
||||
|
||||
static BOOL socket_port_debug = NO;
|
||||
|
||||
/* xxx This function is just temporary.
|
||||
Eventually we should write a real name server for sockets */
|
||||
static unsigned int
|
||||
name_to_port_number (const char *name)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
unsigned int ctr = 0;
|
||||
|
||||
while (*name)
|
||||
{
|
||||
ret ^= *name++ << ctr;
|
||||
ctr = (ctr + 1) % sizeof (void *);
|
||||
}
|
||||
return ret % (65535 - IPPORT_USERRESERVED - 1);
|
||||
}
|
||||
|
||||
@implementation SocketPort
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if ([self class] == [SocketPort class])
|
||||
{
|
||||
socketPortList = [[List alloc] init];
|
||||
socketPortListGate = [Lock new];
|
||||
}
|
||||
}
|
||||
|
||||
+ setDebug: (BOOL)f
|
||||
{
|
||||
socket_port_debug = f;
|
||||
return self;
|
||||
}
|
||||
|
||||
+ newPortFromRegisterWithName: (NSString*)name onHost: (NSString*)h
|
||||
{
|
||||
id p;
|
||||
int n;
|
||||
|
||||
#if SOCKETPORT_NUMBER_NAMES_ONLY
|
||||
if ((n = atoi([name cString])) == 0)
|
||||
[self error:"Name (%s) is not a number", [name cString]];
|
||||
#else
|
||||
n = name_to_port_number([name cString]);
|
||||
#endif
|
||||
p = [SocketPort newRemoteWithNumber:n onHost:h];
|
||||
return p;
|
||||
}
|
||||
|
||||
+ newRegisteredPortWithName: (NSString*)name
|
||||
{
|
||||
int n;
|
||||
|
||||
#if SOCKET_NUMBER_NAMES_ONLY
|
||||
if ((n = atoi([name cString])) == 0)
|
||||
return nil;
|
||||
#else
|
||||
n = name_to_port_number([name cString]);
|
||||
#endif
|
||||
return [SocketPort newLocalWithNumber:n];
|
||||
}
|
||||
|
||||
+ newPort
|
||||
{
|
||||
return [self newLocal];
|
||||
}
|
||||
|
||||
/* xxx Change this to consider INADDR_ANY and the localhost address
|
||||
to be equal. */
|
||||
#define SOCKPORT_EQUAL(s1,s2) \
|
||||
(s1.sin_port == s2.sin_port && \
|
||||
s1.sin_addr.s_addr == s2.sin_addr.s_addr)
|
||||
/* Assume that sin_family is equal */
|
||||
|
||||
/* (!memcmp(&s1, &s2, sizeof(sockport_t)))
|
||||
didn't work because sin_zero's differ. Does this matter? */
|
||||
|
||||
+ newForSockPort: (sockport_t)s close: (BOOL)f
|
||||
{
|
||||
SocketPort* sp;
|
||||
int i, count;
|
||||
sockport_t a;
|
||||
|
||||
[socketPortListGate lock];
|
||||
|
||||
/* See if there is already one created */
|
||||
count = [socketPortList count];
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
sp = [socketPortList objectAt:i];
|
||||
a = [sp sockPort];
|
||||
if (SOCKPORT_EQUAL(a, s))
|
||||
{
|
||||
[socketPortListGate unlock];
|
||||
return sp;
|
||||
}
|
||||
}
|
||||
|
||||
/* No, create a new one */
|
||||
if (s.sin_family != AF_INET)
|
||||
[self error:"we don't do non INET socket addresses"];
|
||||
sp = [[self alloc] init];
|
||||
sp->sockPort = s;
|
||||
sp->close_on_dealloc = f;
|
||||
/* Before we allowed (s.sin_addr.s_addr == htonl(INADDR_LOOPBACK) also,
|
||||
but then we couldn't have both server and client on the same
|
||||
machine. It would think that the client's out port to the server's
|
||||
in port should be bind()'ed, but the server already did that. */
|
||||
if (s.sin_addr.s_addr == INADDR_ANY)
|
||||
{
|
||||
/* it's local */
|
||||
if ((sp->sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
perror("creating socket");
|
||||
[self error:"creating socket"];
|
||||
}
|
||||
i = sizeof(sockport_t);
|
||||
if (bind(sp->sock, (struct sockaddr*)&sp->sockPort, i))
|
||||
{
|
||||
perror("bind");
|
||||
[self error:"binding socket"];
|
||||
}
|
||||
if (getsockname(sp->sock, (struct sockaddr*)&sp->sockPort, &i))
|
||||
{
|
||||
perror("getsockname");
|
||||
[self error:"getsockname socket"];
|
||||
}
|
||||
if (socket_port_debug)
|
||||
fprintf(stderr, "new socket(), fd=%d\n", sp->sock);
|
||||
}
|
||||
if (socket_port_debug)
|
||||
fprintf(stderr, "created new SocketPort 0x%x, number %d\n",
|
||||
(unsigned)sp, [sp socketPortNumber]);
|
||||
[socketPortList addObject:sp];
|
||||
[socketPortListGate unlock];
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (sock && close_on_dealloc)
|
||||
close(sock);
|
||||
[super dealloc];
|
||||
return;
|
||||
}
|
||||
|
||||
+ newForSockPort: (sockport_t)s
|
||||
{
|
||||
return [self newForSockPort:s close:YES];
|
||||
}
|
||||
|
||||
+ newLocalWithNumber: (int)n
|
||||
{
|
||||
sockport_t s;
|
||||
SocketPort* sp;
|
||||
|
||||
/* xxx clean this up */
|
||||
if (n > 65535 - IPPORT_USERRESERVED - 1)
|
||||
[self error:"port number too high"];
|
||||
n += IPPORT_USERRESERVED + 1;
|
||||
|
||||
/* xxx bzero(&s, sizeof(s)) necessary here? */
|
||||
s.sin_family = AF_INET;
|
||||
s.sin_addr.s_addr = INADDR_ANY;
|
||||
s.sin_port = htons(n);
|
||||
sp = [self newForSockPort:s close:YES];
|
||||
return sp;
|
||||
}
|
||||
|
||||
+ newLocal
|
||||
{
|
||||
id sp;
|
||||
sockport_t a;
|
||||
|
||||
a.sin_family = AF_INET;
|
||||
a.sin_addr.s_addr = INADDR_ANY;
|
||||
a.sin_port = 0;
|
||||
sp = [self newForSockPort:a];
|
||||
return sp;
|
||||
}
|
||||
|
||||
+ newRemoteWithNumber: (int)n onHost: (NSString*)h
|
||||
{
|
||||
struct sockaddr_in remote_addr;
|
||||
struct hostent *hp;
|
||||
const char *hs;
|
||||
|
||||
/* xxx clean this up */
|
||||
if (n > 65535 - IPPORT_USERRESERVED - 1)
|
||||
[self error:"port number too high"];
|
||||
n += IPPORT_USERRESERVED + 1;
|
||||
|
||||
if (!h || ![h length])
|
||||
hs = "localhost";
|
||||
else
|
||||
hs = [h cString];
|
||||
|
||||
hp = gethostbyname((char*)hs);
|
||||
if (hp == 0)
|
||||
[self error:"unknown host: \"%s\"", hs];
|
||||
bcopy(hp->h_addr, &remote_addr.sin_addr, hp->h_length);
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons(n);
|
||||
return [self newForSockPort:remote_addr];
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
Notes for new interface:
|
||||
|
||||
- (int) sendPacket: (const char *)b length: (int)l
|
||||
toPort: (Port*)remote
|
||||
resendTimeout: (int) milliseconds
|
||||
#if foo
|
||||
failTimeout: (int) milliseconds
|
||||
#else
|
||||
retriesBeforeFailure: (int) tries
|
||||
#endif
|
||||
- (int) receivePacket: (char*)b length: (int)l
|
||||
fromPort: (Port**) remote
|
||||
failTimeout: (int) milliseconds
|
||||
|
||||
or
|
||||
|
||||
- (int) sendPacket: (const char *)b length: (int)l
|
||||
toPort: (Port*)remote
|
||||
timeout: (int) milliseconds
|
||||
- (int) receivePacket: (char*)b length: (int)l
|
||||
inResponseToPacket: (char*)b2 length: (int)l2
|
||||
fromPort: (Port**) remote
|
||||
failTimeout: (int) milliseconds
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
/* This currently ignores the timeout parameter */
|
||||
|
||||
- (int) sendPacket: (const char *)b length: (int)l
|
||||
toPort: (Port*)remote
|
||||
timeout: (int) milliseconds
|
||||
{
|
||||
int r;
|
||||
sockport_t a;
|
||||
|
||||
if (![remote isKindOfClass:[SocketPort class]])
|
||||
[self error:"Trying to send to a non-SocketPort"];
|
||||
a = [(SocketPort*)remote sockPort];
|
||||
if (socket_port_debug)
|
||||
fprintf(stderr, "sending to %d\n", [(SocketPort*)remote socketPortNumber]);
|
||||
if ((r = sendto([self socket], (char*)b, l, 0, (struct sockaddr *)&a,
|
||||
sizeof(sockport_t)))
|
||||
< 0)
|
||||
{
|
||||
perror("sendto");
|
||||
[self error:"sendto"];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Returns -1 on timeout.
|
||||
Pass -1 for milliseconds to ignore timeout parameter and block indefinitely.
|
||||
*/
|
||||
|
||||
- (int) receivePacket: (char*)b length: (int)l
|
||||
fromPort: (Port**) remote
|
||||
timeout: (int) milliseconds
|
||||
{
|
||||
int r;
|
||||
struct sockaddr_in remote_addr;
|
||||
int remote_len;
|
||||
int local_sock;
|
||||
|
||||
if (socket_port_debug)
|
||||
fprintf(stderr, "receiving from %d\n", [self socketPortNumber]);
|
||||
|
||||
local_sock = [self socket];
|
||||
|
||||
if (milliseconds >= 0)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set ready;
|
||||
|
||||
timeout.tv_sec = milliseconds / 1000;
|
||||
timeout.tv_usec = (milliseconds % 1000) * 1000;
|
||||
FD_ZERO(&ready);
|
||||
FD_SET(local_sock, &ready);
|
||||
if ((r = select(local_sock + 1, &ready, 0, 0, &timeout)) < 0)
|
||||
{
|
||||
perror("select");
|
||||
[self error:"select"];
|
||||
}
|
||||
if (r == 0) /* timeout */
|
||||
return -1;
|
||||
if (!FD_ISSET(local_sock, &ready))
|
||||
[self error:"select lied"];
|
||||
}
|
||||
|
||||
remote_len = sizeof(sockport_t);
|
||||
if ((r = recvfrom(local_sock, b, l, 0, (struct sockaddr*)&remote_addr,
|
||||
&remote_len))
|
||||
< 0)
|
||||
{
|
||||
perror("recvfrom");
|
||||
[self error:"recvfrom"];
|
||||
}
|
||||
if (remote_len != sizeof(sockport_t))
|
||||
[self error:"remote address size mismatch"];
|
||||
*remote = [[self class] newForSockPort:remote_addr close:NO];
|
||||
return r;
|
||||
}
|
||||
|
||||
- (sockport_t) sockPort
|
||||
{
|
||||
return sockPort;
|
||||
}
|
||||
|
||||
- classForConnectedCoder: aRmc
|
||||
{
|
||||
/* Make sure that Connection's always send us bycopy,
|
||||
i.e. as our own class, not a Proxy class. */
|
||||
return [self class];
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: aCoder
|
||||
{
|
||||
[aCoder encodeValueOfObjCType:@encode(typeof(sockPort.sin_port))
|
||||
at:&sockPort.sin_port
|
||||
withName:@"socket number"];
|
||||
if (![self isSoft])
|
||||
{
|
||||
struct hostent *hp;
|
||||
sockport_t sp;
|
||||
|
||||
/* xxx this could be cleaned up */
|
||||
hp = gethostbyname("localhost");
|
||||
if (hp == 0)
|
||||
[self error:"gethostbyname(): can't get host info"];
|
||||
bcopy(hp->h_addr, &sp.sin_addr, hp->h_length);
|
||||
[aCoder encodeValueOfObjCType:@encode(typeof(sp.sin_addr.s_addr))
|
||||
at:&sp.sin_addr.s_addr
|
||||
withName:@"inet address"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[aCoder encodeValueOfObjCType:@encode(typeof(sockPort.sin_addr.s_addr))
|
||||
at:&sockPort.sin_addr.s_addr
|
||||
withName:@"inet address"];
|
||||
}
|
||||
}
|
||||
|
||||
+ newWithCoder: aCoder
|
||||
{
|
||||
sockport_t sp;
|
||||
|
||||
sp.sin_family = AF_INET;
|
||||
[aCoder decodeValueOfObjCType:@encode(typeof(sp.sin_port))
|
||||
at:&sp.sin_port
|
||||
withName:NULL];
|
||||
[aCoder decodeValueOfObjCType:@encode(typeof(sp.sin_addr.s_addr))
|
||||
at:&sp.sin_addr.s_addr
|
||||
withName:NULL];
|
||||
return [SocketPort newForSockPort:sp];
|
||||
}
|
||||
|
||||
- (int) socket
|
||||
{
|
||||
return sock;
|
||||
}
|
||||
|
||||
- (BOOL) isSoft
|
||||
{
|
||||
if (sock)
|
||||
return NO;
|
||||
else
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (int) socketPortNumber
|
||||
{
|
||||
return (int) ntohs(sockPort.sin_port);
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
{
|
||||
unsigned h = [self socketPortNumber] + sockPort.sin_addr.s_addr;
|
||||
return h;
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: anotherPort
|
||||
{
|
||||
sockport_t s = [anotherPort sockPort];
|
||||
if (SOCKPORT_EQUAL(s, sockPort))
|
||||
{
|
||||
/* xxx Is this really a problem? */
|
||||
if (self != anotherPort)
|
||||
[self error:
|
||||
"Another SocketPort object with the same underlying address!"];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,97 +0,0 @@
|
|||
#include <gnustep/base/Port.h>
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
@interface SunRpcPort : Port
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation SunRpcPort
|
||||
|
||||
+ newRegisteredPortWithName: (const char *)n
|
||||
{
|
||||
SunRpcPort *newPort;
|
||||
unsigned long prognum, versnum, procnum;
|
||||
char *(*procname)();
|
||||
xdrproc_t *(*procname)();
|
||||
|
||||
|
||||
if (registerrpc(prognum, versnum, procnum, procname, inproc, outproc))
|
||||
[self error:"registerrpc failed"];
|
||||
return newPort;
|
||||
}
|
||||
|
||||
+ newPortFromRegisterWithName: (const char *)n onHost: (const char *)host
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ newPort
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* These sending and receiving interfaces will change */
|
||||
|
||||
- (int) sendPacket: (const char *)b length: (int)l
|
||||
toPort: (Port*) remote
|
||||
timeout: (int) milliseconds
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (int) sendPacket: (const char *)b length: (int)l
|
||||
toPort: (Port*) remote
|
||||
{
|
||||
return [self sendPacket:b length:l toPort:remote timeout:-1];
|
||||
}
|
||||
|
||||
- (int) receivePacket: (char*)b length: (int)l
|
||||
fromPort: (Port**) remote
|
||||
timeout: (int) milliseconds
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (int) receivePacket: (char*)b length: (int)l
|
||||
fromPort: (Port**) remote
|
||||
{
|
||||
return [self receivePacket:b length:l fromPort:remote timeout:-1];
|
||||
}
|
||||
|
||||
- (BOOL) canReceive
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: anotherPort
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: (Coder*)anEncoder
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
}
|
||||
|
||||
+ newWithCoder: (Coder*)aDecoder;
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
#if defined(NeXT)
|
||||
|
||||
#elif defined(MACH)
|
||||
|
||||
#elif defined(sun) && defined(svr4)
|
||||
|
||||
@implementation Thread
|
||||
@end
|
||||
@implementation Lock
|
||||
@end
|
||||
|
||||
#else
|
||||
#error Threads not available for this system.
|
||||
#endif
|
476
Source/Tree.m
476
Source/Tree.m
|
@ -1,476 +0,0 @@
|
|||
/* Implementation for Objective-C Tree collection object
|
||||
Copyright (C) 1993,1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/Tree.h>
|
||||
#include <gnustep/base/IndexedCollectionPrivate.h>
|
||||
#include <gnustep/base/TreeNode.h>
|
||||
|
||||
/* sentinal */
|
||||
static id nilTreeNode;
|
||||
|
||||
@implementation Tree
|
||||
|
||||
+ initialize
|
||||
{
|
||||
if (self == [Tree class])
|
||||
{
|
||||
[self setVersion:0]; /* beta release */
|
||||
nilTreeNode = [[TreeNode alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/* This is the designated initializer of this class */
|
||||
- init
|
||||
{
|
||||
[super initWithType:@encode(id)];
|
||||
_count = 0;
|
||||
_contents_root = [self nilNode];
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Archiving must mimic the above designated initializer */
|
||||
|
||||
- _newCollectionWithCoder: aCoder
|
||||
{
|
||||
[super _initCollectionWithCoder:aCoder];
|
||||
_count = 0;
|
||||
_contents_root = [self nilNode];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) _encodeContentsWithCoder: (Coder*)aCoder
|
||||
{
|
||||
[aCoder startEncodingInterconnectedObjects];
|
||||
[super _encodeContentsWithCoder:aCoder];
|
||||
[aCoder finishEncodingInterconnectedObjects];
|
||||
}
|
||||
|
||||
- (void) _decodeContentsWithCoder: (Coder*)aCoder
|
||||
{
|
||||
[aCoder startDecodingInterconnectedObjects];
|
||||
[super _decodeContentsWithCoder:aCoder];
|
||||
[aCoder finishDecodingInterconnectedObjects];
|
||||
}
|
||||
|
||||
/* Empty copy must empty an allocCopy'ed version of self */
|
||||
- emptyCopy
|
||||
{
|
||||
Tree *copy = [super emptyCopy];
|
||||
copy->_count = 0;
|
||||
copy->_contents_root = [self nilNode];
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* This must work without sending any messages to content objects */
|
||||
- _empty
|
||||
{
|
||||
_count = 0;
|
||||
_contents_root = [self nilNode];
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Override the designated initializer for our superclass IndexedCollection
|
||||
to make sure we have object contents */
|
||||
- initWithType: (const char *)contentEncoding
|
||||
{
|
||||
if (!ENCODING_IS_OBJECT(contentEncoding))
|
||||
[self error:"Tree contents must be objects."];
|
||||
return [self init];
|
||||
}
|
||||
|
||||
- nilNode
|
||||
{
|
||||
return nilTreeNode;
|
||||
}
|
||||
|
||||
- rootNode
|
||||
{
|
||||
return _contents_root;
|
||||
}
|
||||
|
||||
- leftmostNodeFromNode: aNode
|
||||
{
|
||||
id left;
|
||||
|
||||
if (aNode && aNode != [self nilNode])
|
||||
{
|
||||
while ([[aNode children] count] &&
|
||||
(left = [[aNode children] firstObject]) != [self nilNode])
|
||||
aNode = left;
|
||||
}
|
||||
return aNode;
|
||||
}
|
||||
|
||||
- rightmostNodeFromNode: aNode
|
||||
{
|
||||
id right;
|
||||
|
||||
if (aNode && aNode != [self nilNode])
|
||||
while ([[aNode children] count] &&
|
||||
(right = [[aNode children] lastObject]) != [self nilNode])
|
||||
{
|
||||
aNode = right;
|
||||
}
|
||||
return aNode;
|
||||
}
|
||||
|
||||
- (elt) firstElement
|
||||
{
|
||||
return [self leftmostNodeFromNode:_contents_root];
|
||||
}
|
||||
|
||||
- (elt) lastElement
|
||||
{
|
||||
return [self rightmostNodeFromNode:_contents_root];
|
||||
}
|
||||
|
||||
/* This is correct only is the tree is sorted. How to deal with this? */
|
||||
- (elt) maxElement
|
||||
{
|
||||
return [self rightmostNodeFromNode:_contents_root];
|
||||
}
|
||||
|
||||
/* This is correct only is the tree is sorted. How to deal with this? */
|
||||
- (elt) minElement
|
||||
{
|
||||
return [self leftmostNodeFromNode:_contents_root];
|
||||
}
|
||||
|
||||
// returns [self nilNode] is there is no successor;
|
||||
- (elt) successorOfElement: (elt)anElement
|
||||
{
|
||||
id tmp;
|
||||
|
||||
// here tmp is the right node;
|
||||
if ((tmp = [anElement.id_u rightNode]) != [self nilNode])
|
||||
return [self leftmostNodeFromNode:tmp];
|
||||
// here tmp is the parent;
|
||||
tmp = [anElement.id_u parentNode];
|
||||
while (tmp != [self nilNode]
|
||||
[[tmp children] count] &&
|
||||
&& anElement.id_u == [[tmp children] lastObject])
|
||||
{
|
||||
anElement.id_u = tmp;
|
||||
tmp = [tmp parentNode];
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// I should make sure that [_contents_root parentNode] == [self nilNode];
|
||||
// Perhaps I should make [_contents_root parentNode] == TreeObj ??;
|
||||
|
||||
// returns [self nilNode] is there is no predecessor;
|
||||
- (elt) predecessorElement: (elt)anElement
|
||||
{
|
||||
id tmp;
|
||||
|
||||
// here tmp is the left node;
|
||||
if ((tmp = [anElement.id_u leftNode]) != [self nilNode])
|
||||
return [self rightmostNodeFromNode:tmp];
|
||||
// here tmp is the parent;
|
||||
tmp = [anElement.id_u parentNode];
|
||||
while (tmp != [self nilNode]
|
||||
[[tmp children] count] &&
|
||||
&& anElement.id_u == [[tmp children] firstObject])
|
||||
{
|
||||
anElement.id_u = tmp;
|
||||
tmp = [tmp parentNode];
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* This relies on [_contents_root parentNode] == [self nilNode] */
|
||||
- rootFromNode: aNode
|
||||
{
|
||||
id parentNode;
|
||||
while ((parentNode = [aNode parentNode]) != [self nilNode])
|
||||
aNode = parentNode;
|
||||
return aNode;
|
||||
}
|
||||
|
||||
/* This relies on [_contents_root parentNode] == [self nilNode] */
|
||||
- (unsigned) depthOfNode: aNode
|
||||
{
|
||||
unsigned count = 0;
|
||||
|
||||
if (aNode == nil || aNode == [self nilNode])
|
||||
[self error:"in %s, Can't find depth of nil node", sel_get_name(_cmd)];
|
||||
do
|
||||
{
|
||||
aNode = [aNode parentNode];
|
||||
count++;
|
||||
}
|
||||
while (aNode != [self nilNode]);
|
||||
return count;
|
||||
}
|
||||
|
||||
#if 0
|
||||
- (unsigned) heightOfNode: aNode
|
||||
{
|
||||
unsigned leftHeight, rightHeight;
|
||||
id tmpNode;
|
||||
|
||||
if (aNode == nil || aNode == [self nilNode])
|
||||
{
|
||||
[self error:"in %s, Can't find height of nil node", sel_get_name(_cmd)];
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
leftHeight = ((tmpNode = [aNode leftNode])
|
||||
?
|
||||
(1 + [self heightOfNode:tmpNode])
|
||||
:
|
||||
0);
|
||||
rightHeight = ((tmpNode = [aNode rightNode])
|
||||
?
|
||||
(1 + [self heightOfNode:tmpNode])
|
||||
:
|
||||
0);
|
||||
return MAX(leftHeight, rightHeight);
|
||||
}
|
||||
}
|
||||
|
||||
- (unsigned) nodeCountUnderNode: aNode
|
||||
{
|
||||
unsigned count = 0;
|
||||
if ([aNode leftNode] != [self nilNode])
|
||||
count += 1 + [self nodeCountUnderNode:[aNode leftNode]];
|
||||
if ([aNode rightNode] != [self nilNode])
|
||||
count += 1 + [self nodeCountUnderNode:[aNode rightNode]];
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (elt) elementAtIndex: (unsigned)index
|
||||
{
|
||||
elt ret;
|
||||
|
||||
CHECK_INDEX_RANGE_ERROR(index, _count);
|
||||
ret = [self firstElement];
|
||||
// Not very efficient; Should be rewritten;
|
||||
while (index--)
|
||||
ret = [self successorOfElement:ret];
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
- sortAddElement: (elt)newElement byCalling: (int(*)(elt,elt))aFunc
|
||||
{
|
||||
id theParent, tmpChild;
|
||||
|
||||
[newElement.id_u setLeftNode:[self nilNode]];
|
||||
[newElement.id_u setRightNode:[self nilNode]];
|
||||
theParent = [self nilNode];
|
||||
tmpChild = _contents_root;
|
||||
while (tmpChild != [self nilNode])
|
||||
{
|
||||
theParent = tmpChild;
|
||||
if ((*aFunc)(newElement,theParent) < 0)
|
||||
tmpChild = [tmpChild leftNode];
|
||||
else
|
||||
tmpChild = [tmpChild rightNode];
|
||||
}
|
||||
[newElement.id_u setParentNode:theParent];
|
||||
if (theParent == [self nilNode])
|
||||
_contents_root = newElement.id_u;
|
||||
else
|
||||
{
|
||||
if (COMPARE_ELEMENTS(newElement, theParent) < 0)
|
||||
[theParent setLeftNode:newElement.id_u];
|
||||
else
|
||||
[theParent setRightNode:newElement.id_u];
|
||||
}
|
||||
_count++;
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
- addElement: (elt)newElement
|
||||
{
|
||||
// By default add to root node. Is this what we want?;
|
||||
if (_contents_root)
|
||||
[[_contents_root children] addObject:newElement.id_u];
|
||||
else
|
||||
_contents_root = newElement.id_u;
|
||||
_count++;
|
||||
return self;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// NOTE: This gives you the power to put elements in unsorted order;
|
||||
- insertElement: (elt)newElement before: (elt)oldElement
|
||||
{
|
||||
id tmp;
|
||||
|
||||
#ifdef SAFE_Tree
|
||||
if ([self rootFromNode:oldElement.id_u] != _contents_root)
|
||||
[self error:"in %s, oldElement not in tree!!", sel_get_name(_cmd)];
|
||||
#endif
|
||||
|
||||
[newElement.id_u setRightNode:[self nilNode]];
|
||||
[newElement.id_u setLeftNode:[self nilNode]];
|
||||
if ((tmp = [oldElement.id_u leftNode]) != [self nilNode])
|
||||
{
|
||||
[(tmp = [self rightmostNodeFromNode:tmp]) setRightNode:newElement.id_u];
|
||||
[newElement.id_u setParentNode:tmp];
|
||||
}
|
||||
else if (newElement.id_u != [self nilNode])
|
||||
{
|
||||
[oldElement.id_u setLeftNode:newElement.id_u];
|
||||
[newElement.id_u setParentNode:oldElement.id_u];
|
||||
}
|
||||
else
|
||||
{
|
||||
_contents_root = newElement.id_u;
|
||||
[newElement.id_u setParentNode:[self nilNode]];
|
||||
}
|
||||
_count++;
|
||||
return self;
|
||||
}
|
||||
|
||||
// NOTE: This gives you the power to put elements in unsorted order;
|
||||
- insertElement: (elt)newElement after: (elt)oldElement
|
||||
{
|
||||
id tmp;
|
||||
|
||||
#ifdef SAFE_Tree
|
||||
if ([self rootFromNode:oldElement.id_u] != _contents_root)
|
||||
[self error:"in %s, !!!!!!!!", sel_get_name(_cmd)];
|
||||
#endif
|
||||
|
||||
[newElement.id_u setRightNode:[self nilNode]];
|
||||
[newElement.id_u setLeftNode:[self nilNode]];
|
||||
if ((tmp = [oldElement.id_u rightNode]) != [self nilNode])
|
||||
{
|
||||
[(tmp = [self leftmostNodeFromNode:tmp]) setLeftNode:newElement.id_u];
|
||||
[newElement.id_u setParentNode:tmp];
|
||||
}
|
||||
else if (newElement.id_u != [self nilNode])
|
||||
{
|
||||
[oldElement.id_u setRightNode:newElement.id_u];
|
||||
[newElement.id_u setParentNode:oldElement.id_u];
|
||||
}
|
||||
else
|
||||
{
|
||||
_contents_root = newElement.id_u;
|
||||
[newElement.id_u setParentNode:[self nilNode]];
|
||||
}
|
||||
_count++;
|
||||
return self;
|
||||
}
|
||||
|
||||
// NOTE: This gives you the power to put elements in unsorted order;
|
||||
- insertElement: (elt)newElement atIndex: (unsigned)index
|
||||
{
|
||||
CHECK_INDEX_RANGE_ERROR(index, _count+1);
|
||||
if (index == _count)
|
||||
[self appendElement:newElement];
|
||||
else
|
||||
[self insertElement:newElement before:[self elementAtIndex:index]];
|
||||
return self;
|
||||
}
|
||||
|
||||
// NOTE: This gives you the power to put elements in unsorted order;
|
||||
- appendElement: (elt)newElement
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
_contents_root = newElement.id_u;
|
||||
_count = 1;
|
||||
[newElement.id_u setLeftNode:[self nilNode]];
|
||||
[newElement.id_u setRightNode:[self nilNode]];
|
||||
[newElement.id_u setParentNode:[self nilNode]];
|
||||
}
|
||||
else
|
||||
[self insertElement:newElement after:[self lastElement]];
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (elt) removeElement: (elt)oldElement
|
||||
{
|
||||
id parent = [oldElement.id_u parentNode];
|
||||
[parent removeObject:oldElement.id_u];
|
||||
[parent addContentsOf:[oldElement.id_u children]];
|
||||
_count--;
|
||||
return oldElement;
|
||||
}
|
||||
|
||||
- withElementsCall: (void(*)(elt))aFunc whileTrue: (BOOL*)flag
|
||||
{
|
||||
void traverse(id aNode)
|
||||
{
|
||||
if (!(*flag) || aNode == [self nilNode] || !aNode)
|
||||
return;
|
||||
(*aFunc)(aNode);
|
||||
[[aNode children] withObjectsCall:traverse];
|
||||
}
|
||||
traverse(_contents_root);
|
||||
return self;
|
||||
}
|
||||
|
||||
- withElementsInReverseCall: (void(*)(elt))aFunc whileTrue: (BOOL*)flag
|
||||
{
|
||||
void traverse(id aNode)
|
||||
{
|
||||
if (*flag || aNode == [self nilNode] || !aNode)
|
||||
return;
|
||||
[[aNode children] withObjectsCall:traverse];
|
||||
(*aFunc)(aNode);
|
||||
}
|
||||
traverse(_contents_root);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) getNextElement:(elt *)anElementPtr withEnumState: (void**)enumState
|
||||
{
|
||||
if (!(*enumState))
|
||||
*enumState = [self leftmostNodeFromNode:_contents_root];
|
||||
else
|
||||
*enumState = [self successorOfElement:*enumState].id_u;
|
||||
*anElementPtr = *enumState;
|
||||
if (*enumState)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) getPrevElement:(elt *)anElementPtr withEnumState: (void**)enumState
|
||||
{
|
||||
if (!(*enumState))
|
||||
*enumState = [self rightmostNodeFromNode:_contents_root];
|
||||
else
|
||||
*enumState = [self predecessorElement:*enumState].id_u;
|
||||
*anElementPtr = *enumState;
|
||||
if (*enumState)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (unsigned) count
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,101 +0,0 @@
|
|||
/* Implementation for Objective-C TreeNode object
|
||||
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/TreeNode.h>
|
||||
#include <gnustep/base/Array.h>
|
||||
|
||||
@implementation TreeNode
|
||||
|
||||
+ initialize
|
||||
{
|
||||
if (self == [TreeNode class])
|
||||
[self setVersion:0]; /* beta release */
|
||||
return self;
|
||||
}
|
||||
|
||||
+ defaultChildrenCollectionClass
|
||||
{
|
||||
return [Array class];
|
||||
}
|
||||
|
||||
- initWithChildren: (id <Collecting>)kids
|
||||
{
|
||||
[super init];
|
||||
_parent = [self nilNode];
|
||||
_children = kids;
|
||||
return self;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
[self initWithChildren:[[[self defaultChildrenCollectionClass] alloc] init]];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[_children release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: aCoder
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
[aCoder encodeObjectReference:_parent withName:@"Parent Tree Node"];
|
||||
[aCoder encodeObject:_children withName:@"Children of Tree Node"];
|
||||
}
|
||||
|
||||
- initWithCoder: aCoder
|
||||
{
|
||||
[self initWithCoder:aCoder];
|
||||
[aCoder decodeObjectAt:&_parent withName:NULL];
|
||||
[aCoder decodeObjectAt:&_children withName:NULL];
|
||||
return n;
|
||||
}
|
||||
|
||||
- children
|
||||
{
|
||||
return _children;
|
||||
}
|
||||
|
||||
- parentNode
|
||||
{
|
||||
return _parent;
|
||||
}
|
||||
|
||||
- (void) setChildren: (id <IndexedCollecting>)kids
|
||||
{
|
||||
[kids retain];
|
||||
[_children release];
|
||||
_children = kids;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) setParentNode: aNode
|
||||
{
|
||||
_parent = aNode;
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,426 +0,0 @@
|
|||
#include <objc/encoding.h>
|
||||
#include <objc/objc-api.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* These functions can be used for dissecting and making method calls
|
||||
for many different situations. They are used for distributed
|
||||
objects, they could also be used to make interfaces between
|
||||
Objective C and Scheme, Perl, Tcl, whatever... I need to
|
||||
generalize this stuff a little more to make it useable for an
|
||||
Invocation class also. */
|
||||
|
||||
/* Returns YES iff there are any outparameters */
|
||||
BOOL
|
||||
dissect_method_call(arglist_t frame, const char *type,
|
||||
void (*f)(int,void*,const char*,int))
|
||||
{
|
||||
const char *tmptype;
|
||||
unsigned flags;
|
||||
char *datum;
|
||||
int argnum;
|
||||
|
||||
tmptype = type;
|
||||
for (datum = my_method_get_next_argument(argframe, &tmptype), argnum=0;
|
||||
datum;
|
||||
datum = my_method_get_next_argument(argframe, &tmptype), argnum++)
|
||||
{
|
||||
flags = objc_get_type_qualifiers(tmptype);
|
||||
tmptype = objc_skip_type_qualifiers(tmptype);
|
||||
if (*tmptype == _C_ID)
|
||||
{
|
||||
(*f)(argnum, datum, tmptype, flags);
|
||||
}
|
||||
else if (*tmptype == _C_CHARPTR)
|
||||
{
|
||||
if ((flags & _F_OUT) || !(flags & _F_IN))
|
||||
out_parameters = YES;
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*f)(argnum, datum, tmptype, flags);
|
||||
}
|
||||
else if (*tmptype == _C_PTR)
|
||||
{
|
||||
tmptype++;
|
||||
if ((flags & _F_OUT) || !(flags & _F_IN))
|
||||
out_parameters = YES;
|
||||
/* xxx These two cases currently the same */
|
||||
if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
{
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*f)(argnum, *(void**)datum, tmptype, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*f)(argnum, *(void**)datum, tmptype, flags);
|
||||
}
|
||||
}
|
||||
else if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
{
|
||||
#if CONNECTION_STRUCTURES_PASSED_BY_REFERENCE
|
||||
(*f)(argnum, *(void**)datum, tmptype, flags);
|
||||
#else
|
||||
(*f)(argnum, datum, tmptype, flags);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
(*f)(argnum, datum, tmptype, flags);
|
||||
}
|
||||
}
|
||||
return out_parameters;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
make_method_call(const char *forward_type,
|
||||
void(*fd)(int,void*,const char*),
|
||||
void(*fe)(int,void*,const char*,int))
|
||||
{
|
||||
const char *type, *tmptype;
|
||||
const char *ftmptype;
|
||||
id object;
|
||||
SEL selector;
|
||||
IMP imp;
|
||||
void *retframe;
|
||||
arglist_t argframe;
|
||||
int stack_argsize;
|
||||
int reg_argsize;
|
||||
char *datum;
|
||||
id op;
|
||||
unsigned flags;
|
||||
BOOL out_parameters = NO;
|
||||
int argnum;
|
||||
|
||||
/* get object and selector */
|
||||
(*fd)(0, &object, @encode(id));
|
||||
|
||||
/* @encode(SEL) produces "^v" in gcc 2.5.8. It should be ":" */
|
||||
(*fd)(1, &selector, ":");
|
||||
assert(selector);
|
||||
|
||||
type = sel_get_type(selector);
|
||||
assert(type);
|
||||
|
||||
/* Set up argframe */
|
||||
stack_argsize = types_get_size_of_stack_arguments(type);
|
||||
reg_argsize = types_get_size_of_register_arguments(type);
|
||||
argframe = (arglist_t) alloca(sizeof(char*) + reg_argsize);
|
||||
if (stack_argsize)
|
||||
argframe->arg_ptr = alloca(stack_argsize);
|
||||
else
|
||||
argframe->arg_ptr = 0;
|
||||
|
||||
/* decode rest of arguments */
|
||||
tmptype = type;
|
||||
ftmptype = objc_skip_argspec(forward_type);
|
||||
datum = my_method_get_next_argument(argframe, &tmptype);
|
||||
assert(datum);
|
||||
assert(*tmptype == _C_ID);
|
||||
*(id*)datum = object;
|
||||
assert(object);
|
||||
ftmptype = objc_skip_argspec(ftmptype);
|
||||
datum = my_method_get_next_argument(argframe, &tmptype);
|
||||
assert(datum);
|
||||
assert(*tmptype == _C_SEL);
|
||||
*(SEL*)datum = selector;
|
||||
assert(selector);
|
||||
for (datum = my_method_get_next_argument(argframe, &tmptype),
|
||||
ftmptype = objc_skip_argspec(ftmptype), argnum = 2;
|
||||
datum;
|
||||
datum = my_method_get_next_argument(argframe, &tmptype),
|
||||
ftmptype = objc_skip_argspec(ftmptype), argnum++)
|
||||
{
|
||||
flags = objc_get_type_qualifiers(ftmptype);
|
||||
tmptype = objc_skip_type_qualifiers(tmptype);
|
||||
if (*tmptype == _C_CHARPTR)
|
||||
{
|
||||
if ((flags & _F_OUT) || !(flags & _F_IN))
|
||||
out_parameters = YES;
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*fd)(argnum, datum, tmptype);
|
||||
}
|
||||
else if (*tmptype == _C_PTR)
|
||||
{
|
||||
tmptype++;
|
||||
if ((flags & _F_OUT) || !(flags & _F_IN))
|
||||
out_parameters = YES;
|
||||
/* xxx These two cases currently the same */
|
||||
if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
{
|
||||
/* *(void**)datum = alloca(sizeof(void*)); */
|
||||
/* xxx or should this be alloca?!
|
||||
What about inout params? Where do they get freed? */
|
||||
*(void**)datum =
|
||||
objc_malloc (objc_sizeof_type(tmptype));
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*fd)(argnum, *(void**)datum, tmptype);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* xxx or should this be alloca?!
|
||||
What about inout params? Where dothey get freed? */
|
||||
*(char**)datum =
|
||||
objc_malloc (objc_sizeof_type(tmptype));
|
||||
if ((flags & _F_IN) || !(flags & _F_OUT))
|
||||
(*fd)(argnum, *(void**)datum, tmptype);
|
||||
}
|
||||
}
|
||||
else if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
{
|
||||
#if CONNECTION_STRUCTURES_PASSED_BY_REFERENCE
|
||||
*(void**)datum = alloca(objc_sizeof_type(tmptype));
|
||||
(*fd)(argnum, *(void**)datum, tmptype);
|
||||
#else
|
||||
(*fd)(argnum, datum, tmptype);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
(*fd)(argnum, datum, tmptype);
|
||||
}
|
||||
}
|
||||
|
||||
/* Call the method */
|
||||
imp = objc_msg_lookup(object, selector);
|
||||
assert(imp);
|
||||
retframe = __builtin_apply((apply_t)imp,
|
||||
argframe,
|
||||
stack_argsize);
|
||||
|
||||
/* Return results, if necessary */
|
||||
flags = objc_get_type_qualifiers(forward_type);
|
||||
ftmptype = objc_skip_type_qualifiers(forward_type);
|
||||
tmptype = objc_skip_type_qualifiers(type);
|
||||
/* Is this right? Do we also have to check _F_ONEWAY? */
|
||||
if (out_parameters || *tmptype != _C_VOID)
|
||||
{
|
||||
if (*tmptype != _C_VOID)
|
||||
{
|
||||
/* encode return value */
|
||||
/* xxx Change this to switch(*tmptype) */
|
||||
if (*tmptype == _C_ID)
|
||||
{
|
||||
(*fe)(-1, retframe, @encode(id), flags);
|
||||
}
|
||||
else if (*tmptype == _C_PTR)
|
||||
{
|
||||
tmptype++;
|
||||
/* xxx These two cases currently the same */
|
||||
if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
(*fe)(-1, *(void**)retframe, tmptype, flags);
|
||||
else
|
||||
(*fe)(-1, *(void**)retframe, tmptype, flags);
|
||||
}
|
||||
else if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
{
|
||||
/* xxx these two cases currently the same? */
|
||||
#if CONNECTION_STRUCTURES_PASSED_BY_REFERENCE
|
||||
(*fe)(-1, *(void**)retframe, tmptype, flags);
|
||||
#else
|
||||
(*fe)(-1, *(void**)retframe, tmptype, flags);
|
||||
#endif
|
||||
}
|
||||
else if (*tmptype == _C_FLT || *tmptype == _C_DBL)
|
||||
{
|
||||
(*fe)(-1, ((char*)retframe) + FLT_AND_DBL_RETFRAME_OFFSET
|
||||
tmptype, flags);
|
||||
}
|
||||
else /* Among other types, _C_CHARPTR is handled here */
|
||||
{
|
||||
int retsize = objc_sizeof_type(tmptype);
|
||||
/* Special case BOOL (and other types smaller than int)
|
||||
because retframe doesn't actually point to the char */
|
||||
/* xxx What about structures smaller than int's that
|
||||
are passed by reference on true structure reference-
|
||||
passing architectures? */
|
||||
/* xxx Is this the right test? Use sizeof(int*) instead? */
|
||||
if (retsize < sizeof(void*))
|
||||
{
|
||||
(*fe)(-1, ((char*)retframe)+sizeof(void*)-retsize
|
||||
tmptype, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*fe)(-1, retframe, tmptype, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* encode values returned by reference */
|
||||
if (out_parameters)
|
||||
{
|
||||
for (datum = my_method_get_next_argument(argframe,&tmptype),
|
||||
argnum = 1,
|
||||
ftmptype = objc_skip_argspec(ftmptype);
|
||||
datum;
|
||||
datum = my_method_get_next_argument(argframe,&tmptype),
|
||||
argnum++,
|
||||
ftmptype = objc_skip_argspec(ftmptype))
|
||||
{
|
||||
flags = objc_get_type_qualifiers(ftmptype);
|
||||
tmptype = objc_skip_type_qualifiers(tmptype);
|
||||
sprintf(argname, "arg%d", argnum); /* too expensive? */
|
||||
if ((*tmptype == _C_PTR)
|
||||
&& ((flags & _F_OUT) || !(flags & _F_IN)))
|
||||
{
|
||||
tmptype++;
|
||||
/* xxx These two cases currently the same */
|
||||
if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
{
|
||||
(*fe)(argnum, *(void**)datum, tmptype, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*fe)(argnum, *(void**)datum, tmptype, flags);
|
||||
}
|
||||
}
|
||||
else if (*tmptype == _C_CHARPTR
|
||||
&& ((flags & _F_OUT) || !(flags & _F_IN)))
|
||||
{
|
||||
(*fe)(argnum, datum, tmptype, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
void f_decode_rets (int argnum, void *datum, const char *type)
|
||||
{
|
||||
[ip decodeValueOfObjCType:type
|
||||
at:datum
|
||||
withName:NULL];
|
||||
}
|
||||
|
||||
/* In the function that calls this one, be careful about calling more
|
||||
functions after this one. The memory for the retval_t is alloca'ed */
|
||||
retval_t dissect_method_return(arglist_t frame, const char *type,
|
||||
BOOL out_parameters,
|
||||
void(*f)(int,void*,const char*,int))
|
||||
{
|
||||
retval_t retframe;
|
||||
int argnum;
|
||||
int flags;
|
||||
const char *tmptype;
|
||||
|
||||
/* get return values, if necessary */
|
||||
flags = objc_get_type_qualifiers(type);
|
||||
tmptype = objc_skip_type_qualifiers(type);
|
||||
/* xxx What happens with method declared "- (oneway) foo: (out int*)ip;" */
|
||||
/* xxx What happens with method declared "- (in char *) bar;" */
|
||||
/* Is this right? Do we also have to check _F_ONEWAY? */
|
||||
if (out_parameters || *tmptype != _C_VOID)
|
||||
{
|
||||
argnum = -1
|
||||
if (*tmptype != _C_VOID)
|
||||
{
|
||||
/* decode return value */
|
||||
retsize = objc_sizeof_type(tmptype);
|
||||
/* xxx We need to test retsize's less than 4. Also note that
|
||||
if we return structures using a structure-value-address, we
|
||||
are potentially alloca'ing much more than we need here. */
|
||||
/* xxx Find out about returning structures by reference
|
||||
on non--structure-value-address machines, and potentially
|
||||
just always alloca(RETFRAME_SIZE == sizeof(void*)*4) */
|
||||
retframe = alloca(MAX(retsize, sizeof(void*)*4));
|
||||
/* xxx change this to a switch (*tmptype) */
|
||||
if (*tmptype == _C_PTR)
|
||||
{
|
||||
tmptype++;
|
||||
/* xxx these two cases are the same */
|
||||
if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
{
|
||||
*(void**)retframe =
|
||||
objc_malloc (objc_sizeof_type(tmptype));
|
||||
(*f)(argnum, *(void**)retframe, tmptype, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
*(void**)retframe =
|
||||
objc_malloc (objc_sizeof_type(tmptype));
|
||||
(*f)(argnum, *(void**)retframe, tmptype, flags);
|
||||
}
|
||||
}
|
||||
else if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
{
|
||||
/* xxx These two cases currently the same */
|
||||
xxx wwoooooo, we have to alloca in the frame above
|
||||
#if CONNECTION_STRUCTURES_PASSED_BY_REFERENCE
|
||||
*(void**)retframe = alloca(objc_sizeof_type(tmptype));
|
||||
(*f)(argnum, *(void**)retframe, tmptype, flags);
|
||||
#else
|
||||
*(void**)retframe = alloca(objc_sizeof_type(tmptype));
|
||||
(*f)(argnum, *(void**)retframe, tmptype, flags);
|
||||
#endif
|
||||
}
|
||||
else if (*tmptype == _C_FLT || *tmptype == _C_DBL)
|
||||
{
|
||||
(*f)(argnum, ((char*)retframe) + FLT_AND_DBL_RETFRAME_OFFSET,
|
||||
tmptype, flags);
|
||||
}
|
||||
else /* Among other things, _C_CHARPTR is handled here */
|
||||
{
|
||||
/* int typesize; xxx Use retsize instead! */
|
||||
/* xxx was: (typesize = objc_sizeof_type(tmptype)) */
|
||||
/* Special case BOOL (and other types smaller than int)
|
||||
because retframe doesn't actually point to the char */
|
||||
/* xxx What about structures smaller than int's that
|
||||
are passed by reference on true structure reference-
|
||||
passing architectures? */
|
||||
/* xxx Is this the right test? Use sizeof(int*) instead? */
|
||||
if (retsize < sizeof(void*))
|
||||
{
|
||||
*(void**)retframe = 0;
|
||||
(*f)(argnum, ((char*)retframe)+sizeof(void*)-retsize,
|
||||
tmptype, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*f)(argnum, retframe, tmptype, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* decode values returned by reference */
|
||||
if (out_parameters)
|
||||
{
|
||||
for (datum = my_method_get_next_argument(argframe, &tmptype), argnum=0;
|
||||
datum;
|
||||
(datum = my_method_get_next_argument(argframe, &tmptype)), argnum++)
|
||||
{
|
||||
flags = objc_get_type_qualifiers(tmptype);
|
||||
tmptype = objc_skip_type_qualifiers(tmptype);
|
||||
if (*tmptype == _C_PTR
|
||||
&& ((flags & _F_OUT) || !(flags & _F_IN)))
|
||||
{
|
||||
tmptype++;
|
||||
/* xxx Note that a (char**) is malloc'ed anew here.
|
||||
Yucky, or worse than yucky. If the returned string
|
||||
is smaller than the original, we should just put it
|
||||
there; if the returned string is bigger, I don't know
|
||||
what to do. */
|
||||
/* xxx These two cases are the same */
|
||||
if (*tmptype == _C_STRUCT_B || *tmptype == _C_ARY_B)
|
||||
{
|
||||
(*f)(argnum, *(void**)datum, tmptype, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*f)(argnum, *(void**)datum, tmptype, flags);
|
||||
}
|
||||
}
|
||||
/* __builtin_return can't return structures by value */
|
||||
else if (*tmptype == _C_CHARPTR
|
||||
&& ((flags & _F_OUT) || !(flags & _F_IN)))
|
||||
{
|
||||
(*f)(argnum, datum, tmptype, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* void return value */
|
||||
{
|
||||
retframe = alloca(sizeof(void*));
|
||||
}
|
||||
}
|
1026
Source/data.m
1026
Source/data.m
File diff suppressed because it is too large
Load diff
|
@ -1,556 +0,0 @@
|
|||
/* Functions for dealing with elt unions
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/eltfuncs.h>
|
||||
#include <gnustep/base/collhash.h>
|
||||
#include <gnustep/base/Stream.h>
|
||||
|
||||
/* Is there a better (shorter) way to specify all this junk? */
|
||||
|
||||
unsigned int
|
||||
elt_hash_int (elt key)
|
||||
{
|
||||
return (key.int_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_ints (elt k1, elt k2)
|
||||
{
|
||||
if (k1.int_u == k2.int_u)
|
||||
return 0;
|
||||
else if (k1.int_u > k2.int_u)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_unsigned_int (elt key)
|
||||
{
|
||||
return (key.unsigned_int_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_unsigned_ints (elt k1, elt k2)
|
||||
{
|
||||
if (k1.unsigned_int_u == k2.unsigned_int_u)
|
||||
return 0;
|
||||
else if (k1.unsigned_int_u > k2.unsigned_int_u)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_long_int (elt key)
|
||||
{
|
||||
return ((unsigned int)key.long_int_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_long_ints (elt k1, elt k2)
|
||||
{
|
||||
if (k1.long_int_u == k2.long_int_u)
|
||||
return 0;
|
||||
else if (k1.long_int_u > k2.long_int_u)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_unsigned_long_int (elt key)
|
||||
{
|
||||
return ((unsigned int)key.unsigned_long_int_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_unsigned_long_ints (elt k1, elt k2)
|
||||
{
|
||||
if (k1.unsigned_long_int_u == k2.unsigned_long_int_u)
|
||||
return 0;
|
||||
else if (k1.unsigned_long_int_u > k2.unsigned_long_int_u)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_char (elt key)
|
||||
{
|
||||
return ((unsigned int)key.char_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_chars (elt k1, elt k2)
|
||||
{
|
||||
if (k1.char_u == k2.char_u)
|
||||
return 0;
|
||||
else if (k1.char_u > k2.char_u)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_unsigned_char (elt key)
|
||||
{
|
||||
return ((unsigned int)key.unsigned_char_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_unsigned_chars (elt k1, elt k2)
|
||||
{
|
||||
if (k1.unsigned_char_u == k2.unsigned_char_u)
|
||||
return 0;
|
||||
else if (k1.unsigned_char_u > k2.unsigned_char_u)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_short (elt key)
|
||||
{
|
||||
return ((unsigned int)key.short_int_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_shorts (elt k1, elt k2)
|
||||
{
|
||||
if (k1.short_int_u == k2.short_int_u)
|
||||
return 0;
|
||||
else if (k1.short_int_u > k2.short_int_u)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_unsigned_short (elt key)
|
||||
{
|
||||
return ((unsigned int)key.unsigned_short_int_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_unsigned_shorts (elt k1, elt k2)
|
||||
{
|
||||
if (k1.unsigned_short_int_u == k2.unsigned_short_int_u)
|
||||
return 0;
|
||||
else if (k1.unsigned_short_int_u > k2.unsigned_short_int_u)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_float (elt key)
|
||||
{
|
||||
/* There must be a better hash function for floats than this */
|
||||
return ((unsigned int)key.float_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_floats (elt k1, elt k2)
|
||||
{
|
||||
float diff = k1.float_u - k2.float_u;
|
||||
if (diff == 0)
|
||||
return 0;
|
||||
else if (diff > 0)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if (ELT_INCLUDES_DOUBLE)
|
||||
unsigned int
|
||||
elt_hash_double (elt key)
|
||||
{
|
||||
/* There must be a better hash function for doubles than this.
|
||||
Fix this nonsense: */
|
||||
return ((unsigned int)key.double_u);
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_doubles (elt k1, elt k2)
|
||||
{
|
||||
double diff = k1.double_u - k2.double_u;
|
||||
if (diff == 0)
|
||||
return 0;
|
||||
else if (diff > 0)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
elt_compare_strings (elt k1, elt k2)
|
||||
{
|
||||
return strcmp (k1.char_ptr_u, k2.char_ptr_u);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_string (elt key)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
unsigned int ctr = 0;
|
||||
|
||||
while (*key.char_ptr_u) {
|
||||
ret ^= *key.char_ptr_u++ << ctr;
|
||||
ctr = (ctr + 1) % sizeof (void *);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_void_ptrs (elt k1, elt k2)
|
||||
{
|
||||
if (k1.void_ptr_u == k2.void_ptr_u)
|
||||
return 0;
|
||||
else if (k1.void_ptr_u > k2.void_ptr_u)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_void_ptr (elt key)
|
||||
{
|
||||
return ((unsigned)key.void_ptr_u) / sizeof(void *);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
elt_hash_object (elt key)
|
||||
{
|
||||
return [key.id_u hash];
|
||||
}
|
||||
|
||||
int
|
||||
elt_compare_objects (elt k1, elt k2)
|
||||
{
|
||||
return [k1.id_u compare:k2.id_u];
|
||||
}
|
||||
|
||||
int
|
||||
(*(elt_get_comparison_function(const char *encoding)))(elt,elt)
|
||||
{
|
||||
switch (*encoding)
|
||||
{
|
||||
case _C_CHARPTR:
|
||||
case _C_ATOM:
|
||||
return elt_compare_strings;
|
||||
|
||||
case _C_ID:
|
||||
case _C_CLASS: /* isEqual: on classes works well? */
|
||||
return elt_compare_objects;
|
||||
|
||||
case _C_PTR:
|
||||
return elt_compare_void_ptrs;
|
||||
|
||||
case _C_INT:
|
||||
return elt_compare_ints;
|
||||
|
||||
case _C_SEL: /* is this where this belongs? */
|
||||
case _C_UINT:
|
||||
return elt_compare_unsigned_ints;
|
||||
|
||||
case _C_FLT:
|
||||
return elt_compare_floats;
|
||||
|
||||
#if ELT_INCLUDES_DOUBLE
|
||||
case _C_DBL:
|
||||
return elt_compare_doubles;
|
||||
#endif
|
||||
|
||||
case _C_LNG:
|
||||
return elt_compare_long_ints;
|
||||
|
||||
case _C_ULNG:
|
||||
return elt_compare_unsigned_long_ints;
|
||||
|
||||
case _C_CHR:
|
||||
return elt_compare_chars;
|
||||
|
||||
case _C_UCHR:
|
||||
return elt_compare_unsigned_chars;
|
||||
|
||||
case _C_SHT:
|
||||
return elt_compare_shorts;
|
||||
|
||||
case _C_USHT:
|
||||
return elt_compare_unsigned_shorts;
|
||||
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int
|
||||
(*(elt_get_hash_function(const char *encoding)))(elt)
|
||||
{
|
||||
switch (*encoding)
|
||||
{
|
||||
case _C_CHARPTR:
|
||||
case _C_ATOM:
|
||||
return elt_hash_string;
|
||||
|
||||
case _C_ID:
|
||||
case _C_CLASS: /* I can send classes isEqual:? */
|
||||
return elt_hash_object;
|
||||
|
||||
case _C_PTR:
|
||||
return elt_hash_void_ptr;
|
||||
|
||||
case _C_INT:
|
||||
return elt_hash_int;
|
||||
|
||||
case _C_SEL: /* is this where this belongs? */
|
||||
case _C_UINT:
|
||||
return elt_hash_unsigned_int;
|
||||
|
||||
case _C_FLT:
|
||||
return elt_hash_float;
|
||||
|
||||
#if ELT_INCLUDES_DOUBLE
|
||||
case _C_DBL:
|
||||
return elt_hash_double;
|
||||
#endif
|
||||
case _C_LNG:
|
||||
return elt_hash_long_int;
|
||||
|
||||
case _C_ULNG:
|
||||
return elt_hash_unsigned_long_int;
|
||||
|
||||
case _C_CHR:
|
||||
return elt_hash_char;
|
||||
|
||||
case _C_UCHR:
|
||||
return elt_hash_unsigned_char;
|
||||
|
||||
case _C_SHT:
|
||||
return elt_hash_short;
|
||||
|
||||
case _C_USHT:
|
||||
return elt_hash_unsigned_short;
|
||||
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static coll_cache_ptr __comp_func_hashtable = 0;
|
||||
#define INIT_COMP_FUNC_HASHTABLE_SIZE 32
|
||||
|
||||
static inline void
|
||||
__init_comp_func_hashtable()
|
||||
{
|
||||
__comp_func_hashtable =
|
||||
coll_hash_new(INIT_COMP_FUNC_HASHTABLE_SIZE,
|
||||
(coll_hash_func_type)elt_hash_void_ptr,
|
||||
(coll_compare_func_type)elt_compare_void_ptrs);
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_ints,
|
||||
@encode(int));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_unsigned_ints,
|
||||
@encode(unsigned int));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_long_ints,
|
||||
@encode(long int));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_unsigned_long_ints,
|
||||
@encode(unsigned long int));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_chars,
|
||||
@encode(char));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_unsigned_chars,
|
||||
@encode(unsigned char));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_shorts,
|
||||
@encode(short));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_unsigned_shorts,
|
||||
@encode(unsigned short));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_floats,
|
||||
@encode(float));
|
||||
#if (ELT_INCLUDES_DOUBLE)
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_doubles,
|
||||
@encode(double));
|
||||
#endif
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_strings,
|
||||
@encode(char*));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_void_ptrs,
|
||||
@encode(void*));
|
||||
coll_hash_add(&__comp_func_hashtable,
|
||||
(void*)elt_compare_objects,
|
||||
@encode(id));
|
||||
}
|
||||
|
||||
const char *
|
||||
elt_get_encoding(int(*comparison_function)(elt,elt))
|
||||
{
|
||||
if (!__comp_func_hashtable)
|
||||
__init_comp_func_hashtable();
|
||||
|
||||
return (const char *)
|
||||
coll_hash_value_for_key(__comp_func_hashtable,
|
||||
(void*)comparison_function).char_ptr_u;
|
||||
}
|
||||
|
||||
|
||||
/* Is this really necessary? Can I count on element members always
|
||||
starting at the beginning? */
|
||||
|
||||
extern void *elt_get_ptr_to_member(const char *encoding, elt *anElement)
|
||||
{
|
||||
switch (*encoding)
|
||||
{
|
||||
case _C_CHARPTR:
|
||||
case _C_ATOM:
|
||||
return &(anElement->char_ptr_u);
|
||||
|
||||
case _C_ID:
|
||||
case _C_CLASS:
|
||||
return &(anElement->id_u);
|
||||
|
||||
case _C_PTR:
|
||||
return &(anElement->void_ptr_u);
|
||||
|
||||
case _C_SEL:
|
||||
return &(anElement->SEL_u);
|
||||
|
||||
case _C_CHR:
|
||||
return &(anElement->char_u);
|
||||
|
||||
case _C_UCHR:
|
||||
return &(anElement->unsigned_char_u);
|
||||
|
||||
case _C_SHT:
|
||||
return &(anElement->short_int_u);
|
||||
|
||||
case _C_USHT:
|
||||
return &(anElement->unsigned_short_int_u);
|
||||
break;
|
||||
|
||||
case _C_INT:
|
||||
return &(anElement->int_u);
|
||||
|
||||
case _C_UINT:
|
||||
return &(anElement->unsigned_int_u);
|
||||
|
||||
case _C_LNG:
|
||||
return &(anElement->long_int_u);
|
||||
|
||||
case _C_ULNG:
|
||||
return &(anElement->unsigned_long_int_u);
|
||||
|
||||
case _C_FLT:
|
||||
return &(anElement->float_u);
|
||||
|
||||
#if (ELT_INCLUDES_DOUBLE)
|
||||
case _C_DBL:
|
||||
return &(anElement->double_u);
|
||||
#endif
|
||||
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
elt_fprintf_elt(FILE *fp, const char *encoding, elt anElement)
|
||||
{
|
||||
switch (*encoding)
|
||||
{
|
||||
case _C_CHARPTR:
|
||||
case _C_ATOM:
|
||||
fprintf(fp, "\"%s\"", anElement.char_ptr_u);
|
||||
break;
|
||||
|
||||
case _C_ID:
|
||||
case _C_CLASS:
|
||||
fprintf(fp, "%s:0x%x", [anElement.id_u name], anElement.unsigned_int_u);
|
||||
break;
|
||||
|
||||
case _C_PTR:
|
||||
fprintf(fp, "0x%x", anElement.unsigned_int_u);
|
||||
break;
|
||||
|
||||
case _C_SEL:
|
||||
fprintf(fp, "%s", sel_get_name(anElement.SEL_u));
|
||||
break;
|
||||
|
||||
case _C_CHR:
|
||||
fprintf(fp, "%c", anElement.char_u);
|
||||
break;
|
||||
|
||||
case _C_UCHR:
|
||||
fprintf(fp, "%c", anElement.unsigned_char_u);
|
||||
break;
|
||||
|
||||
case _C_SHT:
|
||||
fprintf(fp, "%d", anElement.short_int_u);
|
||||
break;
|
||||
|
||||
case _C_USHT:
|
||||
fprintf(fp, "%d", anElement.unsigned_short_int_u);
|
||||
break;
|
||||
|
||||
case _C_INT:
|
||||
fprintf(fp, "%d", anElement.int_u);
|
||||
break;
|
||||
|
||||
case _C_UINT:
|
||||
fprintf(fp, "%d", anElement.unsigned_int_u);
|
||||
break;
|
||||
|
||||
case _C_LNG:
|
||||
fprintf(fp, "%ld", anElement.long_int_u);
|
||||
break;
|
||||
|
||||
case _C_ULNG:
|
||||
fprintf(fp, "%lu", anElement.unsigned_long_int_u);
|
||||
break;
|
||||
|
||||
case _C_FLT:
|
||||
fprintf(fp, "%g", anElement.float_u);
|
||||
break;
|
||||
|
||||
#if (ELT_INCLUDES_DOUBLE)
|
||||
case _C_DBL:
|
||||
fprintf(fp, "%g", anElement.double_u);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default :
|
||||
fprintf(fp, "unknown?");
|
||||
}
|
||||
}
|
|
@ -1,441 +0,0 @@
|
|||
/* Method encoding types for Objective C.
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Author: Kresten Krab Thorup
|
||||
Modified by: Andrew McCallum
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "gnustep/base/next2gnu.h"
|
||||
#include <objc/objc.h>
|
||||
#include <objc/objc-api.h>
|
||||
|
||||
/* Deal with strrchr: */
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
#include <string.h>
|
||||
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
|
||||
#if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#define bcopy(s, d, n) memcpy ((d), (s), (n))
|
||||
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
|
||||
#define bzero(s, n) memset ((s), 0, (n))
|
||||
#else /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
#include <strings.h>
|
||||
/* memory.h and strings.h conflict on some systems. */
|
||||
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
|
||||
#define MAX(X, Y) \
|
||||
({ typeof(X) __x = (X), __y = (Y); \
|
||||
(__x > __y ? __x : __y); })
|
||||
|
||||
#define MIN(X, Y) \
|
||||
({ typeof(X) __x = (X), __y = (Y); \
|
||||
(__x < __y ? __x : __y); })
|
||||
|
||||
#define ROUND(V, A) \
|
||||
({ typeof(V) __v=(V); typeof(A) __a=(A); \
|
||||
__a*((__v+__a-1)/__a); })
|
||||
|
||||
|
||||
static inline int
|
||||
atoi (const char* str)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
while (isdigit (*str))
|
||||
res *= 10, res += (*str++ - '0');
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#if NeXT_runtime
|
||||
/*
|
||||
return the size of an object specified by type
|
||||
*/
|
||||
|
||||
int
|
||||
objc_sizeof_type(const char* type)
|
||||
{
|
||||
switch(*type) {
|
||||
case _C_ID:
|
||||
return sizeof(id);
|
||||
break;
|
||||
|
||||
case _C_CLASS:
|
||||
return sizeof(Class);
|
||||
break;
|
||||
|
||||
case _C_SEL:
|
||||
return sizeof(SEL);
|
||||
break;
|
||||
|
||||
case _C_CHR:
|
||||
return sizeof(char);
|
||||
break;
|
||||
|
||||
case _C_UCHR:
|
||||
return sizeof(unsigned char);
|
||||
break;
|
||||
|
||||
case _C_SHT:
|
||||
return sizeof(short);
|
||||
break;
|
||||
|
||||
case _C_USHT:
|
||||
return sizeof(unsigned short);
|
||||
break;
|
||||
|
||||
case _C_INT:
|
||||
return sizeof(int);
|
||||
break;
|
||||
|
||||
case _C_UINT:
|
||||
return sizeof(unsigned int);
|
||||
break;
|
||||
|
||||
case _C_LNG:
|
||||
return sizeof(long);
|
||||
break;
|
||||
|
||||
case _C_ULNG:
|
||||
return sizeof(unsigned long);
|
||||
break;
|
||||
|
||||
case _C_FLT:
|
||||
return sizeof(float);
|
||||
break;
|
||||
|
||||
case _C_DBL:
|
||||
return sizeof(double);
|
||||
break;
|
||||
|
||||
case _C_PTR:
|
||||
case _C_ATOM:
|
||||
case _C_CHARPTR:
|
||||
return sizeof(char*);
|
||||
break;
|
||||
|
||||
case _C_ARY_B:
|
||||
{
|
||||
int len = atoi(type+1);
|
||||
while (isdigit(*++type));
|
||||
return len*objc_aligned_size (type);
|
||||
}
|
||||
break;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
{
|
||||
int acc_size = 0;
|
||||
int align;
|
||||
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
|
||||
while (*type != _C_STRUCT_E)
|
||||
{
|
||||
align = objc_alignof_type (type); /* padd to alignment */
|
||||
acc_size = ROUND (acc_size, align);
|
||||
acc_size += objc_sizeof_type (type); /* add component size */
|
||||
type = objc_skip_typespec (type); /* skip component */
|
||||
}
|
||||
return acc_size;
|
||||
}
|
||||
|
||||
case _C_UNION_B:
|
||||
{
|
||||
int max_size = 0;
|
||||
while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
|
||||
while (*type != _C_UNION_E)
|
||||
{
|
||||
max_size = MAX (max_size, objc_sizeof_type (type));
|
||||
type = objc_skip_typespec (type);
|
||||
}
|
||||
return max_size;
|
||||
}
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return the alignment of an object specified by type
|
||||
*/
|
||||
|
||||
int
|
||||
objc_alignof_type(const char* type)
|
||||
{
|
||||
switch(*type) {
|
||||
case _C_ID:
|
||||
return __alignof__(id);
|
||||
break;
|
||||
|
||||
case _C_CLASS:
|
||||
return __alignof__(Class);
|
||||
break;
|
||||
|
||||
case _C_SEL:
|
||||
return __alignof__(SEL);
|
||||
break;
|
||||
|
||||
case _C_CHR:
|
||||
return __alignof__(char);
|
||||
break;
|
||||
|
||||
case _C_UCHR:
|
||||
return __alignof__(unsigned char);
|
||||
break;
|
||||
|
||||
case _C_SHT:
|
||||
return __alignof__(short);
|
||||
break;
|
||||
|
||||
case _C_USHT:
|
||||
return __alignof__(unsigned short);
|
||||
break;
|
||||
|
||||
case _C_INT:
|
||||
return __alignof__(int);
|
||||
break;
|
||||
|
||||
case _C_UINT:
|
||||
return __alignof__(unsigned int);
|
||||
break;
|
||||
|
||||
case _C_LNG:
|
||||
return __alignof__(long);
|
||||
break;
|
||||
|
||||
case _C_ULNG:
|
||||
return __alignof__(unsigned long);
|
||||
break;
|
||||
|
||||
case _C_FLT:
|
||||
return __alignof__(float);
|
||||
break;
|
||||
|
||||
case _C_DBL:
|
||||
return __alignof__(double);
|
||||
break;
|
||||
|
||||
case _C_ATOM:
|
||||
case _C_CHARPTR:
|
||||
return __alignof__(char*);
|
||||
break;
|
||||
|
||||
case _C_ARY_B:
|
||||
while (isdigit(*++type)) /* do nothing */;
|
||||
return objc_alignof_type (type);
|
||||
|
||||
case _C_STRUCT_B:
|
||||
{
|
||||
struct { int x; double y; } fooalign;
|
||||
while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */;
|
||||
if (*type != _C_STRUCT_E)
|
||||
return MAX (objc_alignof_type (type), __alignof__ (fooalign));
|
||||
else
|
||||
return __alignof__ (fooalign);
|
||||
}
|
||||
|
||||
case _C_UNION_B:
|
||||
{
|
||||
int maxalign = 0;
|
||||
while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
|
||||
while (*type != _C_UNION_E)
|
||||
{
|
||||
maxalign = MAX (maxalign, objc_alignof_type (type));
|
||||
type = objc_skip_typespec (type);
|
||||
}
|
||||
return maxalign;
|
||||
}
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The aligned size if the size rounded up to the nearest alignment.
|
||||
*/
|
||||
|
||||
int
|
||||
objc_aligned_size (const char* type)
|
||||
{
|
||||
int size = objc_sizeof_type (type);
|
||||
int align = objc_alignof_type (type);
|
||||
return ROUND (size, align);
|
||||
}
|
||||
|
||||
/*
|
||||
The size rounded up to the nearest integral of the wordsize, taken
|
||||
to be the size of a void*.
|
||||
*/
|
||||
|
||||
int
|
||||
objc_promoted_size (const char* type)
|
||||
{
|
||||
int size = objc_sizeof_type (type);
|
||||
int wordsize = sizeof (void*);
|
||||
|
||||
return ROUND (size, wordsize);
|
||||
}
|
||||
|
||||
/*
|
||||
Skip type qualifiers. These may eventually precede typespecs
|
||||
occuring in method prototype encodings.
|
||||
*/
|
||||
|
||||
inline const char*
|
||||
objc_skip_type_qualifiers (const char* type)
|
||||
{
|
||||
while (*type == _C_CONST
|
||||
|| *type == _C_IN
|
||||
|| *type == _C_INOUT
|
||||
|| *type == _C_OUT
|
||||
|| *type == _C_BYCOPY
|
||||
|| *type == _C_ONEWAY)
|
||||
{
|
||||
type += 1;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Skip one typespec element. If the typespec is prepended by type
|
||||
qualifiers, these are skipped as well.
|
||||
*/
|
||||
|
||||
const char*
|
||||
objc_skip_typespec (const char* type)
|
||||
{
|
||||
type = objc_skip_type_qualifiers (type);
|
||||
|
||||
switch (*type) {
|
||||
|
||||
case _C_ID:
|
||||
/* An id may be annotated by the actual type if it is known
|
||||
with the @"ClassName" syntax */
|
||||
|
||||
if (*++type != '"')
|
||||
return type;
|
||||
else
|
||||
{
|
||||
while (*++type != '"') /* do nothing */;
|
||||
return type + 1;
|
||||
}
|
||||
|
||||
/* The following are one character type codes */
|
||||
case _C_CLASS:
|
||||
case _C_SEL:
|
||||
case _C_CHR:
|
||||
case _C_UCHR:
|
||||
case _C_CHARPTR:
|
||||
case _C_ATOM:
|
||||
case _C_SHT:
|
||||
case _C_USHT:
|
||||
case _C_INT:
|
||||
case _C_UINT:
|
||||
case _C_LNG:
|
||||
case _C_ULNG:
|
||||
case _C_FLT:
|
||||
case _C_DBL:
|
||||
case _C_VOID:
|
||||
return ++type;
|
||||
break;
|
||||
|
||||
case _C_ARY_B:
|
||||
/* skip digits, typespec and closing ']' */
|
||||
|
||||
while(isdigit(*++type));
|
||||
type = objc_skip_typespec(type);
|
||||
if (*type == _C_ARY_E)
|
||||
return ++type;
|
||||
else
|
||||
abort();
|
||||
|
||||
case _C_STRUCT_B:
|
||||
/* skip name, and elements until closing '}' */
|
||||
|
||||
while (*type != _C_STRUCT_E && *type++ != '=');
|
||||
while (*type != _C_STRUCT_E) { type = objc_skip_typespec (type); }
|
||||
return ++type;
|
||||
|
||||
case _C_UNION_B:
|
||||
/* skip name, and elements until closing ')' */
|
||||
|
||||
while (*type != _C_UNION_E && *type++ != '=');
|
||||
while (*type != _C_UNION_E) { type = objc_skip_typespec (type); }
|
||||
return ++type;
|
||||
|
||||
case _C_PTR:
|
||||
/* Just skip the following typespec */
|
||||
|
||||
return objc_skip_typespec (++type);
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Skip an offset as part of a method encoding. This is prepended by a
|
||||
'+' if the argument is passed in registers.
|
||||
*/
|
||||
inline const char*
|
||||
objc_skip_offset (const char* type)
|
||||
{
|
||||
if (*type == '+') type++;
|
||||
while(isdigit(*++type));
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
Skip an argument specification of a method encoding.
|
||||
*/
|
||||
const char*
|
||||
objc_skip_argspec (const char* type)
|
||||
{
|
||||
type = objc_skip_typespec (type);
|
||||
type = objc_skip_offset (type);
|
||||
return type;
|
||||
}
|
||||
|
||||
unsigned
|
||||
objc_get_type_qualifiers (const char* type)
|
||||
{
|
||||
unsigned res = 0;
|
||||
BOOL flag = YES;
|
||||
|
||||
while (flag)
|
||||
switch (*type++)
|
||||
{
|
||||
case _C_CONST: res |= _F_CONST; break;
|
||||
case _C_IN: res |= _F_IN; break;
|
||||
case _C_INOUT: res |= _F_INOUT; break;
|
||||
case _C_OUT: res |= _F_OUT; break;
|
||||
case _C_BYCOPY: res |= _F_BYCOPY; break;
|
||||
case _C_ONEWAY: res |= _F_ONEWAY; break;
|
||||
default: flag = NO;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* NeXT_runtime */
|
|
@ -1,469 +0,0 @@
|
|||
/* Some functionality in the GNU runtime that's not in the NeXT runtime
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Author: Kresten Krab Thorup
|
||||
Modified by: Andrew McCallum
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if ! NeXT_runtime
|
||||
#error This file only needed if using NeXT runtime
|
||||
#endif /* ! NeXT_runtime */
|
||||
|
||||
#include "gnustep/base/gnu4next.h"
|
||||
#include <objc/objc.h>
|
||||
#include <objc/objc-api.h>
|
||||
|
||||
/* Deal with strrchr: */
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
#include <string.h>
|
||||
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
|
||||
#if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#define bcopy(s, d, n) memcpy ((d), (s), (n))
|
||||
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
|
||||
#define bzero(s, n) memset ((s), 0, (n))
|
||||
#else /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
#include <strings.h>
|
||||
/* memory.h and strings.h conflict on some systems. */
|
||||
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
|
||||
#define MAX(X, Y) \
|
||||
({ typeof(X) __x = (X), __y = (Y); \
|
||||
(__x > __y ? __x : __y); })
|
||||
|
||||
#define MIN(X, Y) \
|
||||
({ typeof(X) __x = (X), __y = (Y); \
|
||||
(__x < __y ? __x : __y); })
|
||||
|
||||
#define ROUND(V, A) \
|
||||
({ typeof(V) __v=(V); typeof(A) __a=(A); \
|
||||
__a*((__v+__a-1)/__a); })
|
||||
|
||||
|
||||
static inline int
|
||||
atoi (const char* str)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
while (isdigit (*str))
|
||||
res *= 10, res += (*str++ - '0');
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
return the size of an object specified by type
|
||||
*/
|
||||
|
||||
int
|
||||
objc_sizeof_type(const char* type)
|
||||
{
|
||||
switch(*type) {
|
||||
case _C_ID:
|
||||
return sizeof(id);
|
||||
break;
|
||||
|
||||
case _C_CLASS:
|
||||
return sizeof(Class);
|
||||
break;
|
||||
|
||||
case _C_SEL:
|
||||
return sizeof(SEL);
|
||||
break;
|
||||
|
||||
case _C_CHR:
|
||||
return sizeof(char);
|
||||
break;
|
||||
|
||||
case _C_UCHR:
|
||||
return sizeof(unsigned char);
|
||||
break;
|
||||
|
||||
case _C_SHT:
|
||||
return sizeof(short);
|
||||
break;
|
||||
|
||||
case _C_USHT:
|
||||
return sizeof(unsigned short);
|
||||
break;
|
||||
|
||||
case _C_INT:
|
||||
return sizeof(int);
|
||||
break;
|
||||
|
||||
case _C_UINT:
|
||||
return sizeof(unsigned int);
|
||||
break;
|
||||
|
||||
case _C_LNG:
|
||||
return sizeof(long);
|
||||
break;
|
||||
|
||||
case _C_ULNG:
|
||||
return sizeof(unsigned long);
|
||||
break;
|
||||
|
||||
case _C_FLT:
|
||||
return sizeof(float);
|
||||
break;
|
||||
|
||||
case _C_DBL:
|
||||
return sizeof(double);
|
||||
break;
|
||||
|
||||
case _C_PTR:
|
||||
case _C_ATOM:
|
||||
case _C_CHARPTR:
|
||||
return sizeof(char*);
|
||||
break;
|
||||
|
||||
case _C_ARY_B:
|
||||
{
|
||||
int len = atoi(type+1);
|
||||
while (isdigit(*++type));
|
||||
return len*objc_aligned_size (type);
|
||||
}
|
||||
break;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
{
|
||||
int acc_size = 0;
|
||||
int align;
|
||||
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
|
||||
while (*type != _C_STRUCT_E)
|
||||
{
|
||||
align = objc_alignof_type (type); /* padd to alignment */
|
||||
acc_size = ROUND (acc_size, align);
|
||||
acc_size += objc_sizeof_type (type); /* add component size */
|
||||
type = objc_skip_typespec (type); /* skip component */
|
||||
}
|
||||
return acc_size;
|
||||
}
|
||||
|
||||
case _C_UNION_B:
|
||||
{
|
||||
int max_size = 0;
|
||||
while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
|
||||
while (*type != _C_UNION_E)
|
||||
{
|
||||
max_size = MAX (max_size, objc_sizeof_type (type));
|
||||
type = objc_skip_typespec (type);
|
||||
}
|
||||
return max_size;
|
||||
}
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return the alignment of an object specified by type
|
||||
*/
|
||||
|
||||
int
|
||||
objc_alignof_type(const char* type)
|
||||
{
|
||||
switch(*type) {
|
||||
case _C_ID:
|
||||
return __alignof__(id);
|
||||
break;
|
||||
|
||||
case _C_CLASS:
|
||||
return __alignof__(Class);
|
||||
break;
|
||||
|
||||
case _C_SEL:
|
||||
return __alignof__(SEL);
|
||||
break;
|
||||
|
||||
case _C_CHR:
|
||||
return __alignof__(char);
|
||||
break;
|
||||
|
||||
case _C_UCHR:
|
||||
return __alignof__(unsigned char);
|
||||
break;
|
||||
|
||||
case _C_SHT:
|
||||
return __alignof__(short);
|
||||
break;
|
||||
|
||||
case _C_USHT:
|
||||
return __alignof__(unsigned short);
|
||||
break;
|
||||
|
||||
case _C_INT:
|
||||
return __alignof__(int);
|
||||
break;
|
||||
|
||||
case _C_UINT:
|
||||
return __alignof__(unsigned int);
|
||||
break;
|
||||
|
||||
case _C_LNG:
|
||||
return __alignof__(long);
|
||||
break;
|
||||
|
||||
case _C_ULNG:
|
||||
return __alignof__(unsigned long);
|
||||
break;
|
||||
|
||||
case _C_FLT:
|
||||
return __alignof__(float);
|
||||
break;
|
||||
|
||||
case _C_DBL:
|
||||
return __alignof__(double);
|
||||
break;
|
||||
|
||||
case _C_ATOM:
|
||||
case _C_CHARPTR:
|
||||
return __alignof__(char*);
|
||||
break;
|
||||
|
||||
case _C_ARY_B:
|
||||
while (isdigit(*++type)) /* do nothing */;
|
||||
return objc_alignof_type (type);
|
||||
|
||||
case _C_STRUCT_B:
|
||||
{
|
||||
struct { int x; double y; } fooalign;
|
||||
while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */;
|
||||
if (*type != _C_STRUCT_E)
|
||||
return MAX (objc_alignof_type (type), __alignof__ (fooalign));
|
||||
else
|
||||
return __alignof__ (fooalign);
|
||||
}
|
||||
|
||||
case _C_UNION_B:
|
||||
{
|
||||
int maxalign = 0;
|
||||
while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
|
||||
while (*type != _C_UNION_E)
|
||||
{
|
||||
maxalign = MAX (maxalign, objc_alignof_type (type));
|
||||
type = objc_skip_typespec (type);
|
||||
}
|
||||
return maxalign;
|
||||
}
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The aligned size if the size rounded up to the nearest alignment.
|
||||
*/
|
||||
|
||||
int
|
||||
objc_aligned_size (const char* type)
|
||||
{
|
||||
int size = objc_sizeof_type (type);
|
||||
int align = objc_alignof_type (type);
|
||||
return ROUND (size, align);
|
||||
}
|
||||
|
||||
/*
|
||||
The size rounded up to the nearest integral of the wordsize, taken
|
||||
to be the size of a void*.
|
||||
*/
|
||||
|
||||
int
|
||||
objc_promoted_size (const char* type)
|
||||
{
|
||||
int size = objc_sizeof_type (type);
|
||||
int wordsize = sizeof (void*);
|
||||
|
||||
return ROUND (size, wordsize);
|
||||
}
|
||||
|
||||
/*
|
||||
Skip type qualifiers. These may eventually precede typespecs
|
||||
occuring in method prototype encodings.
|
||||
*/
|
||||
|
||||
inline const char*
|
||||
objc_skip_type_qualifiers (const char* type)
|
||||
{
|
||||
while (*type == _C_CONST
|
||||
|| *type == _C_IN
|
||||
|| *type == _C_INOUT
|
||||
|| *type == _C_OUT
|
||||
|| *type == _C_BYCOPY
|
||||
|| *type == _C_ONEWAY)
|
||||
{
|
||||
type += 1;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Skip one typespec element. If the typespec is prepended by type
|
||||
qualifiers, these are skipped as well.
|
||||
*/
|
||||
|
||||
const char*
|
||||
objc_skip_typespec (const char* type)
|
||||
{
|
||||
type = objc_skip_type_qualifiers (type);
|
||||
|
||||
switch (*type) {
|
||||
|
||||
case _C_ID:
|
||||
/* An id may be annotated by the actual type if it is known
|
||||
with the @"ClassName" syntax */
|
||||
|
||||
if (*++type != '"')
|
||||
return type;
|
||||
else
|
||||
{
|
||||
while (*++type != '"') /* do nothing */;
|
||||
return type + 1;
|
||||
}
|
||||
|
||||
/* The following are one character type codes */
|
||||
case _C_CLASS:
|
||||
case _C_SEL:
|
||||
case _C_CHR:
|
||||
case _C_UCHR:
|
||||
case _C_CHARPTR:
|
||||
case _C_ATOM:
|
||||
case _C_SHT:
|
||||
case _C_USHT:
|
||||
case _C_INT:
|
||||
case _C_UINT:
|
||||
case _C_LNG:
|
||||
case _C_ULNG:
|
||||
case _C_FLT:
|
||||
case _C_DBL:
|
||||
case _C_VOID:
|
||||
return ++type;
|
||||
break;
|
||||
|
||||
case _C_ARY_B:
|
||||
/* skip digits, typespec and closing ']' */
|
||||
|
||||
while(isdigit(*++type));
|
||||
type = objc_skip_typespec(type);
|
||||
if (*type == _C_ARY_E)
|
||||
return ++type;
|
||||
else
|
||||
abort();
|
||||
|
||||
case _C_STRUCT_B:
|
||||
/* skip name, and elements until closing '}' */
|
||||
|
||||
while (*type != _C_STRUCT_E && *type++ != '=');
|
||||
while (*type != _C_STRUCT_E) { type = objc_skip_typespec (type); }
|
||||
return ++type;
|
||||
|
||||
case _C_UNION_B:
|
||||
/* skip name, and elements until closing ')' */
|
||||
|
||||
while (*type != _C_UNION_E && *type++ != '=');
|
||||
while (*type != _C_UNION_E) { type = objc_skip_typespec (type); }
|
||||
return ++type;
|
||||
|
||||
case _C_PTR:
|
||||
/* Just skip the following typespec */
|
||||
|
||||
return objc_skip_typespec (++type);
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Skip an offset as part of a method encoding. This is prepended by a
|
||||
'+' if the argument is passed in registers.
|
||||
*/
|
||||
inline const char*
|
||||
objc_skip_offset (const char* type)
|
||||
{
|
||||
if (*type == '+') type++;
|
||||
while(isdigit(*++type));
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
Skip an argument specification of a method encoding.
|
||||
*/
|
||||
const char*
|
||||
objc_skip_argspec (const char* type)
|
||||
{
|
||||
type = objc_skip_typespec (type);
|
||||
type = objc_skip_offset (type);
|
||||
return type;
|
||||
}
|
||||
|
||||
unsigned
|
||||
objc_get_type_qualifiers (const char* type)
|
||||
{
|
||||
unsigned res = 0;
|
||||
BOOL flag = YES;
|
||||
|
||||
while (flag)
|
||||
switch (*type++)
|
||||
{
|
||||
case _C_CONST: res |= _F_CONST; break;
|
||||
case _C_IN: res |= _F_IN; break;
|
||||
case _C_INOUT: res |= _F_INOUT; break;
|
||||
case _C_OUT: res |= _F_OUT; break;
|
||||
case _C_BYCOPY: res |= _F_BYCOPY; break;
|
||||
case _C_ONEWAY: res |= _F_ONEWAY; break;
|
||||
default: flag = NO;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Returns YES iff t1 and t2 have same method types, but we ignore
|
||||
the argframe layout */
|
||||
BOOL
|
||||
sel_types_match (const char* t1, const char* t2)
|
||||
{
|
||||
if (!t1 || !t2)
|
||||
return NO;
|
||||
while (*t1 && *t2)
|
||||
{
|
||||
if (*t1 == '+') t1++;
|
||||
if (*t2 == '+') t2++;
|
||||
while (isdigit(*t1)) t1++;
|
||||
while (isdigit(*t2)) t2++;
|
||||
/* xxx Remove these next two lines when qualifiers are put in
|
||||
all selectors, not just Protocol selectors. */
|
||||
t1 = objc_skip_type_qualifiers(t1);
|
||||
t2 = objc_skip_type_qualifiers(t2);
|
||||
if (!*t1 && !*t2)
|
||||
return YES;
|
||||
if (*t1 != *t2)
|
||||
return NO;
|
||||
t1++;
|
||||
t2++;
|
||||
}
|
||||
return NO;
|
||||
}
|
|
@ -1,585 +0,0 @@
|
|||
/* Implementation of o_vprintf for GNUstep Base Library
|
||||
|
||||
Reworked by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: July 1994
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Reworked from glibc by Andrew McCallum:
|
||||
Use function pointer argument to put next character.
|
||||
|
||||
This is a solution for MemoryStream. It's not ideal.
|
||||
It is a temporary fix.
|
||||
On GNU systems we could just use GNU stdio stream functions, but
|
||||
on non-GNU systems, using this is easier than installing glibc. */
|
||||
|
||||
/* #include <ansidecl.h> */
|
||||
/* #include <localeinfo.h> */
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
/* #include <printf.h> */
|
||||
#include <assert.h>
|
||||
#include "_itoa.h"
|
||||
|
||||
|
||||
/* If it's an unbuffered stream that we provided
|
||||
temporary buffering for, remove that buffering. */
|
||||
#define RETURN(x) \
|
||||
do \
|
||||
{ \
|
||||
done = (x); \
|
||||
goto do_return; \
|
||||
} while (0)
|
||||
|
||||
#define outchar(x) \
|
||||
do \
|
||||
{ \
|
||||
char outc = (x); \
|
||||
if ((*write_func)(stream, &outc, 1) == EOF) \
|
||||
RETURN(-1); \
|
||||
else \
|
||||
++done; \
|
||||
} while (0)
|
||||
|
||||
/* Cast the next arg, of type ARGTYPE, into CASTTYPE, and put it in VAR. */
|
||||
#define castarg(var, argtype, casttype) \
|
||||
var = (casttype) va_arg(args, argtype)
|
||||
/* Get the next arg, of type TYPE, and put it in VAR. */
|
||||
#define nextarg(var, type) castarg(var, type, type)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define HAVE_LONGLONG
|
||||
#define LONGLONG long long
|
||||
#else
|
||||
#define LONGLONG long
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
o_vprintf(void *stream,
|
||||
int (*write_func)(void*, char*, int len),
|
||||
const char *format, va_list args)
|
||||
{
|
||||
/* Pointer into the format string. */
|
||||
register const char *f;
|
||||
|
||||
/* Number of characters written. */
|
||||
register size_t done = 0;
|
||||
|
||||
/* Reset multibyte characters to their initial state. */
|
||||
(void) mblen((char *) NULL, 0);
|
||||
|
||||
f = format;
|
||||
while (*f != '\0')
|
||||
{
|
||||
/* Type modifiers. */
|
||||
char is_short, is_long, is_long_double;
|
||||
#ifdef HAVE_LONGLONG
|
||||
/* We use the `L' modifier for `long long int'. */
|
||||
#define is_longlong is_long_double
|
||||
#else
|
||||
#define is_longlong 0
|
||||
#endif
|
||||
/* Format spec modifiers. */
|
||||
char space, showsign, left, alt;
|
||||
|
||||
/* Padding character: ' ' or '0'. */
|
||||
char pad;
|
||||
/* Width of a field. */
|
||||
register int width;
|
||||
/* Precision of a field. */
|
||||
int prec;
|
||||
|
||||
/* Decimal integer is negative. */
|
||||
char is_neg;
|
||||
|
||||
/* Current character of the format. */
|
||||
char fc;
|
||||
|
||||
/* Base of a number to be written. */
|
||||
int base;
|
||||
/* Integral values to be written. */
|
||||
unsigned LONGLONG int num;
|
||||
LONGLONG int signed_num;
|
||||
|
||||
/* String to be written. */
|
||||
const char *str;
|
||||
char unknown_error[256]; /* Buffer sometimes used by %m. */
|
||||
|
||||
if (!isascii(*f))
|
||||
{
|
||||
/* Non-ASCII, may be a multibyte. */
|
||||
int len = mblen(f, strlen(f));
|
||||
if (len > 0)
|
||||
{
|
||||
while (len-- > 0)
|
||||
outchar(*f++);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (*f != '%')
|
||||
{
|
||||
/* This isn't a format spec, so write
|
||||
everything out until the next one. */
|
||||
const char *next = strchr(f + 1, '%');
|
||||
if (next == NULL)
|
||||
next = strchr(f + 1, '\0');
|
||||
if (next - f > 20)
|
||||
{
|
||||
size_t written = (*write_func)(stream, (void*)f, next - f);
|
||||
done += written;
|
||||
if (written != next - f)
|
||||
break;
|
||||
f += written;
|
||||
}
|
||||
else
|
||||
while (f < next)
|
||||
outchar(*f++);
|
||||
continue;
|
||||
}
|
||||
|
||||
++f;
|
||||
|
||||
/* Check for "%%". Note that although the ANSI standard lists
|
||||
'%' as a conversion specifier, it says "The complete format
|
||||
specification shall be `%%'," so we can avoid all the width
|
||||
and precision processing. */
|
||||
if (*f == '%')
|
||||
{
|
||||
++f;
|
||||
outchar('%');
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for spec modifiers. */
|
||||
space = showsign = left = alt = 0;
|
||||
pad = ' ';
|
||||
while (*f == ' ' || *f == '+' || *f == '-' || *f == '#' || *f == '0')
|
||||
switch (*f++)
|
||||
{
|
||||
case ' ':
|
||||
/* Output a space in place of a sign, when there is no sign. */
|
||||
space = 1;
|
||||
break;
|
||||
case '+':
|
||||
/* Always output + or - for numbers. */
|
||||
showsign = 1;
|
||||
break;
|
||||
case '-':
|
||||
/* Left-justify things. */
|
||||
left = 1;
|
||||
break;
|
||||
case '#':
|
||||
/* Use the "alternate form":
|
||||
Hex has 0x or 0X, FP always has a decimal point. */
|
||||
alt = 1;
|
||||
break;
|
||||
case '0':
|
||||
/* Pad with 0s. */
|
||||
pad = '0';
|
||||
break;
|
||||
}
|
||||
if (left)
|
||||
pad = ' ';
|
||||
|
||||
/* Get the field width. */
|
||||
width = 0;
|
||||
if (*f == '*')
|
||||
{
|
||||
/* The field width is given in an argument.
|
||||
A negative field width indicates left justification. */
|
||||
nextarg(width, int);
|
||||
if (width < 0)
|
||||
{
|
||||
width = - width;
|
||||
left = 1;
|
||||
}
|
||||
++f;
|
||||
}
|
||||
else
|
||||
while (isdigit(*f))
|
||||
{
|
||||
width *= 10;
|
||||
width += *f++ - '0';
|
||||
}
|
||||
|
||||
/* Get the precision. */
|
||||
/* -1 means none given; 0 means explicit 0. */
|
||||
prec = -1;
|
||||
if (*f == '.')
|
||||
{
|
||||
++f;
|
||||
if (*f == '*')
|
||||
{
|
||||
/* The precision is given in an argument. */
|
||||
nextarg(prec, int);
|
||||
/* Avoid idiocy. */
|
||||
if (prec < 0)
|
||||
prec = -1;
|
||||
++f;
|
||||
}
|
||||
else if (isdigit(*f))
|
||||
{
|
||||
prec = 0;
|
||||
while (*f != '\0' && isdigit(*f))
|
||||
{
|
||||
prec *= 10;
|
||||
prec += *f++ - '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for type modifiers. */
|
||||
is_short = is_long = is_long_double = 0;
|
||||
while (*f == 'h' || *f == 'l' || *f == 'L')
|
||||
switch (*f++)
|
||||
{
|
||||
case 'h':
|
||||
/* int's are short int's. */
|
||||
is_short = 1;
|
||||
break;
|
||||
case 'l':
|
||||
#ifdef HAVE_LONGLONG
|
||||
if (is_long)
|
||||
/* A double `l' is equivalent to an `L'. */
|
||||
is_longlong = 1;
|
||||
else
|
||||
#endif
|
||||
/* int's are long int's. */
|
||||
is_long = 1;
|
||||
break;
|
||||
case 'L':
|
||||
/* double's are long double's, and int's are long long int's. */
|
||||
is_long_double = 1;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
/* int's are size_t's. */
|
||||
#ifdef HAVE_LONGLONG
|
||||
assert (sizeof(size_t) <= sizeof(unsigned long long int));
|
||||
is_longlong = sizeof(size_t) > sizeof(unsigned long int);
|
||||
#endif
|
||||
is_long = sizeof(size_t) > sizeof(unsigned int);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Format specification. */
|
||||
fc = *f++;
|
||||
if (1)
|
||||
switch (fc)
|
||||
{
|
||||
case 'i':
|
||||
case 'd':
|
||||
/* Decimal integer. */
|
||||
base = 10;
|
||||
if (is_longlong)
|
||||
nextarg(signed_num, LONGLONG int);
|
||||
else if (is_long)
|
||||
nextarg(signed_num, long int);
|
||||
else if (!is_short)
|
||||
castarg(signed_num, int, long int);
|
||||
else
|
||||
castarg(signed_num, int, short int);
|
||||
|
||||
is_neg = signed_num < 0;
|
||||
num = is_neg ? (- signed_num) : signed_num;
|
||||
goto number;
|
||||
|
||||
case 'u':
|
||||
/* Decimal unsigned integer. */
|
||||
base = 10;
|
||||
goto unsigned_number;
|
||||
|
||||
case 'o':
|
||||
/* Octal unsigned integer. */
|
||||
base = 8;
|
||||
goto unsigned_number;
|
||||
|
||||
case 'X':
|
||||
/* Hexadecimal unsigned integer. */
|
||||
case 'x':
|
||||
/* Hex with lower-case digits. */
|
||||
|
||||
base = 16;
|
||||
|
||||
unsigned_number:
|
||||
/* Unsigned number of base BASE. */
|
||||
|
||||
if (is_longlong)
|
||||
castarg(num, LONGLONG int, unsigned LONGLONG int);
|
||||
else if (is_long)
|
||||
castarg(num, long int, unsigned long int);
|
||||
else if (!is_short)
|
||||
castarg(num, int, unsigned int);
|
||||
else
|
||||
castarg(num, int, unsigned short int);
|
||||
|
||||
/* ANSI only specifies the `+' and
|
||||
` ' flags for signed conversions. */
|
||||
is_neg = showsign = space = 0;
|
||||
|
||||
number:
|
||||
/* Number of base BASE. */
|
||||
{
|
||||
char work[BUFSIZ];
|
||||
char *const workend = &work[sizeof(work) - 1];
|
||||
register char *w;
|
||||
|
||||
/* Supply a default precision if none was given. */
|
||||
if (prec == -1)
|
||||
prec = 1;
|
||||
|
||||
/* Put the number in WORK. */
|
||||
w = _itoa (num, workend + 1, base, fc == 'X') - 1;
|
||||
width -= workend - w;
|
||||
prec -= workend - w;
|
||||
|
||||
if (alt && base == 8 && prec <= 0)
|
||||
{
|
||||
*w-- = '0';
|
||||
--width;
|
||||
}
|
||||
|
||||
if (prec > 0)
|
||||
{
|
||||
width -= prec;
|
||||
while (prec-- > 0)
|
||||
*w-- = '0';
|
||||
}
|
||||
|
||||
if (alt && base == 16)
|
||||
width -= 2;
|
||||
|
||||
if (is_neg || showsign || space)
|
||||
--width;
|
||||
|
||||
if (!left && pad == ' ')
|
||||
while (width-- > 0)
|
||||
outchar(' ');
|
||||
|
||||
if (is_neg)
|
||||
outchar('-');
|
||||
else if (showsign)
|
||||
outchar('+');
|
||||
else if (space)
|
||||
outchar(' ');
|
||||
|
||||
if (alt && base == 16)
|
||||
{
|
||||
outchar ('0');
|
||||
outchar (fc);
|
||||
}
|
||||
|
||||
if (!left && pad == '0')
|
||||
while (width-- > 0)
|
||||
outchar('0');
|
||||
|
||||
/* Write the number. */
|
||||
while (++w <= workend)
|
||||
outchar(*w);
|
||||
|
||||
if (left)
|
||||
while (width-- > 0)
|
||||
outchar(' ');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'G':
|
||||
{
|
||||
/* Floating-point number. */
|
||||
extern printf_function __printf_fp;
|
||||
function = __printf_fp;
|
||||
goto use_function;
|
||||
}
|
||||
|
||||
case 'c':
|
||||
/* Character. */
|
||||
nextarg(num, int);
|
||||
if (!left)
|
||||
while (--width > 0)
|
||||
outchar(' ');
|
||||
outchar((unsigned char) num);
|
||||
if (left)
|
||||
while (--width > 0)
|
||||
outchar(' ');
|
||||
break;
|
||||
|
||||
case 's':
|
||||
{
|
||||
static CONST char null[] = "(null)";
|
||||
size_t len;
|
||||
|
||||
nextarg(str, CONST char *);
|
||||
|
||||
string:
|
||||
|
||||
if (str == NULL)
|
||||
/* Write "(null)" if there's space. */
|
||||
if (prec == -1 || prec >= (int) sizeof(null) - 1)
|
||||
{
|
||||
str = null;
|
||||
len = sizeof(null) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = "";
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
len = strlen(str);
|
||||
|
||||
if (prec != -1 && (size_t) prec < len)
|
||||
len = prec;
|
||||
width -= len;
|
||||
|
||||
if (!left)
|
||||
while (width-- > 0)
|
||||
outchar(' ');
|
||||
if (len < 20)
|
||||
while (len-- > 0)
|
||||
outchar(*str++);
|
||||
else
|
||||
if ((*write_func)(stream, str, len) != len)
|
||||
RETURN(-1);
|
||||
else
|
||||
done += len;
|
||||
if (left)
|
||||
while (width-- > 0)
|
||||
outchar(' ');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
/* Generic pointer. */
|
||||
{
|
||||
CONST PTR ptr;
|
||||
nextarg(ptr, const void*);
|
||||
if (ptr != NULL)
|
||||
{
|
||||
/* If the pointer is not NULL, write it as a %#x spec. */
|
||||
base = 16;
|
||||
fc = 'x';
|
||||
alt = 1;
|
||||
num = (unsigned LONGLONG int) (unsigned long int) ptr;
|
||||
is_neg = 0;
|
||||
goto number;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write "(nil)" for a nil pointer. */
|
||||
static const char nil[] = "(nil)";
|
||||
register const char *p;
|
||||
|
||||
width -= sizeof (nil) - 1;
|
||||
if (!left)
|
||||
while (width-- > 0)
|
||||
outchar (' ');
|
||||
for (p = nil; *p != '\0'; ++p)
|
||||
outchar (*p);
|
||||
if (left)
|
||||
while (width-- > 0)
|
||||
outchar (' ');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
/* Answer the count of characters written. */
|
||||
if (is_longlong)
|
||||
{
|
||||
LONGLONG int *p;
|
||||
nextarg(p, LONGLONG int *);
|
||||
*p = done;
|
||||
}
|
||||
else if (is_long)
|
||||
{
|
||||
long int *p;
|
||||
nextarg(p, long int *);
|
||||
*p = done;
|
||||
}
|
||||
else if (!is_short)
|
||||
{
|
||||
int *p;
|
||||
nextarg(p, int *);
|
||||
*p = done;
|
||||
}
|
||||
else
|
||||
{
|
||||
short int *p;
|
||||
nextarg(p, short int *);
|
||||
*p = done;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
#ifndef HAVE_GNU_LD
|
||||
#define _sys_errlist sys_errlist
|
||||
#define _sys_nerr sys_nerr
|
||||
#endif
|
||||
|
||||
if (errno < 0 || errno > _sys_nerr)
|
||||
{
|
||||
sprintf (unknown_error, "Unknown error %d", errno);
|
||||
str = unknown_error;
|
||||
}
|
||||
else
|
||||
str = _sys_errlist[errno];
|
||||
goto string;
|
||||
|
||||
default:
|
||||
/* Unrecognized format specifier. */
|
||||
sprintf (unknown_error, "Unknown format specifier %c", fc);
|
||||
str = unknown_error;
|
||||
goto string;
|
||||
}
|
||||
}
|
||||
|
||||
do_return:;
|
||||
return done;
|
||||
}
|
||||
|
599
Source/vfscanf.c
599
Source/vfscanf.c
|
@ -1,599 +0,0 @@
|
|||
/* Implementation of vfscanf for GNUstep Base Library
|
||||
|
||||
Reworked by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Reworked from glibc by Andrew McCallum:
|
||||
Fixed bug by adding "*f == 'a'" to type modifier checking.
|
||||
Declared extern strtod. */
|
||||
|
||||
/* #include <localeinfo.h> */
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern double strtod(const char *str, char **ptr);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define HAVE_LONGLONG
|
||||
#define LONGLONG long long
|
||||
#define CONST const
|
||||
#define LONG_DOUBLE long double
|
||||
#else
|
||||
#define LONGLONG long
|
||||
#define CONST
|
||||
#endif
|
||||
|
||||
|
||||
#define inchar() ((c = getc(s)) == EOF ? EOF : (++read_in, c))
|
||||
#define conv_error() return ((c == EOF || ungetc(c, s)), done)
|
||||
#define input_error() return (done == 0 ? EOF : done)
|
||||
#define memory_error() return ((errno = ENOMEM), EOF)
|
||||
|
||||
|
||||
/* Read formatted input from S according to the format string
|
||||
FORMAT, using the argument list in ARG.
|
||||
Return the number of assignments made, or -1 for an input error. */
|
||||
int
|
||||
o_vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
{
|
||||
va_list arg = (va_list) argptr;
|
||||
|
||||
register CONST char *f = format;
|
||||
register char fc; /* Current character of the format. */
|
||||
register size_t done = 0; /* Assignments done. */
|
||||
register size_t read_in = 0; /* Chars read in. */
|
||||
register int c; /* Last char read. */
|
||||
register int do_assign; /* Whether to do an assignment. */
|
||||
register int width; /* Maximum field width. */
|
||||
|
||||
/* Type modifiers. */
|
||||
char is_short, is_long, is_long_double;
|
||||
#ifdef HAVE_LONGLONG
|
||||
/* We use the `L' modifier for `long long int'. */
|
||||
#define is_longlong is_long_double
|
||||
#else
|
||||
#define is_longlong 0
|
||||
#endif
|
||||
int malloc_string; /* Args are char ** to be filled in. */
|
||||
/* Status for reading F-P nums. */
|
||||
char got_dot, got_e;
|
||||
/* If a [...] is a [^...]. */
|
||||
char not_in;
|
||||
/* Base for integral numbers. */
|
||||
int base;
|
||||
/* Signedness for integral numbers. */
|
||||
int number_signed;
|
||||
/* Integral holding variables. */
|
||||
long int num;
|
||||
unsigned long int unum;
|
||||
/* Floating-point holding variable. */
|
||||
LONG_DOUBLE fp_num;
|
||||
/* Character-buffer pointer. */
|
||||
register char *str, **strptr;
|
||||
size_t strsize;
|
||||
/* Workspace. */
|
||||
char work[200];
|
||||
char *w; /* Pointer into WORK. */
|
||||
wchar_t decimal; /* Decimal point character. */
|
||||
|
||||
#if 0
|
||||
if (!__validfp(s) || !s->__mode.__read || format == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return EOF;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Figure out the decimal point character. */
|
||||
#if 0
|
||||
if (mbtowc(&decimal, _numeric_info->decimal_point,
|
||||
strlen(_numeric_info->decimal_point)) <= 0)
|
||||
decimal = (wchar_t) *_numeric_info->decimal_point;
|
||||
#else
|
||||
decimal = '.';
|
||||
#endif
|
||||
|
||||
c = inchar();
|
||||
|
||||
/* Run through the format string. */
|
||||
while (*f != '\0')
|
||||
{
|
||||
if (!isascii(*f))
|
||||
{
|
||||
/* Non-ASCII, may be a multibyte. */
|
||||
int len = mblen(f, strlen(f));
|
||||
if (len > 0)
|
||||
{
|
||||
while (len-- > 0)
|
||||
if (c == EOF)
|
||||
input_error();
|
||||
else if (c == *f++)
|
||||
(void) inchar();
|
||||
else
|
||||
conv_error();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fc = *f++;
|
||||
if (fc != '%')
|
||||
{
|
||||
/* Characters other than format specs must just match. */
|
||||
if (c == EOF)
|
||||
input_error();
|
||||
if (isspace(fc))
|
||||
{
|
||||
/* Whitespace characters match any amount of whitespace. */
|
||||
while (isspace (c))
|
||||
inchar ();
|
||||
continue;
|
||||
}
|
||||
else if (c == fc)
|
||||
(void) inchar();
|
||||
else
|
||||
conv_error();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for the assignment-suppressant. */
|
||||
if (*f == '*')
|
||||
{
|
||||
do_assign = 0;
|
||||
++f;
|
||||
}
|
||||
else
|
||||
do_assign = 1;
|
||||
|
||||
/* Find the maximum field width. */
|
||||
width = 0;
|
||||
while (isdigit(*f))
|
||||
{
|
||||
width *= 10;
|
||||
width += *f++ - '0';
|
||||
}
|
||||
if (width == 0)
|
||||
width = -1;
|
||||
|
||||
/* Check for type modifiers. */
|
||||
is_short = is_long = is_long_double = malloc_string = 0;
|
||||
while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'a')
|
||||
switch (*f++)
|
||||
{
|
||||
case 'h':
|
||||
/* int's are short int's. */
|
||||
is_short = 1;
|
||||
break;
|
||||
case 'l':
|
||||
if (is_long)
|
||||
/* A double `l' is equivalent to an `L'. */
|
||||
is_longlong = 1;
|
||||
else
|
||||
/* int's are long int's. */
|
||||
is_long = 1;
|
||||
break;
|
||||
case 'L':
|
||||
/* double's are long double's, and int's are long long int's. */
|
||||
is_long_double = 1;
|
||||
break;
|
||||
case 'a':
|
||||
/* String conversions (%s, %[) take a `char **'
|
||||
arg and fill it in with a malloc'd pointer. */
|
||||
malloc_string = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* End of the format string? */
|
||||
if (*f == '\0')
|
||||
conv_error();
|
||||
|
||||
/* Find the conversion specifier. */
|
||||
w = work;
|
||||
fc = *f++;
|
||||
if (fc != '[' && fc != 'c' && fc != 'n')
|
||||
/* Eat whitespace. */
|
||||
while (isspace(c))
|
||||
(void) inchar();
|
||||
switch (fc)
|
||||
{
|
||||
case '%': /* Must match a literal '%'. */
|
||||
if (c != fc)
|
||||
conv_error();
|
||||
break;
|
||||
|
||||
case 'n': /* Answer number of assignments done. */
|
||||
if (do_assign)
|
||||
*va_arg(arg, int *) = read_in;
|
||||
break;
|
||||
|
||||
case 'c': /* Match characters. */
|
||||
if (do_assign)
|
||||
{
|
||||
str = va_arg (arg, char *);
|
||||
if (str == NULL)
|
||||
conv_error ();
|
||||
}
|
||||
|
||||
if (c == EOF)
|
||||
input_error();
|
||||
|
||||
if (width == -1)
|
||||
width = 1;
|
||||
|
||||
if (do_assign)
|
||||
{
|
||||
do
|
||||
*str++ = c;
|
||||
while (inchar() != EOF && --width > 0);
|
||||
}
|
||||
else
|
||||
while (inchar() != EOF && width > 0)
|
||||
--width;
|
||||
|
||||
if (do_assign)
|
||||
++done;
|
||||
|
||||
break;
|
||||
|
||||
case 's': /* Read a string. */
|
||||
#define STRING_ARG \
|
||||
if (do_assign) \
|
||||
{ \
|
||||
if (malloc_string) \
|
||||
{ \
|
||||
/* The string is to be stored in a malloc'd buffer. */ \
|
||||
strptr = va_arg (arg, char **); \
|
||||
if (strptr == NULL) \
|
||||
conv_error (); \
|
||||
/* Allocate an initial buffer. */ \
|
||||
strsize = 100; \
|
||||
*strptr = str = malloc (strsize); \
|
||||
} \
|
||||
else \
|
||||
str = va_arg (arg, char *); \
|
||||
if (str == NULL) \
|
||||
conv_error (); \
|
||||
}
|
||||
STRING_ARG;
|
||||
|
||||
if (c == EOF)
|
||||
input_error ();
|
||||
|
||||
do
|
||||
{
|
||||
if (isspace (c))
|
||||
break;
|
||||
#define STRING_ADD_CHAR(c) \
|
||||
if (do_assign) \
|
||||
{ \
|
||||
*str++ = c; \
|
||||
if (malloc_string && str == *strptr + strsize) \
|
||||
{ \
|
||||
/* Enlarge the buffer. */ \
|
||||
str = realloc (*strptr, strsize * 2); \
|
||||
if (str == NULL) \
|
||||
{ \
|
||||
/* Can't allocate that much. Last-ditch effort. */\
|
||||
str = realloc (*strptr, strsize + 1); \
|
||||
if (str == NULL) \
|
||||
{ \
|
||||
/* We lose. Oh well. \
|
||||
Terminate the string and stop converting, \
|
||||
so at least we don't swallow any input. */ \
|
||||
(*strptr)[strsize] = '\0'; \
|
||||
++done; \
|
||||
conv_error (); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
*strptr = str; \
|
||||
str += strsize; \
|
||||
++strsize; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
*strptr = str; \
|
||||
str += strsize; \
|
||||
strsize *= 2; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
STRING_ADD_CHAR (c);
|
||||
} while (inchar () != EOF && (width <= 0 || --width > 0));
|
||||
|
||||
if (do_assign)
|
||||
{
|
||||
*str = '\0';
|
||||
++done;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'x': /* Hexadecimal integer. */
|
||||
case 'X': /* Ditto. */
|
||||
base = 16;
|
||||
number_signed = 0;
|
||||
goto number;
|
||||
|
||||
case 'o': /* Octal integer. */
|
||||
base = 8;
|
||||
number_signed = 0;
|
||||
goto number;
|
||||
|
||||
case 'u': /* Unsigned decimal integer. */
|
||||
base = 10;
|
||||
number_signed = 0;
|
||||
goto number;
|
||||
|
||||
case 'd': /* Signed decimal integer. */
|
||||
base = 10;
|
||||
number_signed = 1;
|
||||
goto number;
|
||||
|
||||
case 'i': /* Generic number. */
|
||||
base = 0;
|
||||
number_signed = 1;
|
||||
|
||||
number:
|
||||
if (c == EOF)
|
||||
input_error();
|
||||
|
||||
/* Check for a sign. */
|
||||
if (c == '-' || c == '+')
|
||||
{
|
||||
*w++ = c;
|
||||
if (width > 0)
|
||||
--width;
|
||||
(void) inchar();
|
||||
}
|
||||
|
||||
/* Look for a leading indication of base. */
|
||||
if (c == '0')
|
||||
{
|
||||
if (width > 0)
|
||||
--width;
|
||||
*w++ = '0';
|
||||
|
||||
(void) inchar();
|
||||
|
||||
if (tolower(c) == 'x')
|
||||
{
|
||||
if (base == 0)
|
||||
base = 16;
|
||||
if (base == 16)
|
||||
{
|
||||
if (width > 0)
|
||||
--width;
|
||||
(void) inchar();
|
||||
}
|
||||
}
|
||||
else if (base == 0)
|
||||
base = 8;
|
||||
}
|
||||
|
||||
if (base == 0)
|
||||
base = 10;
|
||||
|
||||
/* Read the number into WORK. */
|
||||
do
|
||||
{
|
||||
if (base == 16 ? !isxdigit(c) :
|
||||
(!isdigit(c) || c - '0' >= base))
|
||||
break;
|
||||
*w++ = c;
|
||||
if (width > 0)
|
||||
--width;
|
||||
} while (inchar() != EOF && width != 0);
|
||||
|
||||
if (w == work ||
|
||||
(w - work == 1 && (work[0] == '+' || work[0] == '-')))
|
||||
/* There was on number. */
|
||||
conv_error();
|
||||
|
||||
/* Convert the number. */
|
||||
*w = '\0';
|
||||
if (number_signed)
|
||||
num = strtol (work, &w, base);
|
||||
else
|
||||
#if HAVE_STRTOUL
|
||||
unum = strtoul (work, &w, base);
|
||||
#else
|
||||
unum = strtol (work, &w, base);
|
||||
#endif
|
||||
if (w == work)
|
||||
conv_error ();
|
||||
|
||||
if (do_assign)
|
||||
{
|
||||
if (! number_signed)
|
||||
{
|
||||
if (is_longlong)
|
||||
*va_arg (arg, unsigned LONGLONG int *) = unum;
|
||||
else if (is_long)
|
||||
*va_arg (arg, unsigned long int *) = unum;
|
||||
else if (is_short)
|
||||
*va_arg (arg, unsigned short int *)
|
||||
= (unsigned short int) unum;
|
||||
else
|
||||
*va_arg(arg, unsigned int *) = (unsigned int) unum;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_longlong)
|
||||
*va_arg(arg, LONGLONG int *) = num;
|
||||
else if (is_long)
|
||||
*va_arg(arg, long int *) = num;
|
||||
else if (is_short)
|
||||
*va_arg(arg, short int *) = (short int) num;
|
||||
else
|
||||
*va_arg(arg, int *) = (int) num;
|
||||
}
|
||||
++done;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e': /* Floating-point numbers. */
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'G':
|
||||
if (c == EOF)
|
||||
input_error();
|
||||
|
||||
/* Check for a sign. */
|
||||
if (c == '-' || c == '+')
|
||||
{
|
||||
*w++ = c;
|
||||
if (inchar() == EOF)
|
||||
/* EOF is only an input error before we read any chars. */
|
||||
conv_error();
|
||||
if (width > 0)
|
||||
--width;
|
||||
}
|
||||
|
||||
got_dot = got_e = 0;
|
||||
do
|
||||
{
|
||||
if (isdigit(c))
|
||||
*w++ = c;
|
||||
else if (got_e && w[-1] == 'e' && (c == '-' || c == '+'))
|
||||
*w++ = c;
|
||||
else if (!got_e && tolower(c) == 'e')
|
||||
{
|
||||
*w++ = 'e';
|
||||
got_e = got_dot = 1;
|
||||
}
|
||||
else if (c == decimal && !got_dot)
|
||||
{
|
||||
*w++ = c;
|
||||
got_dot = 1;
|
||||
}
|
||||
else
|
||||
break;
|
||||
if (width > 0)
|
||||
--width;
|
||||
} while (inchar() != EOF && width != 0);
|
||||
|
||||
if (w == work)
|
||||
conv_error();
|
||||
if (w[-1] == '-' || w[-1] == '+' || w[-1] == 'e')
|
||||
conv_error();
|
||||
|
||||
#ifndef MIB_HACKS
|
||||
/* Convert the number. */
|
||||
*w = '\0';
|
||||
fp_num = strtod(work, &w);
|
||||
if (w == work)
|
||||
conv_error();
|
||||
|
||||
if (do_assign)
|
||||
{
|
||||
if (is_long_double)
|
||||
*va_arg(arg, LONG_DOUBLE *) = fp_num;
|
||||
else if (is_long)
|
||||
*va_arg(arg, double *) = (double) fp_num;
|
||||
else
|
||||
*va_arg(arg, float *) = (float) fp_num;
|
||||
++done;
|
||||
}
|
||||
break;
|
||||
#endif /* MIB_HACKS */
|
||||
|
||||
case '[': /* Character class. */
|
||||
STRING_ARG;
|
||||
|
||||
if (c == EOF)
|
||||
input_error();
|
||||
|
||||
if (*f == '^')
|
||||
{
|
||||
++f;
|
||||
not_in = 1;
|
||||
}
|
||||
else
|
||||
not_in = 0;
|
||||
|
||||
while ((fc = *f++) != '\0' && fc != ']')
|
||||
{
|
||||
if (fc == '-' && *f != '\0' && *f != ']' &&
|
||||
w > work && w[-1] <= *f)
|
||||
/* Add all characters from the one before the '-'
|
||||
up to (but not including) the next format char. */
|
||||
for (fc = w[-1] + 1; fc < *f; ++fc)
|
||||
*w++ = fc;
|
||||
else
|
||||
/* Add the character to the list. */
|
||||
*w++ = fc;
|
||||
}
|
||||
if (fc == '\0')
|
||||
conv_error();
|
||||
|
||||
*w = '\0';
|
||||
unum = read_in;
|
||||
do
|
||||
{
|
||||
if ((strchr (work, c) == NULL) != not_in)
|
||||
break;
|
||||
STRING_ADD_CHAR (c);
|
||||
if (width > 0)
|
||||
--width;
|
||||
} while (inchar () != EOF && width != 0);
|
||||
if (read_in == unum)
|
||||
conv_error ();
|
||||
|
||||
if (do_assign)
|
||||
{
|
||||
*str = '\0';
|
||||
++done;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p': /* Generic pointer. */
|
||||
base = 16;
|
||||
/* A PTR must be the same size as a `long int'. */
|
||||
is_long = 1;
|
||||
goto number;
|
||||
}
|
||||
}
|
||||
|
||||
conv_error();
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/behavior.h>
|
||||
#include <Foundation/NSCoder.h>
|
||||
|
||||
@interface Foo : NSObject
|
||||
+ fooClass;
|
||||
- foo;
|
||||
- (void) encodeWithCoder: c;
|
||||
@end
|
||||
|
||||
@interface Foo2 : NSObject
|
||||
+ foo2Class;
|
||||
- foo2;
|
||||
@end
|
||||
|
||||
@interface Foo2Sub : Foo2
|
||||
+ foo2SubClass;
|
||||
- foo2Sub;
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
+ (void) initialize
|
||||
{
|
||||
class_add_behavior([Foo class], [Foo2Sub class]);
|
||||
}
|
||||
+ fooClass
|
||||
{
|
||||
printf("fooClass\n");
|
||||
return self;
|
||||
}
|
||||
- foo
|
||||
{
|
||||
printf("foo\n");
|
||||
return self;
|
||||
}
|
||||
- duplicate
|
||||
{
|
||||
printf("Foo duplicate\n");
|
||||
return self;
|
||||
}
|
||||
- (void) encodeWithCoder: c
|
||||
{
|
||||
(void) &c;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Foo2
|
||||
+ foo2Class
|
||||
{
|
||||
printf("foo2Class\n");
|
||||
return self;
|
||||
}
|
||||
- foo2
|
||||
{
|
||||
printf("foo2\n");
|
||||
return self;
|
||||
}
|
||||
- duplicate
|
||||
{
|
||||
printf("Foo2 duplicate\n");
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Foo2Sub
|
||||
+ foo2SubClass
|
||||
{
|
||||
printf("foo2SubClass\n");
|
||||
return self;
|
||||
}
|
||||
- foo2Sub
|
||||
{
|
||||
printf("foo2Sub\n");
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
int main()
|
||||
{
|
||||
id f = [Foo new];
|
||||
|
||||
[f encodeWithCoder:nil];
|
||||
behavior_set_debug(1);
|
||||
|
||||
[f foo2];
|
||||
[[f class] foo2Class];
|
||||
[f foo2Sub];
|
||||
[[f class] foo2SubClass];
|
||||
[f duplicate];
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
compile-command: "gcc beh.m -I.. -L.. -lobjects -lobjc -o beh"
|
||||
End:
|
||||
*/
|
|
@ -1,73 +0,0 @@
|
|||
#include <math.h>
|
||||
|
||||
#define FACTOR (1 << 30)
|
||||
/* #define FACTOR 1e8 */
|
||||
|
||||
int main()
|
||||
{
|
||||
int i1, i2, i3;
|
||||
unsigned u2, u3 = 0;
|
||||
volatile double d = 0.123456789;
|
||||
volatile double di;
|
||||
|
||||
#if 0
|
||||
printf ("%f %d\n", d, i);
|
||||
d = frexp (d, &i);
|
||||
printf ("%f %d\n", d, i);
|
||||
|
||||
d = ldexp (d, i);
|
||||
printf("%f\n", d);
|
||||
|
||||
#elif 1
|
||||
|
||||
i1 = i2 = i3 = 0;
|
||||
d = -0.123456789;
|
||||
printf ("encoded value = %.15g\n", d);
|
||||
d = frexp (d, &i1);
|
||||
printf ("%g %d %d %d\n", d, i1, i2, i3);
|
||||
d *= FACTOR;
|
||||
i2 = d;
|
||||
d -= i2;
|
||||
printf ("%g %d %d %d\n", d, i1, i2, i3);
|
||||
d *= FACTOR;
|
||||
i3 = d;
|
||||
d -= i3;
|
||||
printf ("%g %d %d %d\n", d, i1, i2, i3);
|
||||
|
||||
d = 0;
|
||||
d = i3;
|
||||
d /= FACTOR;
|
||||
d += i2;
|
||||
d /= FACTOR;
|
||||
d = ldexp (d, i1);
|
||||
printf ("decoded value = %.15g\n", d);
|
||||
|
||||
#else
|
||||
|
||||
d = 0.123456789;
|
||||
printf ("original value = %g\n", d);
|
||||
|
||||
d = frexp (d, &i1);
|
||||
d *= FACTOR;
|
||||
d = modf (d, &di);
|
||||
u2 = di;
|
||||
if (d != 0)
|
||||
{
|
||||
d *= FACTOR;
|
||||
d = modf (d, &di);
|
||||
u3 = di;
|
||||
}
|
||||
printf ("%d %u %u\n", i1, u2, u3);
|
||||
|
||||
d = 0;
|
||||
d = u3;
|
||||
d /= FACTOR;
|
||||
d += u2;
|
||||
d /= FACTOR;
|
||||
d = ldexp (d, i1);
|
||||
printf ("decoded value = %g\n", d);
|
||||
|
||||
#endif
|
||||
|
||||
exit (0);
|
||||
}
|
Loading…
Reference in a new issue