예제 #1
0
파일: dev-file.c 프로젝트: Oldes/R3A110
*/	DEVICE_CMD Write_File(REBREQ *file)
/*
**	Bug?: update file->size value after write !?
**
***********************************************************************/
{
	if (!file->id) {
		file->error = -RFE_NO_HANDLE;
		return DR_ERROR;
	}

	if (GET_FLAG(file->modes, RFM_APPEND)) {
		CLR_FLAG(file->modes, RFM_APPEND);
		lseek(file->id, 0, SEEK_END);
	}

	if (file->modes & ((1 << RFM_SEEK) | (1 << RFM_RESEEK) | (1 << RFM_TRUNCATE))) {
		CLR_FLAG(file->modes, RFM_RESEEK);
		if (!Seek_File_64(file)) return DR_ERROR;
		if (GET_FLAG(file->modes, RFM_TRUNCATE))
			if (ftruncate(file->id, file->file.index)) return DR_ERROR;
	}

	if (file->length == 0) return DR_DONE;

	file->actual = write(file->id, file->data, file->length);
	if (file->actual < 0) {
		if (errno == ENOSPC) file->error = -RFE_DISK_FULL;
		else file->error = -RFE_BAD_WRITE;
		return DR_ERROR;
	}

	return DR_DONE;
}
예제 #2
0
static int emac_set_pauseparam(struct net_device *netdev,
			       struct ethtool_pauseparam *pause)
{
	struct emac_adapter *adpt = netdev_priv(netdev);
	struct emac_hw *hw = &adpt->hw;
	enum emac_fc_mode req_fc_mode;
	bool disable_fc_autoneg;
	int retval = 0;

