changed the compiler to allow a character literal within a byte array literal
This commit is contained in:
		| @ -3,11 +3,16 @@ | |||||||
| class Socket(Object) from 'sck' | class Socket(Object) from 'sck' | ||||||
| { | { | ||||||
| 	var handle := -1. | 	var handle := -1. | ||||||
|  | 	var insem, outsem. | ||||||
|  | 	var(#get,#set) inputAction, outputAction. | ||||||
|  |  | ||||||
| 	method(#primitive) open(domain, type, proto). | 	method(#primitive) open(domain, type, proto). | ||||||
| 	method(#primitive) _close. | 	method(#primitive) _close. | ||||||
| 	method(#primitive) connect(a,b,c). | 	method(#primitive) connect(a,b,c). | ||||||
| 	method(#primitive) endConnect: xxx. | 	method(#primitive) endConnect. | ||||||
|  |  | ||||||
|  | 	method(#primitive) readBytes: bytes. | ||||||
|  | 	method(#primitive) writeBytes: bytes. | ||||||
| } | } | ||||||
|  |  | ||||||
| (* TODO: generate these domain and type from the C header *) | (* TODO: generate these domain and type from the C header *) | ||||||
| @ -39,6 +44,19 @@ extend Socket | |||||||
| 		{ | 		{ | ||||||
| 			## this primitive method may return failure.  | 			## this primitive method may return failure.  | ||||||
| 			## but ignore it here. | 			## but ignore it here. | ||||||
|  | 			if (self.insem)  | ||||||
|  | 			{  | ||||||
|  | 				System unsignal: self.insem. | ||||||
|  | 				System removeAsyncSemaphore: self.insem. | ||||||
|  | 				self.insem := nil. | ||||||
|  | 			}. | ||||||
|  | 			if (self.outsem) | ||||||
|  | 			{ | ||||||
|  | 				System unsignal: self.outsem. | ||||||
|  | 				System removeAsyncSemaphore: self.outsem. | ||||||
|  | 				self.outsem := nil. | ||||||
|  | 			}. | ||||||
|  |  | ||||||
| 			self _close. | 			self _close. | ||||||
| 			self.handle := -1. | 			self.handle := -1. | ||||||
| 		} | 		} | ||||||
| @ -54,9 +72,13 @@ extend Socket | |||||||
| 		sa := [:sem |  | 		sa := [:sem |  | ||||||
| 			System unsignal: s1. | 			System unsignal: s1. | ||||||
| 			System unsignal: s2. | 			System unsignal: s2. | ||||||
|  | 'UNSIGNALLLING      ...........' dump. | ||||||
| 			System removeAsyncSemaphore: s1. | 			System removeAsyncSemaphore: s1. | ||||||
| 			System removeAsyncSemaphore: s2. | 			System removeAsyncSemaphore: s2. | ||||||
| 			connectBlock value: (sem == s1) |  | ||||||
|  | 'FINALIZING CONNECT' dump. | ||||||
|  | 			self endConnect. | ||||||
|  | 			connectBlock value: self value: (sem == s1) | ||||||
| 		]. | 		]. | ||||||
|  |  | ||||||
| 		s1 signalAction: sa. | 		s1 signalAction: sa. | ||||||
| @ -74,34 +96,51 @@ extend Socket | |||||||
| 		] | 		] | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	method asyncRead: readBlock | 	method watchInput | ||||||
| 	{ | 	{ | ||||||
| 		| s1 s2 |  | 		if (self.insem isNil) | ||||||
| 		s1 := Semaphore new. | 		{ | ||||||
| 		s2 := Semaphore new. | 			self.insem := Semaphore new. | ||||||
|  | 			self.insem signalAction: [:sem | self.inputAction value: self value: true]. | ||||||
|  | 			System signal: self.insem onInput: self.handle. | ||||||
|  | 			System addAsyncSemaphore: self.insem. | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			self.insem signalAction: [:sem | self.inputAction value: self value: true]. | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		s1 signalAction: [:sem | readBlock value: true]. | 		###s2 := Semaphore new. | ||||||
| 		s2 signalAction: [:sem | readBlock value: false]. | 		###s2 signalAction: [:sem | inputActionBlock value: self value: false]. | ||||||
|  | 		###System signal: s2 afterSecs: 10. | ||||||
| 		System signal: s1 onInput: self.handle. |  | ||||||
| 		System signal: s2 afterSecs: 10. |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| (* | 	method unwatchInput | ||||||
| 	method asyncWrite:  |  | ||||||
| 	{ | 	{ | ||||||
| 		| s1 s2 |  | 		System unsignal: self.insem. | ||||||
| 		s1 := Semaphore new. | 		System removeAsyncSemaphore: self.insem. | ||||||
| 		s2 := Semaphore new. |  | ||||||
|  |  | ||||||
| 		s1 signalAction: [:sem | writeBlock value: true]. |  | ||||||
| 		s2 signalAction: [:sem | writeBlock value: false]. |  | ||||||
|  |  | ||||||
| 		System signal: s1 onOutput: self.handle. |  | ||||||
| 		System signal: s2 afterSecs: 10. |  | ||||||
| 	} | 	} | ||||||
| *) |  | ||||||
|  |  | ||||||
|  | 	method watchOutput | ||||||
|  | 	{ | ||||||
|  | 		if (self.outsem isNil) | ||||||
|  | 		{ | ||||||
|  | 			self.outsem := Semaphore new. | ||||||
|  | 			self.outsem signalAction: [:sem | self.outputAction value: self value: true]. | ||||||
|  | 			System signal: self.outsem onOutput: self.handle. | ||||||
|  | 			System addAsyncSemaphore: self.outsem. | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			self.outsem signalAction: [:sem | self.outputAction value: self value: true]. | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method unwatchOutput | ||||||
|  | 	{ | ||||||
|  | 		System unsignal: self.outsem. | ||||||
|  | 		System removeAsyncSemaphore: self.outsem. | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -109,32 +148,60 @@ class MyObject(Object) | |||||||
| { | { | ||||||
| 	method(#class) main | 	method(#class) main | ||||||
| 	{ | 	{ | ||||||
| 		| s | | 		| s conact inact outact | | ||||||
|  |  | ||||||
|  | 		inact := [:sck :state | | ||||||
|  | 			| data n | | ||||||
|  |  | ||||||
|  | 			data := ByteArray new: 100. | ||||||
|  | 			n := sck readBytes: data. | ||||||
|  | 			if (n == 0) | ||||||
|  | 			{ | ||||||
|  | 				sck close. | ||||||
|  | 			}. | ||||||
|  | 			(n asString & ' bytes read') dump. | ||||||
|  | 			data dump. | ||||||
|  | 		]. | ||||||
|  |  | ||||||
|  | 		outact := [:sck :state | | ||||||
|  | 			if (state) | ||||||
|  | 			{ | ||||||
|  | 				sck writeBytes: #[ $h $e $l $l $o ]. | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 			} | ||||||
|  | 		]. | ||||||
|  |  | ||||||
|  | 		conact := [:sck :state | | ||||||
|  | 			 | ||||||
|  |  | ||||||
|  | 			if (state) | ||||||
|  | 			{ | ||||||
|  | 				'CONNECTED NOW.............' dump. | ||||||
|  | 				##s onOutputDo: outact. | ||||||
|  | 				s writeBytes: #[ $h $e $l $l $o ]. | ||||||
|  | 				s watchInput. | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				'UNABLE TO CONNECT............' dump. | ||||||
|  | 			} | ||||||
|  | 		]. | ||||||
|  |  | ||||||
|  | 		## ------------------------------------------------------ | ||||||
|  |  | ||||||
| 		[ | 		[ | ||||||
| 			s := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM. | 			s := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM. | ||||||
|  | 			s inputAction: inact; outputAction: outact. | ||||||
| 			s asyncConnect: [:result |  | 			s asyncConnect: conact. | ||||||
| 				##s endConnect: result. |  | ||||||
| 				##s beginRead: xxx. |  | ||||||
| 				if (result) |  | ||||||
| 				{ |  | ||||||
| 					s endConnect: result. |  | ||||||
| 					'CONNECTED NOW.............' dump. |  | ||||||
| 					s asyncRead: [:data | |  | ||||||
| 						data dump. |  | ||||||
| 					] |  | ||||||
| 				} |  | ||||||
| 				else |  | ||||||
| 				{ |  | ||||||
| 					'UNABLE TO CONNECT............' dump. |  | ||||||
| 				} |  | ||||||
| 			]. |  | ||||||
|  |  | ||||||
| 			while (true) | 			while (true) | ||||||
| 			{ | 			{ | ||||||
| 				System handleAsyncEvent. | 				System handleAsyncEvent. | ||||||
| 			}. | 			}. | ||||||
| 			s close dump. | 			s close dump. | ||||||
|  |  | ||||||
| 		] on: Exception do: [:ex | ('Exception - '  & ex messageText) dump ]. | 		] on: Exception do: [:ex | ('Exception - '  & ex messageText) dump ]. | ||||||
|  |  | ||||||
| 		'----- END OF MAIN ------' dump. | 		'----- END OF MAIN ------' dump. | ||||||
|  | |||||||
| @ -4555,11 +4555,16 @@ static int read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) | |||||||
|  |  | ||||||
| 	GET_TOKEN_GOTO (moo, oops); /* skip #[ and read the next token */ | 	GET_TOKEN_GOTO (moo, oops); /* skip #[ and read the next token */ | ||||||
|  |  | ||||||
| 	while (TOKEN_TYPE(moo) == MOO_IOTOK_NUMLIT || TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT) | 	while (TOKEN_TYPE(moo) == MOO_IOTOK_NUMLIT || TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT || TOKEN_TYPE(moo) == MOO_IOTOK_CHARLIT) | ||||||
| 	{ | 	{ | ||||||
| 		/* TODO: check if the number is an integer */ | 		/* TODO: check if the number is an integer */ | ||||||
|  |  | ||||||
| 		if (string_to_smooi(moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT, &tmp) <= -1) | 		if (TOKEN_TYPE(moo) == MOO_IOTOK_CHARLIT) | ||||||
|  | 		{ | ||||||
|  | 			/* accept a character literal inside a byte array literal */ | ||||||
|  | 			tmp = TOKEN_NAME_PTR(moo)[0]; | ||||||
|  | 		} | ||||||
|  | 		else if (string_to_smooi(moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT, &tmp) <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			/* the token reader reads a valid token. no other errors | 			/* the token reader reads a valid token. no other errors | ||||||
| 			 * than the range error must not occur */ | 			 * than the range error must not occur */ | ||||||
| @ -4570,7 +4575,8 @@ static int read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) | |||||||
| 			set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo)); | 			set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo)); | ||||||
| 			goto oops; | 			goto oops; | ||||||
| 		} | 		} | ||||||
| 		else if (tmp < 0 || tmp > 255) |  | ||||||
|  | 		if (tmp < 0 || tmp > 255) | ||||||
| 		{ | 		{ | ||||||
| 			set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo)); | 			set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo)); | ||||||
| 			goto oops; | 			goto oops; | ||||||
|  | |||||||
| @ -1666,7 +1666,6 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c | |||||||
| 				if (revents & XPOLLERR) mask |= MOO_SEMAPHORE_IO_MASK_ERROR; | 				if (revents & XPOLLERR) mask |= MOO_SEMAPHORE_IO_MASK_ERROR; | ||||||
| 				if (revents & XPOLLHUP) mask |= MOO_SEMAPHORE_IO_MASK_HANGUP; | 				if (revents & XPOLLHUP) mask |= MOO_SEMAPHORE_IO_MASK_HANGUP; | ||||||
|  |  | ||||||
| printf ("먹스 마스크  %d\n", (int)mask); |  | ||||||
| 			#if defined(USE_DEVPOLL) | 			#if defined(USE_DEVPOLL) | ||||||
| 				MOO_ASSERT (moo, xtn->epd.capa > xtn->ev.buf[n].fd); | 				MOO_ASSERT (moo, xtn->epd.capa > xtn->ev.buf[n].fd); | ||||||
| 				muxwcb (moo, mask, (void*)xtn->epd.ptr[xtn->ev.buf[n].fd]); | 				muxwcb (moo, mask, (void*)xtn->epd.ptr[xtn->ev.buf[n].fd]); | ||||||
|  | |||||||
| @ -133,7 +133,7 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs) | |||||||
| struct sockaddr_in sin; | struct sockaddr_in sin; | ||||||
| memset (&sin, 0, sizeof(sin)); | memset (&sin, 0, sizeof(sin)); | ||||||
| sin.sin_family = AF_INET; | sin.sin_family = AF_INET; | ||||||
| sin.sin_addr.s_addr = inet_addr ("1.234.53.142"); | sin.sin_addr.s_addr = inet_addr ("192.168.1.143"); | ||||||
| sin.sin_port = htons(12345); | sin.sin_port = htons(12345); | ||||||
| 	do | 	do | ||||||
| 	{ | 	{ | ||||||
| @ -196,11 +196,92 @@ static moo_pfrc_t pf_end_connect (moo_t* moo, moo_ooi_t nargs) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	MOO_STACK_SETRETTORCV (moo, nargs); | 	MOO_STACK_SETRETTORCV (moo, nargs); | ||||||
| 	return MOO_PF_SUCCESS; | 	return MOO_PF_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static moo_pfrc_t pf_read_socket (moo_t* moo, moo_ooi_t nargs) | ||||||
|  | { | ||||||
|  | 	oop_sck_t sck; | ||||||
|  | 	moo_oop_byte_t buf; | ||||||
|  | 	int fd; | ||||||
|  | 	ssize_t n; | ||||||
|  |  | ||||||
|  | 	sck = (oop_sck_t)MOO_STACK_GETRCV(moo, nargs); | ||||||
|  | 	MOO_PF_CHECK_RCV (moo,  | ||||||
|  | 		MOO_OOP_IS_POINTER(sck) &&  | ||||||
|  | 		MOO_OBJ_BYTESOF(sck) >= (MOO_SIZEOF(*sck) - MOO_SIZEOF(moo_obj_t)) && | ||||||
|  | 		MOO_OOP_IS_SMOOI(sck->handle) | ||||||
|  | 	); | ||||||
|  |  | ||||||
|  | 	fd = MOO_OOP_TO_SMOOI(sck->handle); | ||||||
|  | 	if (fd <= -1) | ||||||
|  | 	{ | ||||||
|  | 		moo_seterrbfmt (moo, MOO_EINVAL, "bad socket handle - %d\n", fd); | ||||||
|  | 		return MOO_PF_FAILURE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	buf = (moo_oop_byte_t)MOO_STACK_GETARG (moo, nargs, 0); | ||||||
|  | 	if (!MOO_OBJ_IS_BYTE_POINTER(buf)) | ||||||
|  | 	{ | ||||||
|  | 		moo_seterrbfmt (moo, MOO_EINVAL, "buffer not a byte array - %O\n", buf); | ||||||
|  | 		return MOO_PF_FAILURE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	n = recv (fd, MOO_OBJ_GET_BYTE_SLOT(buf), MOO_OBJ_GET_SIZE(buf), 0); | ||||||
|  | 	if (n <= -1 && errno != EWOULDBLOCK) | ||||||
|  | 	{ | ||||||
|  | 		moo_seterrwithsyserr (moo, errno); | ||||||
|  | 		return MOO_PF_FAILURE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(n)); | ||||||
|  |  | ||||||
|  | 	MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(n)); | ||||||
|  | 	return MOO_PF_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static moo_pfrc_t pf_write_socket (moo_t* moo, moo_ooi_t nargs) | ||||||
|  | { | ||||||
|  | 	oop_sck_t sck; | ||||||
|  | 	moo_oop_byte_t buf; | ||||||
|  | 	int fd; | ||||||
|  | 	ssize_t n; | ||||||
|  |  | ||||||
|  | 	sck = (oop_sck_t)MOO_STACK_GETRCV(moo, nargs); | ||||||
|  | 	MOO_PF_CHECK_RCV (moo,  | ||||||
|  | 		MOO_OOP_IS_POINTER(sck) &&  | ||||||
|  | 		MOO_OBJ_BYTESOF(sck) >= (MOO_SIZEOF(*sck) - MOO_SIZEOF(moo_obj_t)) && | ||||||
|  | 		MOO_OOP_IS_SMOOI(sck->handle) | ||||||
|  | 	); | ||||||
|  |  | ||||||
|  | 	fd = MOO_OOP_TO_SMOOI(sck->handle); | ||||||
|  | 	if (fd <= -1) | ||||||
|  | 	{ | ||||||
|  | 		moo_seterrbfmt (moo, MOO_EINVAL, "bad socket handle - %d\n", fd); | ||||||
|  | 		return MOO_PF_FAILURE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	buf = (moo_oop_byte_t)MOO_STACK_GETARG (moo, nargs, 0); | ||||||
|  | 	if (!MOO_OBJ_IS_BYTE_POINTER(buf)) | ||||||
|  | 	{ | ||||||
|  | 		moo_seterrbfmt (moo, MOO_EINVAL, "buffer not a byte array - %O\n", buf); | ||||||
|  | 		return MOO_PF_FAILURE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	n = send (fd, MOO_OBJ_GET_BYTE_SLOT(buf), MOO_OBJ_GET_SIZE(buf), 0); | ||||||
|  | 	if (n <= -1 && errno != EWOULDBLOCK) | ||||||
|  | 	{ | ||||||
|  | 		moo_seterrwithsyserr (moo, errno); | ||||||
|  | 		return MOO_PF_FAILURE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(n)); | ||||||
|  |  | ||||||
|  | 	MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(n)); | ||||||
|  | 	return MOO_PF_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* ------------------------------------------------------------------------ */ | /* ------------------------------------------------------------------------ */ | ||||||
|   |   | ||||||
| typedef struct fnctab_t fnctab_t; | typedef struct fnctab_t fnctab_t; | ||||||
| @ -221,8 +302,10 @@ static moo_pfinfo_t pfinfos[] = | |||||||
| { | { | ||||||
| 	{ I, { 'c','l','o','s','e','\0' },                          0, { pf_close_socket,    0, 0  }  }, | 	{ I, { 'c','l','o','s','e','\0' },                          0, { pf_close_socket,    0, 0  }  }, | ||||||
| 	{ I, { 'c','o','n','n','e','c','t','\0' },                  0, { pf_connect,         3, 3  }  }, | 	{ I, { 'c','o','n','n','e','c','t','\0' },                  0, { pf_connect,         3, 3  }  }, | ||||||
| 	{ I, { 'e','n','d','C','o','n','n','e','c','t',':','\0' },  0, { pf_end_connect,     1, 1  }  }, | 	{ I, { 'e','n','d','C','o','n','n','e','c','t','\0' },      0, { pf_end_connect,     0, 0  }  }, | ||||||
| 	{ I, { 'o','p','e','n','\0' },                              0, { pf_open_socket,     3, 3  }  }, | 	{ I, { 'o','p','e','n','\0' },                              0, { pf_open_socket,     3, 3  }  }, | ||||||
|  | 	{ I, { 'r','e','a','d','B','y','t','e','s',':','\0' },      0, { pf_read_socket,     1, 1  }  }, | ||||||
|  | 	{ I, { 'w','r','i','t','e','B','y','t','e','s',':','\0' },  0, { pf_write_socket,    1, 1  }  }, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* ------------------------------------------------------------------------ */ | /* ------------------------------------------------------------------------ */ | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user