	while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING))
		msleep(20); /* Reset might take few 10s of ms */

	req_fc_mode        = hw->req_fc_mode;
	disable_fc_autoneg = hw->disable_fc_autoneg;

	if (pause->autoneg != AUTONEG_ENABLE)
		disable_fc_autoneg = true;
	else
		disable_fc_autoneg = false;

	if (pause->rx_pause && pause->tx_pause)
		req_fc_mode = emac_fc_full;
	else if (pause->rx_pause && !pause->tx_pause)
		req_fc_mode = emac_fc_rx_pause;
	else if (!pause->rx_pause && pause->tx_pause)
		req_fc_mode = emac_fc_tx_pause;
	else if (!pause->rx_pause && !pause->tx_pause)
		req_fc_mode = emac_fc_none;
	else {
		CLR_FLAG(adpt, ADPT_STATE_RESETTING);
		return -EINVAL;
	}

	if ((hw->req_fc_mode != req_fc_mode) ||
	    (hw->disable_fc_autoneg != disable_fc_autoneg)) {
		hw->req_fc_mode = req_fc_mode;
		hw->disable_fc_autoneg = disable_fc_autoneg;
		if (!adpt->no_ephy)
			retval = emac_setup_phy_link(hw,
						     hw->autoneg_advertised,
						     hw->autoneg,
						     !disable_fc_autoneg);
		if (!retval)
			emac_hw_config_fc(hw);
	}

	CLR_FLAG(adpt, ADPT_STATE_RESETTING);
	return retval;
}
예제 #3
0
파일: host-device.c 프로젝트: 51weekend/r3
static int Poll_Default(REBDEV *dev)
{
	// The default polling function for devices.
	// Retries pending requests. Return TRUE if status changed.
	REBREQ **prior = &dev->pending;
	REBREQ *req;
	REBOOL change = FALSE;
	int result;

	for (req = *prior; req; req = *prior) {

		// Call command again:
		if (req->command < RDC_MAX)
			result = dev->commands[req->command](req);
		else {
			result = -1;	// invalid command, remove it
			req->error = ((REBCNT)-1);
		}

		// If done or error, remove command from list:
		if (result <= 0) {
			*prior = req->next;
			req->next = 0;
			CLR_FLAG(req->flags, RRF_PENDING);
			change = TRUE;
		}
		else prior = &req->next;
	}

	return change;
}
예제 #4
0
파일: host-device.c 프로젝트: 51weekend/r3
*/	void Detach_Request(REBREQ **node, REBREQ *req)
/*
**		Detach a request to a device's pending or accept list.
**		If it is not in list, then no harm done.
**
***********************************************************************/
{
	REBREQ *r;

#ifdef special_debug
	if (req->device == 5)
		Debug_Fmt("Detach= n: %x r: %x p: %x %x", *node, req, req->port, &req->next);
#endif

	// See if its there, and get last req:
	for (r = *node; r; r = *node) {
#ifdef special_debug
	if (req->device == 5)
		Debug_Fmt("Detach: r: %x n: %x", r, r->next);
#endif
		if (r == req) {
			*node = req->next;
			req->next = 0;
			CLR_FLAG(req->flags, RRF_PENDING);
			return;
		}
		node = &r->next;
	}
}
예제 #5
0
파일: dev-file.c 프로젝트: Oldes/R3A110
*/	DEVICE_CMD Read_File(REBREQ *file)
/*
***********************************************************************/
{
	if (GET_FLAG(file->modes, RFM_DIR)) {
		return Read_Directory(file, (REBREQ*)file->data);
	}

	if (!file->id) {
		file->error = -RFE_NO_HANDLE;
		return DR_ERROR;
	}

	if (file->modes & ((1 << RFM_SEEK) | (1 << RFM_RESEEK))) {
		CLR_FLAG(file->modes, RFM_RESEEK);
		if (!Seek_File_64(file)) return DR_ERROR;
	}

	// printf("read %d len %d\n", file->id, file->length);
	file->actual = read(file->id, file->data, file->length);
	if (file->actual < 0) {
		file->error = -RFE_BAD_READ;
		return DR_ERROR;
	} else {
		file->file.index += file->actual;
	}

	return DR_DONE;
}
예제 #6
0
*/	DEVICE_CMD Read_Clipboard(REBREQ *req)
/*
***********************************************************************/
{
	REBYTE *data;

	//put the OS specific code here
	//=============================
	//
	//=============================

	req->actual = 0;

	if ((data) == NULL) {
		req->error = 30;
		return DR_ERROR;
	}

	//make sure "bytes mode" is set
	CLR_FLAG(req->flags, RRF_WIDE);

	req->data = data;
	req->actual = LEN_STR(data);

	return DR_DONE;
}
예제 #7
0
//
//  Quit_IO: C
//
DEVICE_CMD Quit_IO(REBREQ *dr)
{
    REBDEV *dev = (REBDEV*)dr; // just to keep compiler happy above

    Close_Stdio();

    CLR_FLAG(dev->flags, RDF_OPEN);
    return DR_DONE;
}
예제 #8
0
//
//  Close_IO: C
//
DEVICE_CMD Close_IO(REBREQ *req)
{
    REBDEV *dev = Devices[req->device];

    Close_Stdio();

    CLR_FLAG(dev->flags, RRF_OPEN);

    return DR_DONE;
}
예제 #9
0
파일: dev-stdio.c 프로젝트: earl/r3-hostkit
*/	DEVICE_CMD Quit_IO(REBREQ *dr)
/*
***********************************************************************/
{
    REBDEV *dev = (REBDEV*)dr; // just to keep compiler happy above

    //if (GET_FLAG(dev->flags, RDF_OPEN)) FreeConsole();
    CLR_FLAG(dev->flags, RDF_OPEN);
    return DR_DONE;
}
예제 #10
0
BOOL MYRTLEXP SetFileAttr( CONSTSTR fname,ATTR_TYPE v )
  {
#if defined(__GNUC__) || defined(__QNX__)
    CLR_FLAG( v,flDirectory );
#else
#if defined(__HDOS__)
    CLR_FLAG( v,FA_DIREC | FA_LABEL );
#else
#if defined(__HWIN16__)
    CLR_FLAG( v,FA_DIREC | FA_LABEL );
#else
#if defined(__HWIN32__)
    CLR_FLAG( v,FILE_ATTRIBUTE_DIRECTORY );
#else
  #error ERR_PLATFORM
#endif
#endif
#endif
#endif

#if defined(__GNUC__) || defined(__QNX__)
  return FIO_CHMOD(fname,v);
#else
#if defined(__REALDOS__)
  return _dos_setfileattr(fname,v) == 0;
#else
#if defined(__PROTDOS__)
  return dos_setfileattr(fname,v) == 0;
#else
#if defined(__BCWIN16__)
  return _dos_setfileattr(fname,v) == 0;
#else
#if defined(__HWIN32__)
  return SetFileAttributes(fname,v) != 0;
#else
  #error ERR_PLATFORM
#endif
#endif
#endif
#endif
#endif
}
예제 #11
0
파일: p-file.c 프로젝트: mbk/ren-c
*/	static void Cleanup_File(REBREQ *file)
/*
***********************************************************************/
{
	if (GET_FLAG(file->modes, RFM_NAME_MEM)) {
		//NOTE: file->special.file.path will get GC'd
		file->special.file.path = 0;
		CLR_FLAG(file->modes, RFM_NAME_MEM);
	}
	SET_CLOSED(file);
}
예제 #12
0
파일: dev-stdio.c 프로젝트: MannyZhong/r3
*/	DEVICE_CMD Close_IO(REBREQ *req)
/*
 ***********************************************************************/
{
	REBDEV *dev = Devices[req->device];

	close_stdio();

	CLR_FLAG(req->flags, RRF_OPEN);

	return DR_DONE;
}
예제 #13
0
파일: dev-net.c 프로젝트: earl/r3-hostkit
*/	int Quit_Net(REBREQ *dr)
/*
**		Close and cleanup networking libraries and related interfaces.
**
***********************************************************************/
{
	REBDEV *dev = (REBDEV*)dr; // just to keep compiler happy
#ifdef TO_WIN32
	if (GET_FLAG(dev->flags, RDF_INIT)) WSACleanup();
#endif
	CLR_FLAG(dev->flags, RDF_INIT);
	return DR_DONE;
}
예제 #14
0
파일: dev-dns.c 프로젝트: angerangel/rebol3
*/	DEVICE_CMD Close_DNS(REBREQ *sock)
/*
**		Note: valid even if not open.
**
***********************************************************************/
{
	// Terminate a pending request:
#ifdef HAS_ASYNC_DNS
	if (GET_FLAG(sock->flags, RRF_PENDING)) {
		CLR_FLAG(sock->flags, RRF_PENDING);
		if (sock->handle) WSACancelAsyncRequest(sock->handle);
	}
#endif
	if (sock->net.host_info) OS_Free(sock->net.host_info);
	sock->net.host_info = 0;
	sock->handle = 0;
	SET_CLOSED(sock);
	return DR_DONE; // Removes it from device's pending list (if needed)
}
예제 #15
0
파일: dev-dns.c 프로젝트: angerangel/rebol3
*/	DEVICE_CMD Poll_DNS(REBREQ *dr)
/*
**		Check for completed DNS requests. These are marked with
**		RRF_DONE by the windows message event handler (dev-event.c).
**		Completed requests are removed from the pending queue and
**		event is signalled (for awake dispatch).
**
***********************************************************************/
{
	REBDEV *dev = (REBDEV*)dr;  // to keep compiler happy
	REBREQ **prior = &dev->pending;
	REBREQ *req;
	BOOL change = FALSE;
	HOSTENT *host;

	// Scan the pending request list:
	for (req = *prior; req; req = *prior) {

		// If done or error, remove command from list:
		if (GET_FLAG(req->flags, RRF_DONE)) { // req->error may be set
			*prior = req->next;
			req->next = 0;
			CLR_FLAG(req->flags, RRF_PENDING);

			if (!req->error) { // success!
				host = (HOSTENT*)req->net.host_info;
				if (GET_FLAG(req->modes, RST_REVERSE))
					req->data = host->h_name;
				else
					COPY_MEM((char*)&(req->net.remote_ip), (char *)(*host->h_addr_list), 4); //he->h_length);
				Signal_Device(req, EVT_READ);
			}
			else
				Signal_Device(req, EVT_ERROR);
			change = TRUE;
		}
		else prior = &req->next;
	}

	return change;
}
예제 #16
0
파일: dev-file.c 프로젝트: Oldes/R3A110
static int Get_File_Info(REBREQ *file)
{
	struct stat info;

	if (stat(file->file.path, &info)) {
		file->error = errno;
		return DR_ERROR;
	}

	if (S_ISDIR(info.st_mode)) {
		SET_FLAG(file->modes, RFM_DIR);
		file->file.size = 0; // in order to be consistent on all systems
	}
	else {
		CLR_FLAG(file->modes, RFM_DIR);
		file->file.size = info.st_size;
	}
	file->file.time.l = (long)(info.st_mtime);

	return DR_DONE;
}
예제 #17
0
파일: dev-stdio.c 프로젝트: earl/r3-hostkit
*/	DEVICE_CMD Close_IO(REBREQ *req)
/*
 ***********************************************************************/
{
    REBDEV *dev = Devices[req->device];

    if (GET_FLAG(dev->flags, RDF_OPEN)) {
        OS_Free(Std_Buf);
        Std_Buf = 0;
        //FreeConsole();  // problem: causes a delay
    }

    if (Std_Echo) {
        CloseHandle(Std_Echo);
        Std_Echo = 0;
    }

    CLR_FLAG(req->flags, RRF_OPEN);
    //CLR_FLAG(dev->flags, RDF_OPEN);

    return DR_DONE;
}
예제 #18
0
*/	static int Event_Actor(REBVAL *ds, REBSER *port, REBCNT action)
/*
***********************************************************************/
{
	REBVAL *spec;
	REBVAL *state;
	REBCNT result;
	REBVAL *arg;
	REBVAL save_port;

	Validate_Port(port, action);

	arg = D_ARG(2);
	*D_RET = *D_ARG(1);

	// Validate and fetch relevant PORT fields:
	state = BLK_SKIP(port, STD_PORT_STATE);
	spec  = BLK_SKIP(port, STD_PORT_SPEC);
	if (!IS_OBJECT(spec)) Trap1(RE_INVALID_SPEC, spec);

	// Get or setup internal state data:
	if (!IS_BLOCK(state)) Set_Block(state, Make_Block(127));

	switch (action) {

	case A_UPDATE:
		return R_NONE;

	// Normal block actions done on events:
	case A_POKE:
		if (!IS_EVENT(D_ARG(3))) Trap_Arg(D_ARG(3));
		goto act_blk;
	case A_INSERT:
	case A_APPEND:
	//case A_PATH:		// not allowed: port/foo is port object field access
	//case A_PATH_SET:	// not allowed: above
		if (!IS_EVENT(arg)) Trap_Arg(arg);
	case A_PICK:
act_blk:
		save_port = *D_ARG(1); // save for return
		*D_ARG(1) = *state;
		result = T_Block(ds, action);
		SET_FLAG(Eval_Signals, SIG_EVENT_PORT);
		if (action == A_INSERT || action == A_APPEND || action == A_REMOVE) {
			*D_RET = save_port;
			break;
		}
		return result; // return condition

	case A_CLEAR:
		VAL_TAIL(state) = 0;
		VAL_BLK_TERM(state);
		CLR_FLAG(Eval_Signals, SIG_EVENT_PORT);
		break;

	case A_LENGTHQ:
		SET_INTEGER(D_RET, VAL_TAIL(state));
		break;

	case A_OPEN:
		if (!req) { //!!!
			req = OS_MAKE_DEVREQ(RDI_EVENT);
			SET_OPEN(req);
			OS_DO_DEVICE(req, RDC_CONNECT);		// stays queued
		}
		break;

	default:
		Trap_Action(REB_PORT, action);
	}

	return R_RET;
}
예제 #19
0
파일: dev-file.c 프로젝트: Oldes/R3A110
*/	static int Read_Directory(REBREQ *dir, REBREQ *file)
/*
**		This function will read a file directory, one file entry
**		at a time, then close when no more files are found.
**
**	Procedure:
**
**		This function is passed directory and file arguments.
**		The dir arg provides information about the directory to read.
**		The file arg is used to return specific file information.
**
**		To begin, this function is called with a dir->handle that
**		is set to zero and a dir->file.path string for the directory.
**
**		The directory is opened and a handle is stored in the dir
**		structure for use on subsequent calls. If an error occurred,
**		dir->error is set to the error code and -1 is returned.
**		The dir->size field can be set to the number of files in the
**		dir, if it is known. The dir->file.index field can be used by this
**		function to store information between calls.
**
**		If the open succeeded, then information about the first file
**		is stored in the file argument and the function returns 0.
**		On an error, the dir->error is set, the dir is closed,
**		dir->handle is nulled, and -1 is returned.
**
**		The caller loops until all files have been obtained. This
**		action should be uninterrupted. (The caller should not perform
**		additional OS or IO operations between calls.)
**
**		When no more files are found, the dir is closed, dir->handle
**		is nulled, and 1 is returned. No file info is returned.
**		(That is, this function is called one extra time. This helps
**		for OSes that may deallocate file strings on dir close.)
**
**		Note that the dir->file.path can contain wildcards * and ?. The
**		processing of these can be done in the OS (if supported) or
**		by a separate filter operation during the read.
**
**		Store file date info in file->file.index or other fields?
**		Store permissions? Ownership? Groups? Or, require that
**		to be part of a separate request?
**
***********************************************************************/
{
	struct stat info;
	struct dirent *d;
	char *cp;
	DIR *h;
	int n;

	// Remove * from tail, if present. (Allowed because the
	// path was copied into to-local-path first).
	n = strlen(cp = dir->file.path);
	if (n > 0 && cp[n-1] == '*') cp[n-1] = 0;

	// If no dir handle, open the dir:
	if (!(h = dir->handle)) {
		h = opendir(dir->file.path);
		if (!h) {
			dir->error = errno;
			return DR_ERROR;
		}
		dir->handle = h;
		CLR_FLAG(dir->flags, RRF_DONE);
	}

	// Get dir entry (skip over the . and .. dir cases):
	do {
		// Read next file entry or error:
		if (!(d = readdir(h))) {
			//dir->error = errno;
			closedir(h);
			dir->handle = 0;
			//if (dir->error) return DR_ERROR;
			SET_FLAG(dir->flags, RRF_DONE); // no more files
			return DR_DONE;
		}
		cp = d->d_name;
	} while (cp[0] == '.' && (cp[1] == 0 || cp[1] == '.'));

	file->modes = 0;
	COPY_BYTES(file->file.path, cp, MAX_FILE_NAME);

	// NOTE: not all posix filesystems support this (mainly
	// the Linux and BSD support it.) If this fails to build, a
	// different mechanism must be used. However, this is the
	// most efficient, because it does not require a separate
	// file system call for determining directories.
	if (d->d_type == DT_DIR) SET_FLAG(file->modes, RFM_DIR);

	// Line below DOES NOT WORK -- because we need full path.
	//Get_File_Info(file); // updates modes, size, time

	return DR_DONE;
}
예제 #20
0
파일: s-mold.c 프로젝트: dailybarid/rebol
STOID Mold_Block(REBVAL *value, REB_MOLD *mold)
{
	REBYTE *sep;
	REBOOL all = GET_MOPT(mold, MOPT_MOLD_ALL);
	REBSER *series = mold->series;
	REBFLG over = FALSE;

	if (SERIES_WIDE(VAL_SERIES(value)) == 0)
		Crash(RP_BAD_WIDTH, sizeof(REBVAL), 0, VAL_TYPE(value));

	// Optimize when no index needed:
	if (VAL_INDEX(value) == 0 && !IS_MAP(value)) // && (VAL_TYPE(value) <= REB_LIT_PATH))
		all = FALSE;

	// If out of range, do not cause error to avoid error looping.
	if (VAL_INDEX(value) >= VAL_TAIL(value)) over = TRUE; // Force it into []

	if (all || (over && !IS_BLOCK(value) && !IS_PAREN(value))) {
		SET_FLAG(mold->opts, MOPT_MOLD_ALL);
		Pre_Mold(value, mold); // #[block! part
		//if (over) Append_Bytes(mold->series, "[]");
		//else
		Mold_Block_Series(mold, VAL_SERIES(value), 0, 0);
		Post_Mold(value, mold);
	}
	else
	{
		switch(VAL_TYPE(value)) {

		case REB_MAP:
			Pre_Mold(value, mold);
			sep = 0;

		case REB_BLOCK:
			if (GET_MOPT(mold, MOPT_ONLY)) {
				CLR_FLAG(mold->opts, MOPT_ONLY); // only top level
				sep = "\000\000";
			}
			else sep = 0;
			break;

		case REB_PAREN:
			sep = "()";
			break;

		case REB_GET_PATH:
			series = Append_Byte(series, ':');
			sep = "/";
			break;

		case REB_LIT_PATH:
			series = Append_Byte(series, '\'');
			/* fall through */
		case REB_PATH:
		case REB_SET_PATH:
			sep = "/";
			break;
		}

		if (over) Append_Bytes(mold->series, sep ? sep : (REBYTE*)("[]"));
		else Mold_Block_Series(mold, VAL_SERIES(value), VAL_INDEX(value), sep);

		if (VAL_TYPE(value) == REB_SET_PATH)
			Append_Byte(series, ':');
	}
}
예제 #21
0
/* Main table driver                                                      */
static void  percent( char type, char subtype )
{
  DWORD vofs;
  int   extend = (addrsize == 32) ? 4 : 2;
  BYTE  c;

  switch (type) {
  case 'A':                          /* direct address */
       SET_FLAG( Info->CurrentFlags,DISASM_FL_CODE );
       outhex(subtype, extend, 0, addrsize, 0);
       CLR_FLAG( Info->CurrentFlags,DISASM_FL_CODE );
       break;

  case 'C':                          /* reg(r/m) picks control reg */
       uprintf("C%d", REG(modrm()));
       must_do_size = 0;
       break;

  case 'D':                          /* reg(r/m) picks debug reg */
       uprintf("D%d", REG(modrm()));
       must_do_size = 0;
       break;

  case 'E':                          /* r/m picks operand */
       do_modrm(subtype);
       break;

  case 'G':                          /* reg(r/m) picks register */
       if (subtype == 'F')                 /* 80*87 operand?   */
         reg_name(RM(modrm()), subtype);
       else
         reg_name(REG(modrm()), subtype);
       must_do_size = 0;
       break;

  case 'I':                            /* immed data */
       SET_FLAG( Info->CurrentFlags,DISASM_FL_DATA );
       outhex(subtype, 0, 0, opsize, 0);
       CLR_FLAG( Info->CurrentFlags,DISASM_FL_DATA );
       break;

  case 'J':                            /* relative IP offset */
       vofs = 0;
       switch(bytes(subtype)) {              /* sizeof offset value */
         case 1:
              vofs = (DWORD)getbyte();
            break;
         case 2:
              vofs  = (DWORD)getbyte();
              vofs |= (DWORD)getbyte() << 8;
              vofs &= 0xFFFFu;
            break;
         case 4:
              vofs  = (DWORD)getbyte();           /* yuk! */
              vofs |= (DWORD)getbyte() << 8;
              vofs |= (DWORD)getbyte() << 16;
              vofs |= (DWORD)getbyte() << 24;
            break;
       }
       SET_FLAG( Info->CurrentFlags,DISASM_FL_CODE|DISASM_FL_OFFSET );
       uprintf("%s", addr_to_hex(vofs + Info->instruction_length,1,bytes(subtype)) );
       CLR_FLAG( Info->CurrentFlags,DISASM_FL_CODE|DISASM_FL_OFFSET );
       break;

  case 'K': if (do_distance==0)
              break;
            switch (subtype) {
              case 'f': uprintf( Info->GetStringName(DISASM_ID_FAR) );   uputchar(' '); break;
              case 'n': uprintf( Info->GetStringName(DISASM_ID_NEAR) );  uputchar(' '); break;
              case 's': uprintf( Info->GetStringName(DISASM_ID_SHORT) ); uputchar(' '); break;
            }
       break;

  case 'M':                            /* r/m picks memory */
       do_modrm(subtype);
       break;

  case 'O':                            /* offset only */
       ua_str("%p:[");
       SET_FLAG( Info->CurrentFlags,DISASM_FL_REF );
       outhex(subtype, extend, 0, addrsize, 0);
       CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF );
       uputchar(']');
       break;

  case 'P':                            /* prefix byte (rh) */
       ua_str("%p:");
       break;

  case 'R':                            /* mod(r/m) picks register */
       reg_name(REG(modrm()), subtype);      /* rh */
       must_do_size = 0;
       break;

  case 'S':                            /* reg(r/m) picks segment reg */
       uputchar("ecsdfg"[REG(modrm())]);
       uputchar('s');
       must_do_size = 0;
       break;

  case 'T':                            /* reg(r/m) picks T reg */
       uprintf("tr%d", REG(modrm()));
       must_do_size = 0;
       break;

  case 'X':                            /* ds:si type operator */
       uprintf("ds:[");
       if (addrsize == 32)
         uputchar('e');
       uprintf("si]");
       break;

  case 'Y':                            /* es:di type operator */
       uprintf("es:[");
       if (addrsize == 32)
         uputchar('e');
       uprintf("di]");
       break;

  case '2':                            /* old [pop cs]! now indexes */
       ua_str(second[getbyte()]);      /* instructions in 386/486   */
       break;

  case 'g':                            /* modrm group `subtype' (0--7) */
       ua_str( GetOPGroup(subtype) );
       break;

  case 'd':                             /* sizeof operand==dword? */
       if (opsize == 32)
         uputchar('d');
       uputchar(subtype);
       break;

  case 'w':                             /* insert explicit size specifier */
       if (opsize == 32)
         uputchar('d');
       else
         uputchar('w');
       uputchar(subtype);
       break;

  case 'e':                         /* extended reg name */
       if (opsize == 32) {
         if (subtype == 'w')
           uputchar('d');
         else {
           uputchar('e');
           uputchar(subtype);
         }
       } else
         uputchar(subtype);
       break;

  case 'f':                    /* '87 opcode */
       floating_point(subtype-'0');
       break;

  case 'j':
       if (addrsize==32 || opsize==32) /* both of them?! */
         uputchar('e');
       break;

  case 'p':                    /* prefix byte */
       switch (subtype)  {
       case 'c':
       case 'd':
       case 'e':
       case 'f':
       case 'g':
       case 's':
            prefix = subtype;
            c = getbyte();
            wordop = c & 1;
            ua_str( GetOP(c) );
            break;
       case ':':
            if (prefix)
              uprintf("%cs:", prefix);
            break;
       case ' ':
            c = getbyte();
            wordop = c & 1;
            ua_str( GetOP(c) );
            break;
       }
       break;

  case 's':                           /* size override */
       switch (subtype) {
       case 'a':
            addrsize = 48 - addrsize;
            c = getbyte();
            wordop = c & 1;
            ua_str( GetOP(c) );
            break;
       case 'o':
            opsize = 48 - opsize;
            c = getbyte();
            wordop = c & 1;
            ua_str( GetOP(c) );
            break;
       }
       break;
   }
}
예제 #22
0
/*------------------------------------------------------------------------*/
static void  do_modrm(char subtype)
{
  int mod = MOD(modrm());
  int rm = RM(modrm());
  int extend = (addrsize == 32) ? 4 : 2;

/* specifies two registers */
  if (mod == 3) {
    reg_name(rm, subtype);
    return;
  }

  if (must_do_size) {
    if (wordop) {
      if (addrsize==32 || opsize==32)        /* then must specify size */
        uprintf( Info->GetStringName(DISASM_ID_DWORD_PTR) );
       else
        uprintf( Info->GetStringName(DISASM_ID_WORD_PTR) );
    } else
      uprintf( Info->GetStringName(DISASM_ID_BYTE_PTR) );

    uputchar(' ');
  }

/* mem operand with 32 bit ofs */
  if ((mod == 0) && (rm == 5) && (addrsize == 32)) {
    ua_str("%p:[");
    SET_FLAG( Info->CurrentFlags,DISASM_FL_REF );
    outhex('d', extend, 0, addrsize, 0);
    CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF );
    uputchar(']');
  } else
/* 16 bit dsplcmnt */
  if ((mod == 0) && (rm == 6) && (addrsize == 16)) {
    ua_str("%p:[");
    SET_FLAG( Info->CurrentFlags,DISASM_FL_REF );
    outhex('w', extend, 0, addrsize, 0);
    CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF );
    uputchar(']');
  } else {
/*All other*/
    if ( (addrsize != 32) || (rm != 4) )
      ua_str("%p:[");

    SET_FLAG( Info->CurrentFlags,DISASM_FL_REF | DISASM_FL_REFADD );

    if (addrsize == 16)
      switch (rm) {
        case 0: uprintf("bx+si"); break;
        case 1: uprintf("bx+di"); break;
        case 2: uprintf("bp+si"); break;
        case 3: uprintf("bp+di"); break;
        case 4: uprintf("si"); break;
        case 5: uprintf("di"); break;
        case 6: uprintf("bp"); break;
        case 7: uprintf("bx"); break;
      }
     else
      switch (rm) {
        case 0: uprintf("eax"); break;
        case 1: uprintf("ecx"); break;
        case 2: uprintf("edx"); break;
        case 3: uprintf("ebx"); break;
        case 4: do_sib(mod); break;
        case 5: uprintf("ebp"); break;
        case 6: uprintf("esi"); break;
        case 7: uprintf("edi"); break;
      }

    switch (mod) {
      case 1: outhex('b', extend, 1, addrsize, 0); break;
      case 2: outhex('v', extend, 1, addrsize, 1); break;
    }

    CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF | DISASM_FL_REFADD );
    uputchar(']');
  }
}
예제 #23
0
파일: dev-net.c 프로젝트: earl/r3-hostkit
*/	DEVICE_CMD Connect_Socket(REBREQ *sock)
/*
**		Connect a socket to a service.
**		Only required for connection-based protocols (e.g. not UDP).
**		The IP address must already be resolved before calling.
**
**		This function is asynchronous. It will return immediately.
**		You can call this function again to check the pending connection.
**
**		The function will return:
**			=0: connection succeeded (or already is connected)
**			>0: in-progress, still trying
**		    <0: error occurred, no longer trying
**
**		Before usage:
**			Open_Socket() -- to allocate the socket
**
***********************************************************************/
{
	int result;
	SOCKAI sa;

	if (GET_FLAG(sock->modes, RST_LISTEN))
		return Listen_Socket(sock);

	if (GET_FLAG(sock->state, RSM_CONNECT)) return DR_DONE; // already connected

	Set_Addr(&sa, sock->net.remote_ip, sock->net.remote_port);
	result = connect(sock->socket, (struct sockaddr *)&sa, sizeof(sa));

	if (result != 0) result = GET_ERROR;

	WATCH2("connect() error: %d - %s\n", result, strerror(result));

	switch (result) {

	case 0: // no error
	case NE_ISCONN:
		// Connected, set state:
		CLR_FLAG(sock->state, RSM_ATTEMPT);
		SET_FLAG(sock->state, RSM_CONNECT);
		Get_Local_IP(sock);
		Signal_Device(sock, EVT_CONNECT);
		return DR_DONE; // done

#ifdef TO_WIN32
	case NE_INVALID:	// Corrects for Microsoft bug
#endif
	case NE_WOULDBLOCK:
	case NE_INPROGRESS:
	case NE_ALREADY:
		// Still trying:
		SET_FLAG(sock->state, RSM_ATTEMPT);
		return DR_PEND;

	default:
		// An error happened:
		CLR_FLAG(sock->state, RSM_ATTEMPT);
		sock->error = result;
		//Signal_Device(sock, EVT_ERROR);
		return DR_ERROR;
	}
}
예제 #24
0
파일: fstd_ilist.cpp 프로젝트: elfmz/far2l
void FP_ItemList::Copy(PluginPanelItem *dest,const PluginPanelItem *src,int cn)
{
	if(!cn) return;

	memmove(dest, src, sizeof(*dest)*cn);

	for(; cn; cn--,src++,dest++)
	{
		//User data
		if(IS_FLAG(src->Flags,PPIF_USERDATA))
		{
			DWORD sz = (src->UserData && !IsBadReadPtr((void*)src->UserData,sizeof(DWORD)))
			           ? (*((DWORD*)src->UserData))
			           : 0;

			if(sz && !IsBadReadPtr((void*)src->UserData,sz))
			{
				dest->UserData = (DWORD_PTR)malloc(sz+1);
				memmove((char*)dest->UserData,(char*)src->UserData,sz);
			}
			else
			{
				dest->UserData = 0;
				CLR_FLAG(dest->Flags,PPIF_USERDATA);
			}
		}

		//CustomColumn
		if(src->CustomColumnNumber)
		{
			dest->CustomColumnData = (LPSTR*)malloc(sizeof(LPSTR*)*src->CustomColumnNumber);

			for(int n = 0; n < src->CustomColumnNumber; n++)
			{
				dest->CustomColumnData[n] = strdup(src->CustomColumnData[n]);
			}
		}

		//Description
		if(src->Description)
			dest->Description = strdup(src->Description);

		//Owner
		if(src->Owner)
			dest->Owner = strdup(src->Owner);

		//Additionals
		if(FPIL_ADDEXIST(src))
		{
			DWORD  sz  = FPIL_ADDSIZE(src);
			LPVOID ptr = malloc(sz);

			if(ptr)
			{
				memmove(ptr, FPIL_ADDDATA(src), sz);
				FPIL_ADDSET(dest, sz, ptr);
			}
			else
				FPIL_ADDSET(dest, 0, NULL);
		}
	}
}
예제 #25
0
//
//  Clipboard_Actor: C
//
static REB_R Clipboard_Actor(struct Reb_Call *call_, REBSER *port, REBCNT action)
{
    REBREQ *req;
    REBINT result;
    REBVAL *arg;
    REBCNT refs;    // refinement argument flags
    REBINT len;
    REBSER *ser;

    Validate_Port(port, action);

    arg = DS_ARGC > 1 ? D_ARG(2) : NULL;

    req = cast(REBREQ*, Use_Port_State(port, RDI_CLIPBOARD, sizeof(REBREQ)));

    switch (action) {
    case A_UPDATE:
        // Update the port object after a READ or WRITE operation.
        // This is normally called by the WAKE-UP function.
        arg = OFV(port, STD_PORT_DATA);
        if (req->command == RDC_READ) {
            // this could be executed twice:
            // once for an event READ, once for the CLOSE following the READ
            if (!req->common.data) return R_NONE;
            len = req->actual;
            if (GET_FLAG(req->flags, RRF_WIDE)) {
                // convert to UTF8, so that it can be converted back to string!
                Val_Init_Binary(arg, Make_UTF8_Binary(
                    req->common.data,
                    len / sizeof(REBUNI),
                    0,
                    OPT_ENC_UNISRC
                ));
            }
            else {
                REBSER *ser = Make_Binary(len);
                memcpy(BIN_HEAD(ser), req->common.data, len);
                SERIES_TAIL(ser) = len;
                Val_Init_Binary(arg, ser);
            }
            OS_FREE(req->common.data); // release the copy buffer
            req->common.data = 0;
        }
        else if (req->command == RDC_WRITE) {
            SET_NONE(arg);  // Write is done.
        }
        return R_NONE;

    case A_READ:
        // This device is opened on the READ:
        if (!IS_OPEN(req)) {
            if (OS_DO_DEVICE(req, RDC_OPEN))
                fail (Error_On_Port(RE_CANNOT_OPEN, port, req->error));
        }
        // Issue the read request:
        CLR_FLAG(req->flags, RRF_WIDE); // allow byte or wide chars
        result = OS_DO_DEVICE(req, RDC_READ);
        if (result < 0) fail (Error_On_Port(RE_READ_ERROR, port, req->error));
        if (result > 0) return R_NONE; /* pending */

        // Copy and set the string result:
        arg = OFV(port, STD_PORT_DATA);

        len = req->actual;
        if (GET_FLAG(req->flags, RRF_WIDE)) {
            // convert to UTF8, so that it can be converted back to string!
            Val_Init_Binary(arg, Make_UTF8_Binary(
                req->common.data,
                len / sizeof(REBUNI),
                0,
                OPT_ENC_UNISRC
            ));
        }
        else {
            REBSER *ser = Make_Binary(len);
            memcpy(BIN_HEAD(ser), req->common.data, len);
            SERIES_TAIL(ser) = len;
            Val_Init_Binary(arg, ser);
        }

        *D_OUT = *arg;
        return R_OUT;

    case A_WRITE:
        if (!IS_STRING(arg) && !IS_BINARY(arg))
            fail (Error(RE_INVALID_PORT_ARG, arg));
        // This device is opened on the WRITE:
        if (!IS_OPEN(req)) {
            if (OS_DO_DEVICE(req, RDC_OPEN))
                fail (Error_On_Port(RE_CANNOT_OPEN, port, req->error));
        }

        refs = Find_Refines(call_, ALL_WRITE_REFS);

        // Handle /part refinement:
        len = VAL_LEN(arg);
        if (refs & AM_WRITE_PART && VAL_INT32(D_ARG(ARG_WRITE_LIMIT)) < len)
            len = VAL_INT32(D_ARG(ARG_WRITE_LIMIT));

        // If bytes, see if we can fit it:
        if (SERIES_WIDE(VAL_SERIES(arg)) == 1) {
#ifdef ARG_STRINGS_ALLOWED
            if (!All_Bytes_ASCII(VAL_BIN_DATA(arg), len)) {
                Val_Init_String(
                    arg, Copy_Bytes_To_Unicode(VAL_BIN_DATA(arg), len)
                );
            } else
                req->common.data = VAL_BIN_DATA(arg);
#endif

            // Temp conversion:!!!
            ser = Make_Unicode(len);
            len = Decode_UTF8(UNI_HEAD(ser), VAL_BIN_DATA(arg), len, FALSE);
            SERIES_TAIL(ser) = len = abs(len);
            UNI_TERM(ser);
            Val_Init_String(arg, ser);
            req->common.data = cast(REBYTE*, UNI_HEAD(ser));
            SET_FLAG(req->flags, RRF_WIDE);
        }
        else
        // If unicode (may be from above conversion), handle it:
        if (SERIES_WIDE(VAL_SERIES(arg)) == sizeof(REBUNI)) {
            req->common.data = cast(REBYTE *, VAL_UNI_DATA(arg));
            SET_FLAG(req->flags, RRF_WIDE);
        }
예제 #26
0
static int emac_set_settings(struct net_device *netdev,
			     struct ethtool_cmd *ecmd)
{
	struct emac_adapter *adpt = netdev_priv(netdev);
	struct emac_hw *hw = &adpt->hw;
	u32 advertised, old;
	int retval = 0;
	bool autoneg;

	emac_info(adpt, link, "ethtool cmd autoneg %d, speed %d, duplex %d\n",
		  ecmd->autoneg, ecmd->speed, ecmd->duplex);

	while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING))
		msleep(20); /* Reset might take few 10s of ms */

	old = hw->autoneg_advertised;
	advertised = 0;
	if (ecmd->autoneg == AUTONEG_ENABLE) {
		advertised = EMAC_LINK_SPEED_DEFAULT;
		autoneg = true;
	} else {
		u32 speed = ecmd->speed;
		autoneg = false;
		if (speed == SPEED_1000) {
			if (ecmd->duplex != DUPLEX_FULL) {
				emac_warn(adpt, hw,
					  "1000M half is invalid\n");
				CLR_FLAG(adpt, ADPT_STATE_RESETTING);
				return -EINVAL;
			}
			advertised = EMAC_LINK_SPEED_1GB_FULL;
		} else if (speed == SPEED_100) {
			if (ecmd->duplex == DUPLEX_FULL)
				advertised = EMAC_LINK_SPEED_100_FULL;
			else
				advertised = EMAC_LINK_SPEED_100_HALF;
		} else {
			if (ecmd->duplex == DUPLEX_FULL)
				advertised = EMAC_LINK_SPEED_10_FULL;
			else
				advertised = EMAC_LINK_SPEED_10_HALF;
		}
	}

	if ((hw->autoneg == autoneg) && (hw->autoneg_advertised == advertised))
		goto done;

	retval = emac_setup_phy_link_speed(hw, advertised, autoneg,
					   !hw->disable_fc_autoneg);
	if (retval) {
		emac_setup_phy_link_speed(hw, old, autoneg,
					  !hw->disable_fc_autoneg);
	}

	if (netif_running(adpt->netdev)) {
		/* If there is no EPHY, the EMAC internal PHY may get reset in
		 * emac_setup_phy_link_speed. Reset the MAC to avoid the memory
		 * corruption.
		 */
		if (adpt->no_ephy) {
			emac_down(adpt, EMAC_HW_CTRL_RESET_MAC);
			emac_up(adpt);
		}
	}

done:
	CLR_FLAG(adpt, ADPT_STATE_RESETTING);
	return retval;
}
예제 #27
0
파일: t-gob.c 프로젝트: ectsoft/saphir
*/	static REBFLG Set_GOB_Var(REBGOB *gob, REBVAL *word, REBVAL *val)
/*
***********************************************************************/
{
	switch (VAL_WORD_CANON(word)) {
	case SYM_OFFSET:
		return Set_Pair(&(gob->offset), val);

	case SYM_SIZE:
		return Set_Pair(&gob->size, val);

	case SYM_IMAGE:
		CLR_GOB_OPAQUE(gob);
		if (IS_IMAGE(val)) {
			SET_GOB_TYPE(gob, GOBT_IMAGE);
			GOB_W(gob) = (REBD32)VAL_IMAGE_WIDE(val);
			GOB_H(gob) = (REBD32)VAL_IMAGE_HIGH(val);
			GOB_CONTENT(gob) = VAL_SERIES(val);
//			if (!VAL_IMAGE_TRANSP(val)) SET_GOB_OPAQUE(gob);
		}
		else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE);
		else return FALSE;
		break;

	case SYM_DRAW:
		CLR_GOB_OPAQUE(gob);
		if (IS_BLOCK(val)) {
			SET_GOB_TYPE(gob, GOBT_DRAW);
			GOB_CONTENT(gob) = VAL_SERIES(val);
		}
		else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE);
		else return FALSE;
		break;

	case SYM_TEXT:
		CLR_GOB_OPAQUE(gob);
		if (IS_BLOCK(val)) {
			SET_GOB_TYPE(gob, GOBT_TEXT);
			GOB_CONTENT(gob) = VAL_SERIES(val);
		}
		else if (IS_STRING(val)) {
			SET_GOB_TYPE(gob, GOBT_STRING);
			GOB_CONTENT(gob) = VAL_SERIES(val);
		}
		else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE);
		else return FALSE;
		break;

	case SYM_EFFECT:
		CLR_GOB_OPAQUE(gob);
		if (IS_BLOCK(val)) {
			SET_GOB_TYPE(gob, GOBT_EFFECT);
			GOB_CONTENT(gob) = VAL_SERIES(val);
		}
		else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE);
		else return FALSE;
		break;

	case SYM_COLOR:
		CLR_GOB_OPAQUE(gob);
		if (IS_TUPLE(val)) {
			SET_GOB_TYPE(gob, GOBT_COLOR);
			Set_Pixel_Tuple((REBYTE*)&GOB_CONTENT(gob), val);
			if (VAL_TUPLE_LEN(val) < 4 || VAL_TUPLE(val)[3] == 0)
				SET_GOB_OPAQUE(gob);
		}
		else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE);
		break;

	case SYM_PANE:
		if (GOB_PANE(gob)) Clear_Series(GOB_PANE(gob));
		if (IS_BLOCK(val))
			Insert_Gobs(gob, VAL_BLK_DATA(val), 0, VAL_BLK_LEN(val), 0);
		else if (IS_GOB(val))
			Insert_Gobs(gob, val, 0, 1, 0);
		else if (IS_NONE(val))
			gob->pane = 0;
		else
			return FALSE;
		break;

	case SYM_ALPHA:
		GOB_ALPHA(gob) = Clip_Int(Int32(val), 0, 255);
		break;

	case SYM_DATA:
		SET_GOB_DTYPE(gob, GOBD_NONE);
		if (IS_OBJECT(val)) {
			SET_GOB_DTYPE(gob, GOBD_OBJECT);
			SET_GOB_DATA(gob, VAL_OBJ_FRAME(val));
		}
		else if (IS_BLOCK(val)) {
			SET_GOB_DTYPE(gob, GOBD_BLOCK);
			SET_GOB_DATA(gob, VAL_SERIES(val));
		}
		else if (IS_STRING(val)) {
			SET_GOB_DTYPE(gob, GOBD_STRING);
			SET_GOB_DATA(gob, VAL_SERIES(val));
		}
		else if (IS_BINARY(val)) {
			SET_GOB_DTYPE(gob, GOBD_BINARY);
			SET_GOB_DATA(gob, VAL_SERIES(val));
		}
		else if (IS_INTEGER(val)) {
			SET_GOB_DTYPE(gob, GOBD_INTEGER);
			SET_GOB_DATA(gob, (void*)VAL_INT32(val));
		}
		else if (IS_NONE(val))
			SET_GOB_TYPE(gob, GOBT_NONE);
		else return FALSE;
		break;

	case SYM_FLAGS:
		if (IS_WORD(val)) Set_Gob_Flag(gob, val);
		else if (IS_BLOCK(val)) {
			REBINT i;		
			//clear only flags defined by words
			for (i = 0; Gob_Flag_Words[i]; i += 2)
				CLR_FLAG(gob->flags, Gob_Flag_Words[i+1]);
			
			for (val = VAL_BLK(val); NOT_END(val); val++)
				if (IS_WORD(val)) Set_Gob_Flag(gob, val);
		}
		break;

	case SYM_OWNER:
		if (IS_GOB(val))
			GOB_TMP_OWNER(gob) = VAL_GOB(val);
		else
			return FALSE;
		break;

	default:
			return FALSE;
	}
	return TRUE;
}
예제 #28
0
파일: dev-net.c 프로젝트: earl/r3-hostkit
*/	DEVICE_CMD Transfer_Socket(REBREQ *sock)
/*
**		Write or read a socket (for connection-based protocols).
**
**		This function is asynchronous. It will return immediately.
**		You can call this function again to check the pending connection.
**
**		The mode is RSM_RECEIVE or RSM_SEND.
**
**		The function will return:
**			=0: succeeded
**			>0: in-progress, still trying
**		    <0: error occurred, no longer trying
**
**		Before usage:
**			Open_Socket()
**			Connect_Socket()
**			Verify that RSM_CONNECT is true
**			Setup the sock->data and sock->length
**
**		Note that the mode flag is cleared by the caller, not here.
**
***********************************************************************/
{
	int result;
	long len;
	int mode = (sock->command == RDC_READ ? RSM_RECEIVE : RSM_SEND);

	if (!GET_FLAG(sock->state, RSM_CONNECT)) {
		sock->error = -18;
		return DR_ERROR;
	}

	SET_FLAG(sock->state, mode);

	// Limit size of transfer:
	len = MIN(sock->length, MAX_TRANSFER);

	if (mode == RSM_SEND) {
		// If host is no longer connected:
		result = send(sock->socket, sock->data, len, 0);
		WATCH2("send() len: %d actual: %d\n", len, result);

		if (result >= 0) {
			sock->data += result;
			sock->actual += result;
			if (sock->actual >= sock->length) {
				Signal_Device(sock, EVT_WROTE);
				return DR_DONE;
			}
			return DR_PEND;
		}
		// if (result < 0) ...
	}
	else {
		result = recv(sock->socket, sock->data, len, 0);
		WATCH2("recv() len: %d result: %d\n", len, result);

		if (result > 0) {
			sock->actual = result;
			Signal_Device(sock, EVT_READ);
			return DR_DONE;
		}
		if (result == 0) {		// The socket gracefully closed.
			sock->actual = 0;
			CLR_FLAG(sock->state, RSM_CONNECT); // But, keep RRF_OPEN true
			Signal_Device(sock, EVT_CLOSE);
			return DR_DONE;
		}
		// if (result < 0) ...
	}

	// Check error code:
	result = GET_ERROR;
	WATCH2("get error: %d %s\n", result, strerror(result));
	if (result == NE_WOULDBLOCK) return DR_PEND; // still waiting

	WATCH4("ERROR: recv(%d %x) len: %d error: %d\n", sock->socket, sock->data, len, result);
	// A nasty error happened:
	sock->error = result;
	//Signal_Device(sock, EVT_ERROR);
	return DR_ERROR;
}
예제 #29
0
파일: n-sets.c 프로젝트: kealist/ren-c
*/	static REBINT Do_Set_Operation(struct Reb_Call *call_, REBCNT flags)
/*
**		Do set operations on a series.
**
***********************************************************************/
{
	REBVAL *val;
	REBVAL *val1;
	REBVAL *val2 = 0;
	REBSER *ser;
	REBSER *hser = 0;	// hash table for series
	REBSER *retser;		// return series
	REBSER *hret;		// hash table for return series
	REBCNT i;
	REBINT h = TRUE;
	REBCNT skip = 1;	// record size
	REBCNT cased = 0;	// case sensitive when TRUE

	SET_NONE(D_OUT);
	val1 = D_ARG(1);
	i = 2;

	// Check for second series argument:
	if (flags != SET_OP_UNIQUE) {
		val2 = D_ARG(i++);
		if (VAL_TYPE(val1) != VAL_TYPE(val2))
			raise Error_Unexpected_Type(VAL_TYPE(val1), VAL_TYPE(val2));
	}

	// Refinements /case and /skip N
	cased = D_REF(i++); // cased
	if (D_REF(i++)) skip = Int32s(D_ARG(i), 1);

	switch (VAL_TYPE(val1)) {

	case REB_BLOCK:
		i = VAL_LEN(val1);
		// Setup result block:
		if (GET_FLAG(flags, SOP_BOTH)) i += VAL_LEN(val2);
		retser = BUF_EMIT;			// use preallocated shared block
		Resize_Series(retser, i);
		hret = Make_Hash_Sequence(i);	// allocated

		// Optimization note: !!
		// This code could be optimized for small blocks by not hashing them
		// and extending Find_Key to do a FIND on the value itself w/o the hash.

		do {
			// Check what is in series1 but not in series2:
			if (GET_FLAG(flags, SOP_CHECK))
				hser = Hash_Block(val2, cased);

			// Iterate over first series:
			ser = VAL_SERIES(val1);
			i = VAL_INDEX(val1);
			for (; val = BLK_SKIP(ser, i), i < SERIES_TAIL(ser); i += skip) {
				if (GET_FLAG(flags, SOP_CHECK)) {
					h = Find_Key(VAL_SERIES(val2), hser, val, skip, cased, 1) >= 0;
					if (GET_FLAG(flags, SOP_INVERT)) h = !h;
				}
				if (h) Find_Key(retser, hret, val, skip, cased, 2);
			}

			// Iterate over second series?
			if ((i = GET_FLAG(flags, SOP_BOTH))) {
				val = val1;
				val1 = val2;
				val2 = val;
				CLR_FLAG(flags, SOP_BOTH);
			}

			if (GET_FLAG(flags, SOP_CHECK))
				Free_Series(hser);
		} while (i);

		if (hret)
			Free_Series(hret);

		Val_Init_Block(D_OUT, Copy_Array_Shallow(retser));
		RESET_TAIL(retser); // required - allow reuse

		break;

	case REB_BINARY:
		cased = TRUE;
		SET_TYPE(D_OUT, REB_BINARY);
	case REB_STRING:
		i = VAL_LEN(val1);
		// Setup result block:
		if (GET_FLAG(flags, SOP_BOTH)) i += VAL_LEN(val2);

		retser = BUF_MOLD;
		Reset_Buffer(retser, i);
		RESET_TAIL(retser);

		do {
			REBUNI uc;

			cased = cased ? AM_FIND_CASE : 0;

			// Iterate over first series:
			ser = VAL_SERIES(val1);
			i = VAL_INDEX(val1);
			for (; i < SERIES_TAIL(ser); i += skip) {
				uc = GET_ANY_CHAR(ser, i);
				if (GET_FLAG(flags, SOP_CHECK)) {
					h = Find_Str_Char(VAL_SERIES(val2), 0, VAL_INDEX(val2), VAL_TAIL(val2), skip, uc, cased) != NOT_FOUND;
					if (GET_FLAG(flags, SOP_INVERT)) h = !h;
				}
				if (h && (Find_Str_Char(retser, 0, 0, SERIES_TAIL(retser), skip, uc, cased) == NOT_FOUND)) {
					Append_String(retser, ser, i, skip);
				}
			}

			// Iterate over second series?
			if ((i = GET_FLAG(flags, SOP_BOTH))) {
				val = val1;
				val1 = val2;
				val2 = val;
				CLR_FLAG(flags, SOP_BOTH);
			}
		} while (i);

		ser = Copy_String(retser, 0, -1);
		if (IS_BINARY(D_OUT))
			Val_Init_Binary(D_OUT, ser);
		else
			Val_Init_String(D_OUT, ser);
		break;

	case REB_BITSET:
		switch (flags) {
		case SET_OP_UNIQUE:
			return R_ARG1;
		case SET_OP_UNION:
			i = A_OR;
			break;
		case SET_OP_INTERSECT:
			i = A_AND;
			break;
		case SET_OP_DIFFERENCE:
			i = A_XOR;
			break;
		case SET_OP_EXCLUDE:
			i = 0; // special case
			break;
		}
		ser = Xandor_Binary(i, val1, val2);
		Val_Init_Bitset(D_OUT, ser);
		break;

	case REB_TYPESET:
		switch (flags) {
		case SET_OP_UNIQUE:
			break;
		case SET_OP_UNION:
			VAL_TYPESET(val1) |= VAL_TYPESET(val2);
			break;
		case SET_OP_INTERSECT:
			VAL_TYPESET(val1) &= VAL_TYPESET(val2);
			break;
		case SET_OP_DIFFERENCE:
			VAL_TYPESET(val1) ^= VAL_TYPESET(val2);
			break;
		case SET_OP_EXCLUDE:
			VAL_TYPESET(val1) &= ~VAL_TYPESET(val2);
			break;
		}
		return R_ARG1;

	default:
		raise Error_Invalid_Arg(val1);
	}

	return R_OUT;
}
예제 #30
0
파일: dev-net.c 프로젝트: earl/r3-hostkit
*/	DEVICE_CMD Lookup_Socket(REBREQ *sock)
/*
**		Initiate the GetHost request and return immediately.
**		This is very similar to the DNS device.
**		The request will pend until the main event handler gets WM_DNS.
**		Note the temporary results buffer (must be freed later).
**		Note we use the sock->handle for the DNS handle. During use,
**		we store the TCP socket in the length field.
**
***********************************************************************/
{
#ifdef TO_WIN32
	HANDLE handle;
#endif
	HOSTENT *host;

#ifdef HAS_ASYNC_DNS
	// Check if we are polling for completion:
	if (host = (HOSTENT*)(sock->net.host_info)) {
		// The windows main event handler will change this when it gets WM_DNS event:
		if (!GET_FLAG(sock->flags, RRF_DONE)) return DR_PEND; // still waiting
		CLR_FLAG(sock->flags, RRF_DONE);
		if (!sock->error) { // Success!
			host = (HOSTENT*)sock->net.host_info;
			COPY_MEM((char*)&(sock->net.remote_ip), (char *)(*host->h_addr_list), 4); //he->h_length);
			Signal_Device(sock, EVT_LOOKUP);
		}
		else
			Signal_Device(sock, EVT_ERROR);
		OS_Free(host);	// free what we allocated earlier
		sock->socket = sock->length; // Restore TCP socket saved below
		sock->net.host_info = 0;
		return DR_DONE;
	}

	// Else, make the lookup request:
	host = OS_Make(MAXGETHOSTSTRUCT); // be sure to free it
	handle = WSAAsyncGetHostByName(Event_Handle, WM_DNS, sock->data, (char*)host, MAXGETHOSTSTRUCT);
	if (handle != 0) {
		sock->net.host_info = host;
		sock->length = sock->socket; // save TCP socket temporarily
		sock->handle = handle;
		return DR_PEND; // keep it on pending list
	}
	OS_Free(host);
#else
	// Use old-style blocking DNS (mainly for testing purposes):
	host = gethostbyname(sock->data);
	sock->net.host_info = 0; // no allocated data

	if (host) {
		COPY_MEM((char*)&(sock->net.remote_ip), (char *)(*host->h_addr_list), 4); //he->h_length);
		CLR_FLAG(sock->flags, RRF_DONE);
		Signal_Device(sock, EVT_LOOKUP);
		return DR_DONE;
	}
#endif

	sock->error = GET_ERROR;
	//Signal_Device(sock, EVT_ERROR);
	return DR_ERROR; // Remove it from pending list
}