void CTestMachine::StepFindViewsL()
	{
	const TContactViewPreferences viewPrefs = TContactViewPreferences(EUnSortedAtEnd | EContactsOnly);
	_LIT(KMansell, 	"Mansell");	

	BEGIN_ASYNC_TEST
		
		/////////////////////////////////////////
		//Actions:	Create a local view with reverse sort plugin
		TESTTRAP(iLocalView = CContactLocalView::NewL(*this, *iDb, iSurnNameSortOrder, viewPrefs, KReverseSortPlugin));
	WAIT_EVENT(1)

		//Expected Result:	Check the order of entries in the view - it must be reverse.
		test.Printf(_L("Local View created:\n"));
		CheckViewOrderL(iLocalView);
		test.Printf(_L("\n\n"));

		/////////////////////////////////////////
		//Actions:	Create a remote view with reverse sort plugin
		TESTTRAP(iRemoteViewReverse = CContactRemoteView::NewL(*this, *iDb, iSurnNameSortOrder, viewPrefs, KReverseSortPlugin));
	WAIT_EVENT(2)

		//Expected Result:	Check the order of entries in the view - it must be reverse.
		test.Printf(_L("Remote View created:\n"));
		CheckViewOrderL(iRemoteViewReverse);
		test.Printf(_L("\n\n"));

		/////////////////////////////////////////
		//Actions:	Create a remote view with default sorting behaviour
		TESTTRAP(iRemoteViewForward = CContactRemoteView::NewL(*this, *iDb, iSurnNameSortOrder, viewPrefs));
	WAIT_EVENT(3)

		//Expected Result:	Check the order of entries in the view - it must be forward
		test.Printf(_L("Remote View created:\n"));
		CheckViewOrderL(iRemoteViewForward, EFalse, EFalse); //do not Print, forward order
		test.Printf(_L("\n\n"));

		/////////////////////////////////////////
		//Actions:	Create a Find view on top of the local view, using "Ma" search string 
		iFindDesArray =new(ELeave)CPtrC16Array(1);
		_LIT(KMa,"Ma");
		iFindDesArray->AppendL(TPtrC(KMa));

		iLocalFindView= CContactFindView::NewL(*iDb,*iLocalView,*this,iFindDesArray);
	WAIT_EVENT(4)

		//Expected Result:	Check the order of entries in the find view - it must be reverse
		test.Printf(_L("LocalFind View created:\n"));
		CheckViewOrderL(iLocalFindView);
		test.Printf(_L("\n\n"));

		/////////////////////////////////////////
		//Actions:	Create a Find view on top of the reverse remote view, using "el" search string 
		iFindDesArray->Reset();
		_LIT(Kel,"el");
		iFindDesArray->AppendL(TPtrC(Kel));
		iRemoteFindView = CContactFindView::NewL(*iDb,*iRemoteViewReverse,*this,iFindDesArray);
	WAIT_EVENT(5)
		
		//Expected Result:	Check the order of entries in the find view - it must be reverse
		test.Printf(_L("RemoteFind View created:\n"));
		CheckViewOrderL(iRemoteFindView);
		test.Printf(_L("\n\n"));

		/////////////////
		//Actions:	Add a new contact to the database, it must have "ma" and "el" substrings in it 
		//          to appear in either find view. Check the sorting in every view.		
		_LIT8(KIrvVCard, "BEGIN:VCARD\r\nVERSION:2.1\r\nN:Mansell;Nigel;11\r\nPensioner\r\nEND:VCARD");
		RDesReadStream stream(KIrvVCard);
		stream.PushL();
		  TBool success(EFalse);
		  CArrayPtr<CContactItem>* contactItems=iDb->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), stream, success, NULL);
		CleanupStack::PopAndDestroy(); // stream
		
		PUSH(contactItems);
		  TESTTRUE(success);
		  test.Printf(_L("%d entry was added created\n"), contactItems->Count());
		  contactItems->ResetAndDestroy(); //Potential memory leak - must be pushed onto the stack with ResetAndDestroy
		POPD(contactItems);

	WAIT_EVENTS(6,5) //Waiting for 5 events to arrive (one from each view) 
		//Note, that if all 5 events won't arrive the code will stuck here
		//It can be solved with another "timeout" active object, but not yet implemented
		
		//Expected Result:	Every view must send an event (5 events in total). 
		//Sort order for all the views except for RemoteForward view must be reverse. 
		//New entry must be inserted in every view.
		test.Printf(_L("Local View:\n"));
		CheckViewOrderL(iLocalView);
		test.Printf(_L("\n\n"));

		test.Printf(_L("Remote View Reverse:\n"));
		CheckViewOrderL(iRemoteViewReverse);
		test.Printf(_L("\n\n"));

		test.Printf(_L("Remote View Forward:\n"));
		CheckViewOrderL(iRemoteViewForward, EFalse, EFalse); //do not Print, forward order
		test.Printf(_L("\n\n"));

		test.Printf(_L("Local Find View:\n"));
		CheckViewOrderL(iLocalFindView);
		test.Printf(_L("\n\n"));

		test.Printf(_L("Remote Find View:\n"));
		CheckViewOrderL(iRemoteFindView);
		test.Printf(_L("\n\n"));
		
		//Searching for Mansell in the DB.
		TContactItemId manselId = SearchInViewL(iLocalFindView, KMansell);
		TESTTRUEL(manselId != 0); //Have we found it?

		//Actions:	Change a newly added contact from "Nigel Mansell" to "Ayrton Senna". 
		CContactItem* mansContact = iDb->OpenContactLX(manselId);
		PUSH(mansContact);
		  CContactItemFieldSet& fieldSet      = mansContact->CardFields();
		  
		  CContactItemField&    givenNameField = fieldSet[fieldSet.Find(KUidContactFieldGivenName)];
		  givenNameField.TextStorage()->SetTextL(_L("Ayrton"));

		  CContactItemField&    familyNameField = fieldSet[fieldSet.Find(KUidContactFieldFamilyName)];
		  familyNameField.TextStorage()->SetTextL(_L("Senna"));

		  CContactItemField&    ordinalNumField = fieldSet[fieldSet.Find(KUidContactFieldAdditionalName)];
		  ordinalNumField.TextStorage()->SetTextL(_L("20")); //Number is used for sorting checking

		iDb->CommitContactL(*mansContact);
		POPD(mansContact);
		CleanupStack::PopAndDestroy(); //record lock

	WAIT_EVENTS(7,10) //Waiting for 10 events to arrive (delele and insert event from each view)
		//Actions:	Check the sorting in every view.
	
		//Expected Result:	10 events should arrive - 5 deletes and 5 inserts. 
		//Sort order for all the views except for RemoteForward view must be reverse. 
		//The entry must be updated in local and remote views and should disappear 
		//from Find views because it doesn't contain substrings "Ma" or "el" anymore.
		test.Printf(_L("Local View:\n"));
		CheckViewOrderL(iLocalView, ETrue);
		test.Printf(_L("\n\n"));

		test.Printf(_L("Remote View Reverse:\n"));
		CheckViewOrderL(iRemoteViewReverse, ETrue);
		test.Printf(_L("\n\n"));

		test.Printf(_L("Remote View Forward:\n"));
		CheckViewOrderL(iRemoteViewForward, EFalse, EFalse); //do not Print, forward order
		test.Printf(_L("\n\n"));
		
		test.Printf(_L("Local Find View:\n"));
		CheckViewOrderL(iLocalFindView, ETrue);
		test.Printf(_L("\n\n"));

		test.Printf(_L("Remote Find View:\n"));
		CheckViewOrderL(iRemoteFindView, ETrue);
		test.Printf(_L("\n\n"));

		//We changed Mansell to Senna - the entry shouldn't appear in either find views
		TContactItemId manselId = SearchInViewL(iLocalFindView, KMansell);
		TESTTRUE(manselId == 0);
		manselId = SearchInViewL(iRemoteFindView, KMansell);
		TESTTRUE(manselId == 0);

	CloseView(iLocalFindView);
	CloseView(iLocalView);
	CloseView(iRemoteFindView);
	CloseView(iRemoteViewReverse);
	CloseView(iRemoteViewForward);

	iFindDesArray->Reset();
	delete iFindDesArray; iFindDesArray = NULL;

	END_ASYNC_TEST
	}
示例#2
0
static GLboolean equality (slang_assemble_ctx *A, slang_operation *op, GLboolean equal)
{
	slang_assembly_typeinfo ti;
	GLboolean result = GL_FALSE;
	slang_storage_aggregate agg;
	GLuint index, size;
	GLuint skip_jump, true_label, true_jump, false_label, false_jump;

	/* get type of operation */
	if (!slang_assembly_typeinfo_construct (&ti))
		return GL_FALSE;
	if (!_slang_typeof_operation (A, op, &ti))
		goto end1;

	/* convert it to an aggregate */
	if (!slang_storage_aggregate_construct (&agg))
		goto end1;
	if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs,
			A->space.vars, A->mach, A->file, A->atoms))
		goto end;

	/* compute the size of the agregate - there are two such aggregates on the stack */
	size = _slang_sizeof_aggregate (&agg);

	/* jump to the actual data-comparison code */
	skip_jump = A->file->count;
	if (!PUSH (A->file, slang_asm_jump))
		goto end;

	/* pop off the stack the compared data and push 1 */
	true_label = A->file->count;
	if (!PLAB (A->file, slang_asm_local_free, size * 2))
		goto end;
	if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 1))
		goto end;
	true_jump = A->file->count;
	if (!PUSH (A->file, slang_asm_jump))
		goto end;

	false_label = A->file->count;
	if (!PLAB (A->file, slang_asm_local_free, size * 2))
		goto end;
	if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 0))
		goto end;
	false_jump = A->file->count;
	if (!PUSH (A->file, slang_asm_jump))
		goto end;

	A->file->code[skip_jump].param[0] = A->file->count;

	/* compare the data on stack, it will eventually jump either to true or false label */
	index = 0;
	if (!equality_aggregate (A, &agg, &index, size, equal ? false_label : true_label))
		goto end;
	if (!PLAB (A->file, slang_asm_jump, equal ? true_label : false_label))
		goto end;

	A->file->code[true_jump].param[0] = A->file->count;
	A->file->code[false_jump].param[0] = A->file->count;

	result = GL_TRUE;
end:
	slang_storage_aggregate_destruct (&agg);
end1:
	slang_assembly_typeinfo_destruct (&ti);
	return result;
}
示例#3
0
static GLboolean handle_field (slang_assemble_ctx *A, slang_assembly_typeinfo *tia,
	slang_assembly_typeinfo *tib, slang_operation *op, slang_ref_type ref)
{
	/* get type info of the result (field or swizzle) */
	if (!_slang_typeof_operation (A, op, tia))
		return GL_FALSE;

	/* get type info of the master expression being accessed (struct or vector) */
	if (!_slang_typeof_operation (A, &op->children[0], tib))
		return GL_FALSE;

	/* if swizzling a vector in-place, the swizzle temporary is needed */
	if (ref == slang_ref_forbid && tia->is_swizzled)
		if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
			return GL_FALSE;

	/* assemble the master expression */
	if (!_slang_assemble_operation (A, &op->children[0], ref))
		return GL_FALSE;

	/* assemble the field expression */
	if (tia->is_swizzled)
	{
		if (ref == slang_ref_force)
		{
#if 0
			if (tia->swz.num_components == 1)
			{
				/* simple case - adjust the vector's address to point to the selected component */
				if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[0] * 4))
					return 0;
				if (!PUSH (file, slang_asm_addr_add))
					return 0;
			}
			else
#endif
			{
				/* two or more vector components are being referenced - the so-called write mask
				 * must be passed to the upper operations and applied when assigning value
				 * to this swizzle */
				A->swz = tia->swz;
			}
		}
		else
		{
			/* swizzle the vector in-place using the swizzle temporary */
			if (!_slang_assemble_constructor_from_swizzle (A, &tia->swz, &tia->spec, &tib->spec))
				return GL_FALSE;
		}
	}
	else
	{
		GLuint i, struct_size = 0, field_offset = 0, field_size = 0;
		GLboolean relocate, shrink;

		/* calculate struct size, field offset and field size */
		for (i = 0; i < tib->spec._struct->fields->num_variables; i++)
		{
			slang_variable *field;
			slang_storage_aggregate agg;
			GLuint size;

			field = &tib->spec._struct->fields->variables[i];
			if (!slang_storage_aggregate_construct (&agg))
				return GL_FALSE;
			if (!_slang_aggregate_variable (&agg, &field->type.specifier, field->array_len,
					A->space.funcs, A->space.structs, A->space.vars, A->mach, A->file, A->atoms))
			{
				slang_storage_aggregate_destruct (&agg);
				return GL_FALSE;
			}
			size = _slang_sizeof_aggregate (&agg);
			slang_storage_aggregate_destruct (&agg);

			if (op->a_id == field->a_name)
			{
				field_size = size;
				struct_size = field_offset + size;
			}
			else if (struct_size != 0)
				struct_size += size;
			else
				field_offset += size;
		}

		/*
		 * OPTIMIZATION: If selecting the last field, no relocation is needed.
		 */
		relocate = field_offset != struct_size - field_size;

		/*
		 * OPTIMIZATION: If field and struct sizes are equal, no partial free is needed.
		 */
		shrink = field_size != struct_size;

		if (relocate)
		{
			if (!PLAB (A->file, slang_asm_addr_push, field_offset))
				return GL_FALSE;
		}

		if (ref == slang_ref_force)
		{
			if (relocate)
			{
				if (!PUSH (A->file, slang_asm_addr_add))
					return GL_FALSE;
			}
		}
		else
		{
			GLuint free_b = 0;

			if (relocate)
			{
				GLuint i;

				/*
				 * Move the selected element to the end of the master expression.
				 * Do it in reverse order to avoid overwriting itself.
				 */
				for (i = field_size; i > 0; i -= 4)
					if (!PLAB2 (A->file, slang_asm_float_move, struct_size - field_size + i, i))
						return GL_FALSE;
				free_b += 4;
			}

			if (shrink)
			{
				/* free the rest of the master expression */
				free_b += struct_size - field_size;
			}

			if (free_b)
			{
				if (!PLAB (A->file, slang_asm_local_free, free_b))
					return GL_FALSE;
			}
		}
	}

	return GL_TRUE;
}
示例#4
0
GLboolean _slang_assemble_operation (slang_assemble_ctx *A, slang_operation *op, slang_ref_type ref)
{
	/* set default results */
	A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ref;
	A->swz.num_components = 0;

	switch (op->type)
	{
	case slang_oper_block_no_new_scope:
	case slang_oper_block_new_scope:
		{
			GLuint i;

			for (i = 0; i < op->num_children; i++)
			{
				if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid/*slang_ref_freelance*/))
					return GL_FALSE;
				if (!_slang_cleanup_stack (A, &op->children[i]))
					return GL_FALSE;
			}
		}
		break;
	case slang_oper_variable_decl:
		{
			GLuint i;
			slang_operation assign;
			GLboolean result;

			/* Construct assignment expression placeholder. */
			if (!slang_operation_construct (&assign))
				return GL_FALSE;
			assign.type = slang_oper_assign;
			assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
			if (assign.children == NULL)
			{
				slang_operation_destruct (&assign);
				return GL_FALSE;
			}
			for (assign.num_children = 0; assign.num_children < 2; assign.num_children++)
				if (!slang_operation_construct (&assign.children[assign.num_children]))
				{
					slang_operation_destruct (&assign);
					return GL_FALSE;
				}

			result = GL_TRUE;
			for (i = 0; i < op->num_children; i++)
			{
				slang_variable *var;

				var = _slang_locate_variable (op->children[i].locals, op->children[i].a_id, GL_TRUE);
				if (var == NULL)
				{
					result = GL_FALSE;
					break;
				}
				if (var->initializer == NULL)
					continue;

				if (!slang_operation_copy (&assign.children[0], &op->children[i]) ||
					!slang_operation_copy (&assign.children[1], var->initializer) ||
					!_slang_assemble_assign (A, &assign, "=", slang_ref_forbid) ||
					!_slang_cleanup_stack (A, &assign))
				{
					result = GL_FALSE;
					break;
				}
			}
			slang_operation_destruct (&assign);
			if (!result)
				return GL_FALSE;
		}
		break;
	case slang_oper_asm:
		{
			GLuint i;

			if (!_slang_assemble_operation (A, &op->children[0], slang_ref_force))
				return GL_FALSE;
			for (i = 1; i < op->num_children; i++)
				if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid))
					return GL_FALSE;
			if (!call_asm_instruction (A, op->a_id))
				return GL_FALSE;
		}
		break;
	case slang_oper_break:
		if (!PLAB (A->file, slang_asm_jump, A->flow.loop_end))
			return GL_FALSE;
		break;
	case slang_oper_continue:
		if (!PLAB (A->file, slang_asm_jump, A->flow.loop_start))
			return GL_FALSE;
		break;
	case slang_oper_discard:
		if (!PUSH (A->file, slang_asm_discard))
			return GL_FALSE;
		if (!PUSH (A->file, slang_asm_exit))
			return GL_FALSE;
		break;
	case slang_oper_return:
		if (A->local.ret_size != 0)
		{
			/* push the result's address */
			if (!PLAB2 (A->file, slang_asm_local_addr, 0, A->local.ret_size))
				return GL_FALSE;
			if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
				return GL_FALSE;

			A->swz.num_components = 0;
			/* assign the operation to the function result (it was reserved on the stack) */
			if (!_slang_assemble_assignment (A, op->children))
				return GL_FALSE;

			if (!PLAB (A->file, slang_asm_local_free, 4))
				return GL_FALSE;
		}
		if (!PLAB (A->file, slang_asm_jump, A->flow.function_end))
			return GL_FALSE;
		break;
	case slang_oper_expression:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[0], ref))
			return GL_FALSE;
		break;
	case slang_oper_if:
		if (!_slang_assemble_if (A, op))
			return GL_FALSE;
		break;
	case slang_oper_while:
		if (!_slang_assemble_while (A, op))
			return GL_FALSE;
		break;
	case slang_oper_do:
		if (!_slang_assemble_do (A, op))
			return GL_FALSE;
		break;
	case slang_oper_for:
		if (!_slang_assemble_for (A, op))
			return GL_FALSE;
		break;
	case slang_oper_void:
		break;
	case slang_oper_literal_bool:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!PLIT (A->file, slang_asm_bool_push, op->literal))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_literal_int:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!PLIT (A->file, slang_asm_int_push, op->literal))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_literal_float:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!PLIT (A->file, slang_asm_float_push, op->literal))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_identifier:
		{
			slang_variable *var;
			GLuint size;

			/* find the variable and calculate its size */
			var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE);
			if (var == NULL)
				return GL_FALSE;
			size = 0;
			if (!sizeof_variable (A, &var->type.specifier, slang_qual_none, var->array_len, &size))
				return GL_FALSE;

			/* prepare stack for dereferencing */
			if (ref == slang_ref_forbid)
				if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
					return GL_FALSE;

			/* push the variable's address */
			if (var->global)
			{
				if (!PLAB (A->file, slang_asm_global_addr, var->address))
					return GL_FALSE;
			}
			else
			{
				if (!PLAB2 (A->file, slang_asm_local_addr, var->address, size))
					return GL_FALSE;
			}

			/* perform the dereference */
			if (ref == slang_ref_forbid)
			{
				if (!PUSH (A->file, slang_asm_addr_copy))
					return GL_FALSE;
				if (!PLAB (A->file, slang_asm_local_free, 4))
					return GL_FALSE;
				if (!_slang_dereference (A, op))
					return GL_FALSE;
			}
		}
		break;
	case slang_oper_sequence:
		if (ref == slang_ref_force)
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/))
			return GL_FALSE;
		if (!_slang_cleanup_stack (A, &op->children[0]))
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_assign:
		if (!_slang_assemble_assign (A, op, "=", ref))
			return GL_FALSE;
		break;
	case slang_oper_addassign:
		if (!_slang_assemble_assign (A, op, "+=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_subassign:
		if (!_slang_assemble_assign (A, op, "-=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_mulassign:
		if (!_slang_assemble_assign (A, op, "*=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	/*case slang_oper_modassign:*/
	/*case slang_oper_lshassign:*/
	/*case slang_oper_rshassign:*/
	/*case slang_oper_orassign:*/
	/*case slang_oper_xorassign:*/
	/*case slang_oper_andassign:*/
	case slang_oper_divassign:
		if (!_slang_assemble_assign (A, op, "/=", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_select:
		if (!_slang_assemble_select (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_logicalor:
		if (!_slang_assemble_logicalor (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_logicaland:
		if (!_slang_assemble_logicaland (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_logicalxor:
		if (!_slang_assemble_function_call_name (A, "^^", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_bitor:*/
	/*case slang_oper_bitxor:*/
	/*case slang_oper_bitand:*/
	case slang_oper_less:
		if (!_slang_assemble_function_call_name (A, "<", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_greater:
		if (!_slang_assemble_function_call_name (A, ">", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_lessequal:
		if (!_slang_assemble_function_call_name (A, "<=", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_greaterequal:
		if (!_slang_assemble_function_call_name (A, ">=", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_lshift:*/
	/*case slang_oper_rshift:*/
	case slang_oper_add:
		if (!_slang_assemble_function_call_name (A, "+", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_subtract:
		if (!_slang_assemble_function_call_name (A, "-", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_multiply:
		if (!_slang_assemble_function_call_name (A, "*", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_modulus:*/
	case slang_oper_divide:
		if (!_slang_assemble_function_call_name (A, "/", op->children, 2, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_equal:
		if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
			return GL_FALSE;
		if (!equality (A, op->children, GL_TRUE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_notequal:
		if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid))
			return GL_FALSE;
		if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
			return GL_FALSE;
		if (!equality (A, op->children, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_preincrement:
		if (!_slang_assemble_assign (A, op, "++", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_predecrement:
		if (!_slang_assemble_assign (A, op, "--", ref))
			return GL_FALSE;
		A->ref = ref;
		break;
	case slang_oper_plus:
		if (!_slang_dereference (A, op))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_minus:
		if (!_slang_assemble_function_call_name (A, "-", op->children, 1, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	/*case slang_oper_complement:*/
	case slang_oper_not:
		if (!_slang_assemble_function_call_name (A, "!", op->children, 1, GL_FALSE))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_subscript:
		{
			slang_assembly_typeinfo ti_arr, ti_elem;

			if (!slang_assembly_typeinfo_construct (&ti_arr))
				return GL_FALSE;
			if (!slang_assembly_typeinfo_construct (&ti_elem))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				return GL_FALSE;
			}
			if (!handle_subscript (A, &ti_elem, &ti_arr, op, ref))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				slang_assembly_typeinfo_destruct (&ti_elem);
				return GL_FALSE;
			}
			slang_assembly_typeinfo_destruct (&ti_arr);
			slang_assembly_typeinfo_destruct (&ti_elem);
		}
		break;
	case slang_oper_call:
		{
			slang_function *fun;

			fun = _slang_locate_function (A->space.funcs, op->a_id, op->children, op->num_children,
				&A->space, A->atoms);
			if (fun == NULL)
			{
				if (!_slang_assemble_constructor (A, op))
					return GL_FALSE;
			}
			else
			{
				if (!_slang_assemble_function_call (A, fun, op->children, op->num_children, GL_FALSE))
					return GL_FALSE;
			}
			A->ref = slang_ref_forbid;
		}
		break;
	case slang_oper_field:
		{
			slang_assembly_typeinfo ti_after, ti_before;

			if (!slang_assembly_typeinfo_construct (&ti_after))
				return GL_FALSE;
			if (!slang_assembly_typeinfo_construct (&ti_before))
			{
				slang_assembly_typeinfo_destruct (&ti_after);
				return GL_FALSE;
			}
			if (!handle_field (A, &ti_after, &ti_before, op, ref))
			{
				slang_assembly_typeinfo_destruct (&ti_after);
				slang_assembly_typeinfo_destruct (&ti_before);
				return GL_FALSE;
			}
			slang_assembly_typeinfo_destruct (&ti_after);
			slang_assembly_typeinfo_destruct (&ti_before);
		}
		break;
	case slang_oper_postincrement:
		if (!assemble_function_call_name_dummyint (A, "++", op->children))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	case slang_oper_postdecrement:
		if (!assemble_function_call_name_dummyint (A, "--", op->children))
			return GL_FALSE;
		A->ref = slang_ref_forbid;
		break;
	default:
		return GL_FALSE;
	}

	return GL_TRUE;
}
示例#5
0
static GLboolean dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg,
	GLuint *size, slang_swizzle *swz, GLboolean is_swizzled)
{
	GLuint i;

	for (i = agg->count; i > 0; i--)
	{
		const slang_storage_array *arr = &agg->arrays[i - 1];
		GLuint j;

		for (j = arr->length; j > 0; j--)
		{
			if (arr->type == slang_stor_aggregate)
			{
				if (!dereference_aggregate (A, arr->aggregate, size, swz, is_swizzled))
					return GL_FALSE;
			}
			else
			{
				GLuint src_offset;
				slang_assembly_type ty;

				*size -= 4;

				/* calculate the offset within source variable to read */
				if (is_swizzled)
				{
					/* swizzle the index to get the actual offset */
					src_offset = swz->swizzle[*size / 4] * 4;
				}
				else
				{
					/* no swizzling - read sequentially */
					src_offset = *size;
				}

				/* dereference data slot of a basic type */
				if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
					return GL_FALSE;
				if (!PUSH (A->file, slang_asm_addr_deref))
					return GL_FALSE;
				if (!PLAB (A->file, slang_asm_addr_push, src_offset))
					return GL_FALSE;
				if (!PUSH (A->file, slang_asm_addr_add))
					return GL_FALSE;

				switch (arr->type)
				{
				case slang_stor_bool:
					ty = slang_asm_bool_deref;
					break;
				case slang_stor_int:
					ty = slang_asm_int_deref;
					break;
				case slang_stor_float:
					ty = slang_asm_float_deref;
					break;
				default:
					_mesa_problem(NULL, "Unexpected arr->type in dereference_aggregate");
					ty = slang_asm_none;
				}
				if (!PUSH (A->file, ty))
					return GL_FALSE;
			}
		}
	}

	return GL_TRUE;
}
int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus)
{
  int i = 0;
  int j = 0;
  int k;
  int x;
  int index;
  int currentPlayer = whoseTurn(state);
  int nextPlayer = currentPlayer + 1;

  int tributeRevealedCards[2] = {-1, -1};
  int temphand[MAX_HAND];// moved above the if statement
  int drawntreasure=0;
  int cardDrawn;
  int z = 0;// this is the counter for the temp hand
  if (nextPlayer > (state->numPlayers - 1)){
    nextPlayer = 0;
  }
  
	
  //uses switch to select card and perform actions
  switch( card ) 
    {
    case adventurer:
      
      return adventurerCard(currentPlayer, handPos, state, drawntreasure, cardDrawn, temphand);

			
			
			//Edit ****************************************
    case council_room:
		council_room_func(card, state, handPos, bonus, currentPlayer);
			
		return 0;
		
    case feast:

		//Checking supply and cost requirements
		if(supplyCount(choice1, state) <= 0 || getCost(choice1) > 5) return -1;

      //gain card with cost up to 5
      //Backup hand
      for (i = 0; i <= state->handCount[currentPlayer]; i++){
	temphand[i] = state->hand[currentPlayer][i];//Backup card
	state->hand[currentPlayer][i] = -1;//Set to nothing
      }
      //Backup hand

      //Update Coins for Buy
      updateCoins(currentPlayer, state, 5);
      x = 1;//Condition to loop on
      while( x == 1) {//Buy one card
	if (supplyCount(choice1, state) <= 0){
	  if (DEBUG)
	    printf("None of that card left, sorry!\n");
		
	  if (DEBUG){
	    printf("Cards Left: %d\n", supplyCount(choice1, state));
	  }
	}
	else if (state->coins < getCost(choice1)){
	  printf("That card is too expensive!\n");
		return -1;
		}
	}
    if (DEBUG){
		printf("Coins: %d < %d\n", state->coins, getCost(choice1));
	}
		
	else{


		//Add new card to discard
		gainCard(choice1, state, 0, currentPlayer);
		
		//remove feast!
		discardCard(handPos, currentPlayer, state, 1);

		return 0;
			
    case gardens:
      return -1;
			
			//Edit 2 *********************************************************************************************************************
    case mine:
		
		i = mine_func(card, i, j, choice1, choice2, state, handPos, bonus, currentPlayer);
			
        return i;
			//Edit 3 *********************************************************************************************************************
    case remodel:
		i=remodel_func(card, i, j, choice1, choice2, state, handPos, bonus, currentPlayer);


      return i;
		
    case smithy:
      smithy_func(card, i, j, choice1, choice2, state, handPos, bonus, currentPlayer);
      return 0;
		
    case village:
      village_func(card, i, j, choice1, choice2, state, handPos, bonus, currentPlayer);
      return 0;
		
    case baron:
		//increment purchase number
		state->numBuys++;
		
		if(choice1) //Checking bool if we going to discard victory card
		{
			for( i = 0; i < state->handCount[currentPlayer]; ++i)
			{
				if(state->hand[currentPlayer][i] == estate)
				{
					//increamenting coins
					state->coins += 4;
					//discard victory card
					discardCard(i, currentPlayer, state, 0); 
					//discard baron
					discardCard(baron, currentPlayer, state, 0); 
					return 0;
				}
			}

			
		}
		//No estate found, going to get one
		gainCard(estate, state, 0, currentPlayer); //try to get estate

		discardCard(handPos, currentPlayer, state, 0); //discard baron
		return 0;
	    

		
    case great_hall:
      //+1 Card
      drawCard(currentPlayer, state);
			
      //+1 Actions
      state->numActions++;
			
      //discard card from hand
      discardCard(handPos, currentPlayer, state, 0);
      return 0;
		
    case minion:
      //+1 action
      state->numActions++;
			
      //discard card from hand
      discardCard(handPos, currentPlayer, state, 0);
			
      if (choice1)		//+2 coins
	{
	  state->coins = state->coins + 2;
	}
			
      else if (choice2)		//discard hand, redraw 4, other players with 5+ cards discard hand and draw 4
	{
	  //discard hand
	  while(numHandCards(state) > 0)
	    {
	      discardCard(handPos, currentPlayer, state, 0);
	    }
				
	  //draw 4
	  for (i = 0; i < 4; i++)
	    {
	      drawCard(currentPlayer, state);
	    }
				
	  //other players discard hand and redraw if hand size > 4
	  for (i = 0; i < state->numPlayers; i++)
	    {
	      if (i != currentPlayer)
		{
		  if ( state->handCount[i] > 4 )
		    {
		      //discard hand
		      while( state->handCount[i] > 0 )
			{
			  discardCard(handPos, i, state, 0);
			}
							
		      //draw 4
		      for (j = 0; j < 4; j++)
			{
			  drawCard(i, state);
			}
		    }
		}
	    }
				
	}
      return 0;
		
    case steward:
      if (choice1 == 1)
	{
	  //+2 cards
	  drawCard(currentPlayer, state);
	  drawCard(currentPlayer, state);
	}
      else if (choice1 == 2)
	{
	  //+2 coins
	  state->coins = state->coins + 2;
	}
      else
	{
	  //trash 2 cards in hand
	  discardCard(choice2, currentPlayer, state, 1);
	  discardCard(choice3, currentPlayer, state, 1);
	}
			
      //discard card from hand
      discardCard(handPos, currentPlayer, state, 0);
      return 0;
		
    case tribute:
      if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1){
	if (state->deckCount[nextPlayer] > 0){
	  tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1];
	  state->deckCount[nextPlayer]--;
	}
	else if (state->discardCount[nextPlayer] > 0){
	  tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer]-1];
	  state->discardCount[nextPlayer]--;
	}
	else{
	  //No Card to Reveal
	  if (DEBUG){
	    printf("No cards to reveal\n");
	  }
	}
      }
	    
      else{
	if (state->deckCount[nextPlayer] == 0){
	  for (i = 0; i < state->discardCount[nextPlayer]; i++){
	    state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck
	    state->deckCount[nextPlayer]++;
	    state->discard[nextPlayer][i] = -1;
	    state->discardCount[nextPlayer]--;
	  }
			    
	  shuffle(nextPlayer,state);//Shuffle the deck
	} 
	tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1];
	state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1;
	state->deckCount[nextPlayer]--;
	tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1];
	state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1;
	state->deckCount[nextPlayer]--;
      }    
		       
      if (tributeRevealedCards[0] == tributeRevealedCards[1]){//If we have a duplicate card, just drop one 
	state->playedCards[state->playedCardCount] = tributeRevealedCards[1];
	state->playedCardCount++;
	tributeRevealedCards[1] = -1;
      }

      for (i = 0; i <= 2; i ++){
	if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold){//Treasure cards
	  state->coins += 2;
	}
		    
	else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall){//Victory Card Found
	  drawCard(currentPlayer, state);
	  drawCard(currentPlayer, state);
	}
	else{//Action Card
	  state->numActions = state->numActions + 2;
	}
      }
	    
      return 0;
		
    case ambassador:
      j = 0;		//used to check if player has enough cards to discard

      if (choice2 > 2 || choice2 < 0)
	{
	  return -1;				
	}

      if (choice1 == handPos)
	{
	  return -1;
	}

      for (i = 0; i < state->handCount[currentPlayer]; i++)
	{
	  if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1)
	    {
	      j++;
	    }
	}
      if (j < choice2)
	{
	  return -1;				
	}

      if (DEBUG) 
	printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]);

      //increase supply count for choosen card by amount being discarded
      state->supplyCount[state->hand[currentPlayer][choice1]] += choice2;
			
      //each other player gains a copy of revealed card
      for (i = 0; i < state->numPlayers; i++)
	{
	  if (i != currentPlayer)
	    {
	      gainCard(state->hand[currentPlayer][choice1], state, 0, i);
	    }
	}

      //discard played card from hand
      discardCard(handPos, currentPlayer, state, 0);			

      //trash copies of cards returned to supply
      for (j = 0; j < choice2; j++)
	{
	  for (i = 0; i < state->handCount[currentPlayer]; i++)
	    {
	      if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1])
		{
		  discardCard(i, currentPlayer, state, 1);
		  break;
		}
	    }
	}			

      return 0;
		
    case cutpurse:

      updateCoins(currentPlayer, state, 2);
      for (i = 0; i < state->numPlayers; i++)
	{
	  if (i != currentPlayer)
	    {
	      for (j = 0; j < state->handCount[i]; j++)
		{
		  if (state->hand[i][j] == copper)
		    {
		      discardCard(j, i, state, 0);
		      break;
		    }
		  if (j == state->handCount[i])
		    {
		      for (k = 0; k < state->handCount[i]; k++)
			{
			  if (DEBUG)
			    printf("Player %d reveals card number %d\n", i, state->hand[i][k]);
			}	
		      break;
		    }		
		}
					
	    }
				
	}				

      //discard played card from hand
      discardCard(handPos, currentPlayer, state, 0);			

      return 0;

		
    case embargo: 
      //+2 Coins
      state->coins = state->coins + 2;
			
      //see if selected pile is in play
      if ( state->supplyCount[choice1] == -1 )
	{
	  return -1;
	}
			
      //add embargo token to selected supply pile
      state->embargoTokens[choice1]++;
			
      //trash card
      discardCard(handPos, currentPlayer, state, 1);		
      return 0;
		
    case outpost:
      //set outpost flag
      state->outpostPlayed++;
			
      //discard card
      discardCard(handPos, currentPlayer, state, 0);
      return 0;
		
    case salvager:
      //+1 buy
      state->numBuys++;
			
      if (choice1)
	{
	  //gain coins equal to trashed card
	  state->coins = state->coins + getCost( handCard(choice1, state) );
	  //trash card
	  discardCard(choice1, currentPlayer, state, 1);	
	}
			
      //discard card
      discardCard(handPos, currentPlayer, state, 0);
      return 0;
		
    case sea_hag:
      for(i = (currentPlayer+1)%state->numPlayers; i != currentPlayer; i = (i+1)%state->numPlayers)
		{
		if (drawCard(i, state) != 1){
		  PUSH(discard, i, POP_R(hand, i));
		}  
		  gainCard(curse, state, 1, i);
		
	}
	discardCard(handPos, currentPlayer, state, 0);

	return 0;
		
    case treasure_map:
      //search hand for another treasure_map
      index = -1;
      for (i = 0; i < state->handCount[currentPlayer]; i++)
	{
	  if (state->hand[currentPlayer][i] == treasure_map && i != handPos)
	    {
	      index = i;
	      break;
	    }
	}
      if (index > -1)
	{
	  //trash both treasure cards
	  discardCard(handPos, currentPlayer, state, 1);
	  discardCard(index, currentPlayer, state, 1);

	  //gain 4 Gold cards
	  for (i = 0; i < 4; i++)
	    {
	      gainCard(gold, state, 1, currentPlayer);
	    }
				
	  //return success
	  return 1;
	}
			
      //no second treasure_map found in hand
      return -1;
    }
	
  return -1;
	}
}
示例#7
0
int 
xcoff_load(ihandle_t dev)
{
	COFF_filehdr_t fhdr;
	COFF_aouthdr_t ahdr;
	COFF_scnhdr_t shdr;
	uint32_t offset;
	size_t total_size = 0;
	int fd, i;
	int retval = -1;
	
	/* Mark the saved-program-state as invalid */
	feval("0 state-valid !");

	fd = open_ih(dev);
	if (fd == -1) {
		retval = LOADER_NOT_SUPPORT;
		goto out;
	}
	
	for (offset = 0; offset < 16 * 512; offset += 512) {
		seek_io(fd, offset);
		if (read_io(fd, &fhdr, sizeof fhdr) != sizeof fhdr) {
			DPRINTF("Can't read XCOFF header\n");
			retval = LOADER_NOT_SUPPORT;
			goto out;
		}
		
		if (is_xcoff(&fhdr))
			break;
	}
	
	/* Is it executable ? */
	if (fhdr.f_magic != 0x01DF &&
	    (fhdr.f_flags & COFF_F_EXEC) == 0) {
		DPRINTF("Not an executable XCOFF file %02x\n", fhdr.f_flags);
		return LOADER_NOT_SUPPORT;
	}

	/* Optional header is a.out ? */
	if (fhdr.f_opthdr != sizeof(COFF_aouthdr_t)) {
		DPRINTF("AOUT optional error size mismatch in XCOFF file\n");
		return LOADER_NOT_SUPPORT;
	}
	
	seek_io(fd, sizeof(COFF_filehdr_t));
	read_io(fd, &ahdr, sizeof(COFF_aouthdr_t));
	
	/* check a.out magic number */
	if (ahdr.magic != AOUT_MAGIC) {
		DPRINTF("Invalid AOUT optional header\n");
		return LOADER_NOT_SUPPORT;
	}

	offset = sizeof(COFF_filehdr_t) + sizeof(COFF_aouthdr_t);

	DPRINTF("XCOFF file with %d sections\n", fhdr.f_nscns);

	for (i = 0; i < fhdr.f_nscns; i++) {
		DPRINTF("Read header at offset %0x\n", offset);
		seek_io(fd, offset);
		read_io(fd, &shdr, sizeof(COFF_scnhdr_t));

		DPRINTF("Initializing '%s' section from %0x %0x to %0x (%0x)\n",
			shdr.s_name, offset, shdr.s_scnptr,
			shdr.s_vaddr, shdr.s_size);

		if (strcmp(shdr.s_name, ".text") == 0) {
			read_io(fd, (void *)shdr.s_vaddr, shdr.s_size);
			total_size += shdr.s_size;
#ifdef CONFIG_PPC
			flush_icache_range((char*)(uintptr_t)shdr.s_vaddr,
					 (char*)(uintptr_t)(shdr.s_vaddr + shdr.s_size));
#endif
		} else if (strcmp(shdr.s_name, ".data") == 0) {
			read_io(fd, (void *)shdr.s_vaddr, shdr.s_size);
			total_size += shdr.s_size;

		} else if (strcmp(shdr.s_name, ".bss") == 0) {
			memset((void *)(uintptr_t)shdr.s_vaddr, 0, shdr.s_size);
			total_size += shdr.s_size;
		} else {
			DPRINTF("    Skip '%s' section\n", shdr.s_name);
		}
		offset += sizeof(COFF_scnhdr_t);
	}

	DPRINTF("XCOFF entry point: %x\n", *(uint32_t*)ahdr.entry);

	// Initialise load-state
	PUSH(total_size);
	feval("load-state >ls.file-size !");
	feval("xcoff load-state >ls.file-type !");

out:
	close_io(fd);
	return retval;
}
示例#8
0
std::vector<QPoint>
floodFill(QImage *img, const QPoint &pos, const QRgb &newColor)
{
   QImage image = img->copy();
   std::vector<QPoint> modified;

   int x = pos.x(), y = pos.y();
   const QRgb oldColor = image.pixel(x, y);

   std::vector<fillpixelinfo> stack;

   int l, x1, x2, dy;

   if ((x >= 0) && (x < image.width()) && (y >= 0) && (y < image.height()))
   {
       if (oldColor == newColor)
       {
           return modified;
       }
       PUSH(y, x, x, 1);
       PUSH(y + 1, x, x, -1);
       while (!stack.empty())
       {
           POP(y, x1, x2, dy);
           for (x = x1; (x >= 0) && image.pixel(x, y) == oldColor; x--)
           {
               image.setPixel(x, y, newColor);
               modified.emplace_back(x, y);
           }
           if (x >= x1)
           {
               goto skip;
           }
           l = x + 1;
           if (l < x1)
           {
               PUSH(y, l, x1 - 1, -dy);
           }
           x = x1 + 1;
           do
           {
               for (; (x < image.width()) && image.pixel(x, y) == oldColor; x++)
               {
                   image.setPixel(x, y, newColor);
                   modified.emplace_back(x, y);
               }
               PUSH(y, l, x - 1, dy);
               if (x > x2 + 1)
               {
                   PUSH(y, x2 + 1, x - 1, -dy);
               }
skip:
               for (x++; x <= x2 && image.pixel(x, y) != oldColor; x++)
               {
                   /* empty */ ;
               }
               l = x;
           } while (x <= x2);
       }
   }

   return modified;
}
void
INTSORTNAME (
void * const                pbase,                /*+ Array to sort             +*/
const PASTIX_INT                   total_elems)          /*+ Number of entries to sort +*/
{
  register char *base_ptr = (char *) pbase;

  if (total_elems == 0)
    /* Avoid lossage with unsigned arithmetic below.  */
    return;

  if (total_elems > MAX_THRESH)
    {
      char *lo = base_ptr;
      char *hi = &lo[INTSORTSIZE * (total_elems - 1)];
      stack_node stack[STACK_SIZE];
      stack_node *top = stack;

      PUSH (NULL, NULL);

      while (STACK_NOT_EMPTY)
        {
          char *left_ptr;
          char *right_ptr;

	  /* Select median value from among LO, MID, and HI. Rearrange
	     LO and HI so the three values are sorted. This lowers the
	     probability of picking a pathological pivot value and
	     skips a comparison for both the LEFT_PTR and RIGHT_PTR in
	     the while loops. */

	  char *mid = lo + INTSORTSIZE * ((hi - lo) / INTSORTSIZE >> 1);

	  if (INTSORTCMP ((void *) mid, (void *) lo))
	    INTSORTSWAP (mid, lo);
	  if (INTSORTCMP ((void *) hi, (void *) mid))
	    INTSORTSWAP (mid, hi);
	  else
	    goto jump_over;
	  if (INTSORTCMP ((void *) mid, (void *) lo))
	    INTSORTSWAP (mid, lo);
	jump_over:;

	  left_ptr  = lo + INTSORTSIZE;
	  right_ptr = hi - INTSORTSIZE;

	  /* Here's the famous ``collapse the walls'' section of quicksort.
	     Gotta like those tight inner loops!  They are the main reason
	     that this algorithm runs much faster than others. */
	  do
	    {
	      while (INTSORTCMP ((void *) left_ptr, (void *) mid))
		left_ptr += INTSORTSIZE;

	      while (INTSORTCMP ((void *) mid, (void *) right_ptr))
		right_ptr -= INTSORTSIZE;

	      if (left_ptr < right_ptr)
		{
		  INTSORTSWAP (left_ptr, right_ptr);
		  if (mid == left_ptr)
		    mid = right_ptr;
		  else if (mid == right_ptr)
		    mid = left_ptr;
		  left_ptr += INTSORTSIZE;
		  right_ptr -= INTSORTSIZE;
		}
	      else if (left_ptr == right_ptr)
		{
		  left_ptr += INTSORTSIZE;
		  right_ptr -= INTSORTSIZE;
		  break;
		}
	    }
	  while (left_ptr <= right_ptr);

          /* Set up pointers for next iteration.  First determine whether
             left and right partitions are below the threshold size.  If so,
             ignore one or both.  Otherwise, push the larger partition's
             bounds on the stack and continue sorting the smaller one. */

          if ((size_t) (right_ptr - lo) <= max_thresh)
            {
              if ((size_t) (hi - left_ptr) <= max_thresh)
		/* Ignore both small partitions. */
                POP (lo, hi);
              else
		/* Ignore small left partition. */
                lo = left_ptr;
            }
          else if ((size_t) (hi - left_ptr) <= max_thresh)
	    /* Ignore small right partition. */
            hi = right_ptr;
          else if ((right_ptr - lo) > (hi - left_ptr))
            {
	      /* Push larger left partition indices. */
              PUSH (lo, right_ptr);
              lo = left_ptr;
            }
          else
            {
	      /* Push larger right partition indices. */
              PUSH (left_ptr, hi);
              hi = right_ptr;
            }
        }
    }
示例#10
0
mrb_value
mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)
{
    const char *p, *end;
    char *buf;
    mrb_int blen;
    mrb_int bsiz;
    mrb_int n;
    mrb_int width;
    mrb_int prec;
    int flags = FNONE;
    int nextarg = 1;
    int posarg = 0;
    mrb_value nextvalue;
    mrb_value tmp;
    mrb_value str;
    mrb_value hash = mrb_value::undef();

#define CHECK_FOR_WIDTH(f)                                                  \
    if ((f) & FWIDTH) {                                                       \
    mrb->mrb_raise(E_ARGUMENT_ERROR, "width given twice");         \
}                                                                         \
    if ((f) & FPREC0) {                                                       \
    mrb->mrb_raise(E_ARGUMENT_ERROR, "width after precision");     \
}
#define CHECK_FOR_FLAGS(f)                                                  \
    if ((f) & FWIDTH) {                                                       \
    mrb->mrb_raise(E_ARGUMENT_ERROR, "flag after width");          \
}                                                                         \
    if ((f) & FPREC0) {                                                       \
    mrb->mrb_raise(E_ARGUMENT_ERROR, "flag after precision");      \
}

    ++argc;
    --argv;
    fmt = mrb_str_to_str(mrb, fmt);
    p = RSTRING_PTR(fmt);
    end = p + RSTRING_LEN(fmt);
    blen = 0;
    bsiz = 120;
    RString *res_ptr= RString::create(mrb,bsiz);
    buf = res_ptr->m_ptr;
    memset(buf, 0, bsiz);

    for (; p < end; p++) {
        const char *t;
        mrb_sym id = 0;

        for (t = p; t < end && *t != '%'; t++) ;
        PUSH(p, t - p);
        if (t >= end)
            goto sprint_exit; /* end of fmt string */

        p = t + 1;    /* skip `%' */

        width = prec = -1;
        nextvalue = mrb_value::undef();

retry:
        switch (*p) {
        default:
            mrb->mrb_raisef(E_ARGUMENT_ERROR, "malformed format string - \\%%S", mrb_str_new(mrb, p, 1));
            break;

        case ' ':
            CHECK_FOR_FLAGS(flags);
            flags |= FSPACE;
            p++;
            goto retry;

        case '#':
            CHECK_FOR_FLAGS(flags);
            flags |= FSHARP;
            p++;
            goto retry;

        case '+':
            CHECK_FOR_FLAGS(flags);
            flags |= FPLUS;
            p++;
            goto retry;

        case '-':
            CHECK_FOR_FLAGS(flags);
            flags |= FMINUS;
            p++;
            goto retry;

        case '0':
            CHECK_FOR_FLAGS(flags);
            flags |= FZERO;
            p++;
            goto retry;

        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            n = 0;
            GETNUM(n, width);
            if (*p == '$') {
                if (!nextvalue.is_undef()) {
                    mrb->mrb_raisef(E_ARGUMENT_ERROR, "value given twice - %S$", mrb_fixnum_value(n));
                }
                nextvalue = GETPOSARG(n);
                p++;
                goto retry;
            }
            CHECK_FOR_WIDTH(flags);
            width = n;
            flags |= FWIDTH;
            goto retry;

        case '<':
        case '{': {
            const char *start = p;
            char term = (*p == '<') ? '>' : '}';
            mrb_value symname;

            for (; p < end && *p != term; )
                p++;
            if (id) {
                mrb->mrb_raisef(E_ARGUMENT_ERROR, "name%S after <%S>",
                                mrb_str_new(mrb, start, p - start + 1), mrb_sym2str(mrb, id));
            }
            symname = mrb_str_new(mrb, start + 1, p - start - 1);
            id = mrb_intern_str(mrb, symname);
            nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1));
            if (nextvalue.is_undef()) {
                mrb->mrb_raisef(E_KEY_ERROR, "key%S not found", mrb_str_new(mrb, start, p - start + 1));
            }
            if (term == '}') goto format_s;
            p++;
            goto retry;
        }

        case '*':
            CHECK_FOR_WIDTH(flags);
            flags |= FWIDTH;
            GETASTER(width);
            if (width < 0) {
                flags |= FMINUS;
                width = -width;
            }
            p++;
            goto retry;

        case '.':
            if (flags & FPREC0) {
                mrb->mrb_raise(E_ARGUMENT_ERROR, "precision given twice");
            }
            flags |= FPREC|FPREC0;

            prec = 0;
            p++;
            if (*p == '*') {
                GETASTER(prec);
                if (prec < 0) {  /* ignore negative precision */
                    flags &= ~FPREC;
                }
                p++;
                goto retry;
            }

            GETNUM(prec, precision);
            goto retry;

        case '\n':
        case '\0':
            p--;

        case '%':
            if (flags != FNONE) {
                mrb->mrb_raise(E_ARGUMENT_ERROR, "invalid format character - %");
            }
            PUSH("%", 1);
            break;

        case 'c': {
            mrb_value val = GETARG();
            mrb_value tmp;
            unsigned int c;

            tmp = mrb_check_string_type(mrb, val);
            if (!tmp.is_nil()) {
                if (RSTRING_LEN(tmp) != 1 ) {
                    mrb->mrb_raise(E_ARGUMENT_ERROR, "%c requires a character");
                }
                c = RSTRING_PTR(tmp)[0];
                n = 1;
            }
            else {
                c = mrb_fixnum(val);
                n = 1;
            }
            if (n <= 0) {
                mrb->mrb_raise(E_ARGUMENT_ERROR, "invalid character");
            }
            if (!(flags & FWIDTH)) {
                CHECK(n);
                buf[blen] = c;
                blen += n;
            }
            else if ((flags & FMINUS)) {
                CHECK(n);
                buf[blen] = c;
                blen += n;
                FILL(' ', width-1);
            }
            else {
                FILL(' ', width-1);
                CHECK(n);
                buf[blen] = c;
                blen += n;
            }
        }
        break;

        case 's':
        case 'p':
format_s:
            {
                mrb_value arg = GETARG();
                mrb_int len;
                mrb_int slen;

                if (*p == 'p')
                    arg = mrb_inspect(mrb, arg)->wrap();
                str = mrb_obj_as_string(mrb, arg)->wrap();
                len = RSTRING_LEN(str);
                res_ptr->len = blen;
                if (flags&(FPREC|FWIDTH)) {
                    slen = RSTRING_LEN(str);
                    if (slen < 0) {
                        mrb->mrb_raise(E_ARGUMENT_ERROR, "invalid mbstring sequence");
                    }
                    if ((flags&FPREC) && (prec < slen)) {
                        char *p = RSTRING_PTR(str) + prec;
                        slen = prec;
                        len = p - RSTRING_PTR(str);
                    }
                    /* need to adjust multi-byte string pos */
                    if ((flags&FWIDTH) && (width > slen)) {
                        width -= (int)slen;
                        if (!(flags&FMINUS)) {
                            CHECK(width);
                            while (width--) {
                                buf[blen++] = ' ';
                            }
                        }
                        CHECK(len);
                        memcpy(&buf[blen], RSTRING_PTR(str), len);
                        blen += len;
                        if (flags&FMINUS) {
                            CHECK(width);
                            while (width--) {
                                buf[blen++] = ' ';
                            }
                        }
                        break;
                    }
                }
                PUSH(RSTRING_PTR(str), len);
            }
            break;

        case 'd':
        case 'i':
        case 'o':
        case 'x':
        case 'X':
        case 'b':
        case 'B':
        case 'u': {
            mrb_value val = GETARG();
            char fbuf[32], nbuf[64], *s;
            const char *prefix = NULL;
            int sign = 0, dots = 0;
            char sc = 0;
            mrb_int v = 0, org_v = 0;
            int base;
            mrb_int len;

            switch (*p) {
            case 'd':
            case 'i':
            case 'u':
                sign = 1;
                break;
            case 'o':
            case 'x':
            case 'X':
            case 'b':
            case 'B':
                if (flags&(FPLUS|FSPACE)) sign = 1;
                break;
            default:
                break;
            }
            if (flags & FSHARP) {
                switch (*p) {
                case 'o':
                    prefix = "0";
                    break;
                case 'x':
                    prefix = "0x";
                    break;
                case 'X':
                    prefix = "0X";
                    break;
                case 'b':
                    prefix = "0b";
                    break;
                case 'B':
                    prefix = "0B";
                    break;
                default:
                    break;
                }
            }

bin_retry:
            switch (mrb_type(val)) {
            case MRB_TT_FLOAT:
                if (FIXABLE(mrb_float(val))) {
                    val = mrb_fixnum_value((mrb_int)mrb_float(val));
                    goto bin_retry;
                }
                v = mrb_flo_to_fixnum(mrb, val);
                break;
            case MRB_TT_STRING:
                v = val.ptr<RString>()->mrb_str_to_inum(0, true);
                break;
            case MRB_TT_FIXNUM:
                v = mrb_fixnum(val);
                break;
            default:
                val = mrb_Integer(mrb, val);
                goto bin_retry;
            }

            switch (*p) {
            case 'o':
                base = 8;
                break;
            case 'x':
            case 'X':
                base = 16;
                break;
            case 'b':
            case 'B':
                base = 2;
                break;
            case 'u':
            case 'd':
            case 'i':
            default:
                base = 10;
                break;
            }

            if (base == 2) {
                org_v = v;
                RString *val_ptr;
                if ( v < 0 && !sign ) {
                    val_ptr = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
                    dots = 1;
                }
                else {
                    val_ptr = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);
                }
                v = val_ptr->mrb_str_to_inum(10, false);
            }
            if (sign) {
                char c = *p;
                if (c == 'i') c = 'd'; /* %d and %i are identical */
                if (base == 2) c = 'd';
                if (v < 0) {
                    v = -v;
                    sc = '-';
                    width--;
                }
                else if (flags & FPLUS) {
                    sc = '+';
                    width--;
                }
                else if (flags & FSPACE) {
                    sc = ' ';
                    width--;
                }
                snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
                snprintf(nbuf, sizeof(nbuf), fbuf, v);
                s = nbuf;
            }
            else {
                char c = *p;
                if (c == 'X') c = 'x';
                if (base == 2) c = 'd';
                s = nbuf;
                if (v < 0) {
                    dots = 1;
                }
                snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
                snprintf(++s, sizeof(nbuf) - 1, fbuf, v);
                if (v < 0) {
                    char d;

                    s = remove_sign_bits(s, base);
                    switch (base) {
                    case 16:
                        d = 'f';
                        break;
                    case 8:
                        d = '7';
                        break;
                    case 2:
                        d = '1';
                        break;
                    default:
                        d = 0;
                        break;
                    }

                    if (d && *s != d) {
                        *--s = d;
                    }
                }
            }
            {
                size_t size;
                size = strlen(s);
                /* PARANOID: assert(size <= MRB_INT_MAX) */
                len = (mrb_int)size;
            }

            if (dots) {
                prec -= 2;
                width -= 2;
            }

            if (*p == 'X') {
                char *pp = s;
                int c;
                while ((c = (int)(unsigned char)*pp) != 0) {
                    *pp = toupper(c);
                    pp++;
                }
            }

            if (prefix && !prefix[1]) { /* octal */
                if (dots) {
                    prefix = NULL;
                }
                else if (len == 1 && *s == '0') {
                    len = 0;
                    if (flags & FPREC) prec--;
                }
                else if ((flags & FPREC) && (prec > len)) {
                    prefix = NULL;
                }
            }
            else if (len == 1 && *s == '0') {
                prefix = NULL;
            }

            if (prefix) {
                size_t size;
                size = strlen(prefix);
                /* PARANOID: assert(size <= MRB_INT_MAX).
                *  this check is absolutely paranoid. */
                width -= (mrb_int)size;
            }

            if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
                prec = width;
                width = 0;
            }
            else {
                if (prec < len) {
                    if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
                    prec = len;
                }
                width -= prec;
            }

            if (!(flags&FMINUS)) {
                CHECK(width);
                while (width-- > 0) {
                    buf[blen++] = ' ';
                }
            }

            if (sc) PUSH(&sc, 1);

            if (prefix) {
                int plen = (int)strlen(prefix);
                PUSH(prefix, plen);
            }
            CHECK(prec - len);
            if (dots) PUSH("..", 2);

            if (v < 0 || (base == 2 && org_v < 0)) {
                char c = sign_bits(base, p);
                while (len < prec--) {
                    buf[blen++] = c;
                }
            }
            else if ((flags & (FMINUS|FPREC)) != FMINUS) {
                char c = '0';
                while (len < prec--) {
                    buf[blen++] = c;
                }
            }

            PUSH(s, len);
            CHECK(width);
            while (width-- > 0) {
                buf[blen++] = ' ';
            }
        }
        break;

        case 'f':
        case 'g':
        case 'G':
        case 'e':
        case 'E':
        case 'a':
        case 'A': {
            mrb_value val = GETARG();
            double fval;
            int i, need = 6;
            char fbuf[32];

            fval = mrb_float(mrb_Float(mrb, val));
            if (isnan(fval) || isinf(fval)) {
                const char *expr;
                const int elen = 3;

                if (isnan(fval)) {
                    expr = "NaN";
                }
                else {
                    expr = "Inf";
                }
                need = elen;
                if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
                    need++;
                if ((flags & FWIDTH) && need < width)
                    need = width;

                CHECK(need + 1);
                snprintf(&buf[blen], need + 1, "%*s", need, "");
                if (flags & FMINUS) {
                    if (!isnan(fval) && fval < 0.0)
                        buf[blen++] = '-';
                    else if (flags & FPLUS)
                        buf[blen++] = '+';
                    else if (flags & FSPACE)
                        blen++;
                    memcpy(&buf[blen], expr, elen);
                }
                else {
                    if (!isnan(fval) && fval < 0.0)
                        buf[blen + need - elen - 1] = '-';
                    else if (flags & FPLUS)
                        buf[blen + need - elen - 1] = '+';
                    else if ((flags & FSPACE) && need > width)
                        blen++;
                    memcpy(&buf[blen + need - elen], expr, elen);
                }
                blen += strlen(&buf[blen]);
                break;
            }

            fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
            need = 0;
            if (*p != 'e' && *p != 'E') {
                i = INT_MIN;
                frexp(fval, &i);
                if (i > 0)
                    need = BIT_DIGITS(i);
            }
            need += (flags&FPREC) ? prec : 6;
            if ((flags&FWIDTH) && need < width)
                need = width;
            need += 20;

            CHECK(need);
            n = snprintf(&buf[blen], need, fbuf, fval);
            blen += n;
        }
        break;
        }
        flags = FNONE;
    }

sprint_exit:
#if 0
    /* XXX - We cannot validate the number of arguments if (digit)$ style used.
    */
    if (posarg >= 0 && nextarg < argc) {
        const char *mesg = "too many arguments for format string";
        if (mrb_test(ruby_debug)) mrb->mrb_raise(E_ARGUMENT_ERROR, mesg);
        if (mrb_test(ruby_verbose)) mrb_warn(mrb,"%s", mesg);
    }
#endif
    res_ptr->resize(blen);
    return res_ptr->wrap();
}
示例#11
0
文件: bsf_main.c 项目: dv913/manna
int main(int argc, char *argv[]) {
//sgenrand(time(NULL));
int k, curr_pos, check;
int chunk; /* Repeat experiment in chunks. */
srand(SEED);

printf("# Info: $Header: /home/ma/p/pruess/.cvsroot/manna_range/dmitry_20151021/manna_stack_clean_edited.c,v 1.2 2015/10/21 11:37:00 pruess Exp $\n");
preamble(argc, argv);

PRINT_PARAM(SEED, "%lu");
PRINT_PARAM(LENGTH, "%lu");
PRINT_PARAM(DROP_LOCATION, "%lu");
PRINT_PARAM(total_malloced, "%lli");


printf("# Info: Expected avalanche size: <s>(x) = 1+(1/2) (<s>(x+1)+<s>(x-1)), BC <s>(0)=0, <s>(L+1)=0, solved by <s>(x)=(L+1-x)x/2.\n");
printf("# Info: Here L=LENGTH=%lu and x=DROP_LOCATION+1=%lu, so expect %g\n", LENGTH, DROP_LOCATION+1, ((double)(DROP_LOCATION+1))*((double)(LENGTH-DROP_LOCATION))/2.);


for (chunk=1; ((chunk<=NUM_CHUNKS) || (NUM_CHUNKS<0)); chunk++) {
MOMENTS_INIT(size);
for (drop = 0; drop < N_ROLLS; drop++) {  // big droppping cycle

size=0;

#if (1-MODE_BSF)

#define PUSH(a) stack[stack_used++]=(a)
#define POP(a)  (a)=stack[--stack_used]

if(lattice[DROP_LOCATION] == 0) {
      lattice[DROP_LOCATION] = 1;
      }
 else {
      PUSH(DROP_LOCATION); 
      PUSH(DROP_LOCATION);
      lattice[DROP_LOCATION] = 0;
      size++;
 }

/* If validated, optimse by turning stack operations into macros, 
 * optime random number drawing (rather than having doubles in the tree
 * have integers there and draw an integer to compare against),
 * optimise the shuffling of particles. 
 *
 * I have added MOMENT macros for size. */

  while(stack_used != 0) {
    POP(curr_pos);
/* This code with the "check" looks clumsy. I suppose
 * you are "following through" topplings? I would think
 * there is no point doing this later. Anyway, we validate
 * this code and take it from there. */
    do {
      curr_pos = curr_pos+ ( (rand()>RAND_MAX/2) ? 1 : -1); //move_ball(curr_pos);
 
      if((curr_pos>=0) && (curr_pos<LENGTH)) {
        if(lattice[curr_pos] == 0)  {
          lattice[curr_pos] = 1;
          }
        else  {
          size++;
          lattice[curr_pos] = 0;
          PUSH(curr_pos);
        }
    } 
    else {break;}
  }while( (lattice[curr_pos] != 1));
}/* end of while(stack_used != 0) look */
#endif

#if (MODE_BSF)
{
int npos;

#define PUSH(a) stack[stack_used++]=(a)
#define POP(a)  (a)=stack[--stack_used]

if (lattice[DROP_LOCATION]++==1) {
  PUSH(DROP_LOCATION);
  //size++;
    while(stack_used) {
      size++;
      POP(curr_pos);
      do {

	lattice[curr_pos]-=2;
	npos=curr_pos+ ( (new_rand()!=(int)0) ? 1 : -1);
	if ((npos>=0) && (npos<LENGTH)) {
	  if (lattice[npos]++==1) {PUSH(npos);}
	}
//rand()>RAND_MAX/2
//new_rand()==0
        npos=curr_pos+ ( (new_rand()!=(int)0) ? 1 : -1);
	if ((npos>=0) && (npos<LENGTH)) {
	  if (lattice[npos]++==1) {PUSH(npos);}
	}


        
      } while (lattice[curr_pos]>1);
    }
  }
}
#endif

//printf("size is %i\n", size);
MOMENTS(size,size);
} /* end of iterations loop */
MOMENTS_OUT(size);

} /* chunk */
postamble();
}
示例#12
0
static void X6502_RunDebug(int32 cycles)
{
	#define RdMem RdMemHook
	#define WrMem WrMemHook
        #define ADDBT(to) NESDBG_AddBranchTrace(old_PC, to, 0)

        if(PAL)
         cycles*=15;          // 15*4=60
        else
         cycles*=16;          // 16*4=64

        _count+=cycles;

	PenguinPower:
        while(_count>0)
        {
	 const uint16 old_PC = _PC;
         int32 temp;
         uint8 b1;

         if(_IRQlow && !X.cpoint) // Don't run IRQ stuff if we weren't here in a save state
         { 
          if(_IRQlow&MDFN_IQRESET)
          {
           _PC=RdMem(0xFFFC);
           _PC|=RdMem(0xFFFD)<<8;
	   NESDBG_AddBranchTrace(old_PC, _PC, 0xFFFC); //	   ADDBT(_PC);
           _jammed=0;
           _PI=_P=I_FLAG;
           _IRQlow&=~MDFN_IQRESET;
          }
          else if(_IRQlow&MDFN_IQNMI2)
          {
           _IRQlow&=~MDFN_IQNMI2; 
           _IRQlow|=MDFN_IQNMI;
          }
          else if(_IRQlow&MDFN_IQNMI)
          {
           if(!_jammed)
           {
            ADDCYC(7);
            PUSH(_PC>>8);
            PUSH(_PC);
            PUSH((_P&~B_FLAG)|(U_FLAG));
            _P|=I_FLAG; 
            _PC=RdMem(0xFFFA); 
            _PC|=RdMem(0xFFFB)<<8;
	    NESDBG_AddBranchTrace(old_PC, _PC, 0xFFFA); //    ADDBT(_PC);
            _IRQlow&=~MDFN_IQNMI;
           }
          }
          else 
          { 
           if(!(_PI&I_FLAG) && !_jammed)
           {
            ADDCYC(7);
            PUSH(_PC>>8);
            PUSH(_PC);
            PUSH((_P&~B_FLAG)|(U_FLAG));
            _P|=I_FLAG;
            _PC=RdMem(0xFFFE);
            _PC|=RdMem(0xFFFF)<<8;
	    NESDBG_AddBranchTrace(old_PC, _PC, 0xFFFE);	//ADDBT(_PC);
           }
          }
示例#13
0
文件: config.c 项目: ajdavis/mongo
/*
 * __config_next --
 *	Get the next config item in the string without processing the value.
 */
static int
__config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value)
{
	WT_CONFIG_ITEM *out;
	int utf8_remain;
	static const WT_CONFIG_ITEM true_value = {
		"", 0, 1, WT_CONFIG_ITEM_BOOL
	};

	/* Keys with no value default to true. */
	*value = true_value;

	out = key;
	utf8_remain = 0;
	key->len = 0;

	if (conf->go == NULL)
		conf->go = gostruct;

	while (conf->cur < conf->end) {
		switch (conf->go[*(const uint8_t *)conf->cur]) {
		case A_LOOP:
			break;

		case A_BAD:
			return (__config_err(
			    conf, "Unexpected character", EINVAL));

		case A_DOWN:
			if (conf->top == -1)
				return (__config_err(
				    conf, "Unbalanced brackets", EINVAL));
			--conf->depth;
			CAP(0);
			break;

		case A_UP:
			if (conf->top == -1)
				conf->top = 1;
			PUSH(0, WT_CONFIG_ITEM_STRUCT);
			++conf->depth;
			break;

		case A_VALUE:
			if (conf->depth == conf->top) {
				/*
				 * Special case: ':' is permitted in unquoted
				 * values.
				 */
				if (out == value && *conf->cur != ':')
					return (__config_err(conf,
					    "Value already complete", EINVAL));
				out = value;
			}
			break;

		case A_NEXT:
			/*
			 * If we're at the top level and we have a complete
			 * key (and optional value), we're done.
			 */
			if (conf->depth == conf->top && key->len > 0) {
				++conf->cur;
				return (0);
			} else
				break;

		case A_QDOWN:
			CAP(-1);
			conf->go = gostruct;
			break;

		case A_QUP:
			PUSH(1, WT_CONFIG_ITEM_STRING);
			conf->go = gostring;
			break;

		case A_ESC:
			conf->go = goesc;
			break;

		case A_UNESC:
			conf->go = gostring;
			break;

		case A_BARE:
			PUSH(0, WT_CONFIG_ITEM_ID);
			conf->go = gobare;
			break;

		case A_NUMBARE:
			PUSH(0, WT_CONFIG_ITEM_NUM);
			conf->go = gobare;
			break;

		case A_UNBARE:
			CAP(-1);
			conf->go = gostruct;
			continue;

		case A_UTF8_2:
			conf->go = goutf8_continue;
			utf8_remain = 1;
			break;

		case A_UTF8_3:
			conf->go = goutf8_continue;
			utf8_remain = 2;
			break;

		case A_UTF8_4:
			conf->go = goutf8_continue;
			utf8_remain = 3;
			break;

		case A_UTF_CONTINUE:
			if (!--utf8_remain)
				conf->go = gostring;
			break;
		}

		conf->cur++;
	}

	/* Might have a trailing key/value without a closing brace */
	if (conf->go == gobare) {
		CAP(-1);
		conf->go = gostruct;
	}

	/* Did we find something? */
	if (conf->depth <= conf->top && key->len > 0)
		return (0);

	/* We're either at the end of the string or we failed to parse. */
	if (conf->depth == 0)
		return (WT_NOTFOUND);

	return (__config_err(conf, "Unbalanced brackets", EINVAL));
}
示例#14
0
static void stack3(void)
{
    SP = S0;	// empty the stack

    PUSH(-1); PUSH(0); PUSH(237);
}
示例#15
0
void
_quicksort (void *const pbase, size_t total_elems, size_t size,
	    __compar_fn_t cmp)
{
  register char *base_ptr = (char *) pbase;

  /* Allocating SIZE bytes for a pivot buffer facilitates a better
     algorithm below since we can do comparisons directly on the pivot. */
  char *pivot_buffer = (char *) __alloca (size);
  const size_t max_thresh = MAX_THRESH * size;

  if (total_elems == 0)
    /* Avoid lossage with unsigned arithmetic below.  */
    return;

  if (total_elems > MAX_THRESH)
    {
      char *lo = base_ptr;
      char *hi = &lo[size * (total_elems - 1)];
      stack_node stack[STACK_SIZE];
      stack_node *top = stack + 1;

      while (STACK_NOT_EMPTY)
        {
          char *left_ptr;
          char *right_ptr;

	  char *pivot = pivot_buffer;

	  /* Select median value from among LO, MID, and HI. Rearrange
	     LO and HI so the three values are sorted. This lowers the
	     probability of picking a pathological pivot value and
	     skips a comparison for both the LEFT_PTR and RIGHT_PTR in
	     the while loops. */

	  char *mid = lo + size * ((hi - lo) / size >> 1);

	  if ((*cmp) ((void *) mid, (void *) lo) < 0)
	    SWAP (mid, lo, size);
	  if ((*cmp) ((void *) hi, (void *) mid) < 0)
	    SWAP (mid, hi, size);
	  else
	    goto jump_over;
	  if ((*cmp) ((void *) mid, (void *) lo) < 0)
	    SWAP (mid, lo, size);
	jump_over:;
	  memcpy (pivot, mid, size);
	  pivot = pivot_buffer;

	  left_ptr  = lo + size;
	  right_ptr = hi - size;

	  /* Here's the famous ``collapse the walls'' section of quicksort.
	     Gotta like those tight inner loops!  They are the main reason
	     that this algorithm runs much faster than others. */
	  do
	    {
	      while ((*cmp) ((void *) left_ptr, (void *) pivot) < 0)
		left_ptr += size;

	      while ((*cmp) ((void *) pivot, (void *) right_ptr) < 0)
		right_ptr -= size;

	      if (left_ptr < right_ptr)
		{
		  SWAP (left_ptr, right_ptr, size);
		  left_ptr += size;
		  right_ptr -= size;
		}
	      else if (left_ptr == right_ptr)
		{
		  left_ptr += size;
		  right_ptr -= size;
		  break;
		}
	    }
	  while (left_ptr <= right_ptr);

          /* Set up pointers for next iteration.  First determine whether
             left and right partitions are below the threshold size.  If so,
             ignore one or both.  Otherwise, push the larger partition's
             bounds on the stack and continue sorting the smaller one. */

          if ((size_t) (right_ptr - lo) <= max_thresh)
            {
              if ((size_t) (hi - left_ptr) <= max_thresh)
		/* Ignore both small partitions. */
                POP (lo, hi);
              else
		/* Ignore small left partition. */
                lo = left_ptr;
            }
          else if ((size_t) (hi - left_ptr) <= max_thresh)
	    /* Ignore small right partition. */
            hi = right_ptr;
          else if ((right_ptr - lo) > (hi - left_ptr))
            {
	      /* Push larger left partition indices. */
              PUSH (lo, right_ptr);
              lo = left_ptr;
            }
          else
            {
	      /* Push larger right partition indices. */
              PUSH (left_ptr, hi);
              hi = right_ptr;
            }
        }
    }
示例#16
0
文件: elf_load.c 项目: hoyori/panda
int
elf_load(struct sys_info *info, ihandle_t dev, const char *cmdline, void **boot_notes)
{
    Elf_ehdr ehdr;
    Elf_phdr *phdr = NULL;
    unsigned long checksum_offset, file_size;
    unsigned short checksum = 0;
    int retval = -1;
    unsigned int offset;

    image_name = image_version = NULL;

    /* Mark the saved-program-state as invalid */
    feval("0 state-valid !");

    fd = open_ih(dev);
    if (fd == -1) {
        goto out;
    }

    offset = find_elf(&ehdr);
    if (!offset) {
        retval = LOADER_NOT_SUPPORT;
        goto out;
    }

#if DEBUG
    printk("ELF header:\n");
    printk(" ehdr.e_type    = %d\n", (int)ehdr.e_type);
    printk(" ehdr.e_machine = %d\n", (int)ehdr.e_machine);
    printk(" ehdr.e_version = %d\n", (int)ehdr.e_version);
    printk(" ehdr.e_entry   = 0x%08x\n", (int)ehdr.e_entry);
    printk(" ehdr.e_phoff   = 0x%08x\n", (int)ehdr.e_phoff);
    printk(" ehdr.e_shoff   = 0x%08x\n", (int)ehdr.e_shoff);
    printk(" ehdr.e_flags   = %d\n", (int)ehdr.e_flags);
    printk(" ehdr.e_ehsize  = 0x%08x\n", (int)ehdr.e_ehsize);
    printk(" ehdr.e_phentsize = 0x%08x\n", (int)ehdr.e_phentsize);
    printk(" ehdr.e_phnum   = %d\n", (int)ehdr.e_phnum);
#endif

    if (ehdr.e_phnum > MAX_HEADERS) {
        printk ("elfload: too many program headers (MAX_HEADERS)\n");
        retval = 0;
        goto out;
    }

    phdr = elf_readhdrs(offset, &ehdr);
    if (!phdr)
        goto out;

    if (!check_mem_ranges(info, phdr, ehdr.e_phnum))
        goto out;

    checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum, offset);

    printf("Loading %s", image_name ? image_name : "image");
    if (image_version)
        printf(" version %s", image_version);
    printf("...\n");

    if (!load_segments(phdr, ehdr.e_phnum, checksum_offset, offset, &file_size))
        goto out;

    if (checksum_offset) {
        if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum))
            goto out;
    }

    /* If we are attempting an ELF boot image, we pass a non-NULL pointer
       into boot_notes and mark the image as elf-boot rather than standard
       ELF */
    if (boot_notes) {
        *boot_notes = (void *)virt_to_phys(build_boot_notes(info, cmdline));
        feval("elf-boot saved-program-state >sps.file-type !");
    } else {
        feval("elf saved-program-state >sps.file-type !");
    }

    //debug("current time: %lu\n", currticks());

    debug("entry point is " FMT_elf "\n", addr_fixup(ehdr.e_entry));

    // Initialise saved-program-state
    PUSH(addr_fixup(ehdr.e_entry));
    feval("saved-program-state >sps.entry !");
    PUSH(file_size);
    feval("saved-program-state >sps.file-size !");

    feval("-1 state-valid !");

out:
    close_io(fd);
    if (phdr)
        free(phdr);
    if (image_name)
        free(image_name);
    if (image_version)
        free(image_version);
    return retval;
}
示例#17
0
LinearFunc SamplerJitCache::CompileLinear(const SamplerID &id) {
	_assert_msg_(G3D, id.linear, "Linear should be set on sampler id");
	BeginWrite();

	// We'll first write the nearest sampler, which we will CALL.
	// This may differ slightly based on the "linear" flag.
	const u8 *nearest = AlignCode16();

	if (!Jit_ReadTextureFormat(id)) {
		EndWrite();
		SetCodePtr(const_cast<u8 *>(nearest));
		return nullptr;
	}

	RET();

	// Now the actual linear func, which is exposed externally.
	const u8 *start = AlignCode16();

	// NOTE: This doesn't use the general register mapping.
	// POSIX: arg1=uptr, arg2=vptr, arg3=frac_u, arg4=frac_v, arg5=src, arg6=bufw, stack+8=level
	// Win64: arg1=uptr, arg2=vptr, arg3=frac_u, arg4=frac_v, stack+40=src, stack+48=bufw, stack+56=level
	//
	// We map these to nearest CALLs, with order: u, v, src, bufw, level

	// Let's start by saving a bunch of registers.
	PUSH(R15);
	PUSH(R14);
	PUSH(R13);
	PUSH(R12);
	// Won't need frac_u/frac_v for a while.
	PUSH(arg4Reg);
	PUSH(arg3Reg);
	// Extra space to restore alignment and save resultReg for lerp.
	// TODO: Maybe use XMMs instead?
	SUB(64, R(RSP), Imm8(24));

	MOV(64, R(R12), R(arg1Reg));
	MOV(64, R(R13), R(arg2Reg));
#ifdef _WIN32
	// First arg now starts at 24 (extra space) + 48 (pushed stack) + 8 (ret address) + 32 (shadow space)
	const int argOffset = 24 + 48 + 8 + 32;
	MOV(64, R(R14), MDisp(RSP, argOffset));
	MOV(32, R(R15), MDisp(RSP, argOffset + 8));
	// level is at argOffset + 16.
#else
	MOV(64, R(R14), R(arg5Reg));
	MOV(32, R(R15), R(arg6Reg));
	// level is at 24 + 48 + 8.
#endif

	// Early exit on !srcPtr.
	FixupBranch zeroSrc;
	if (id.hasInvalidPtr) {
		CMP(PTRBITS, R(R14), Imm8(0));
		FixupBranch nonZeroSrc = J_CC(CC_NZ);
		XOR(32, R(RAX), R(RAX));
		zeroSrc = J(true);
		SetJumpTarget(nonZeroSrc);
	}

	// At this point:
	// R12=uptr, R13=vptr, stack+24=frac_u, stack+32=frac_v, R14=src, R15=bufw, stack+X=level

	auto doNearestCall = [&](int off) {
		MOV(32, R(uReg), MDisp(R12, off));
		MOV(32, R(vReg), MDisp(R13, off));
		MOV(64, R(srcReg), R(R14));
		MOV(32, R(bufwReg), R(R15));
		// Leave level, we just always load from RAM.  Separate CLUTs is uncommon.

		CALL(nearest);
		MOV(32, MDisp(RSP, off), R(resultReg));
	};

	doNearestCall(0);
	doNearestCall(4);
	doNearestCall(8);
	doNearestCall(12);

	// Convert TL, TR, BL, BR to floats for easier blending.
	if (!cpu_info.bSSE4_1) {
		PXOR(XMM0, R(XMM0));
	}

	MOVD_xmm(fpScratchReg1, MDisp(RSP, 0));
	MOVD_xmm(fpScratchReg2, MDisp(RSP, 4));
	MOVD_xmm(fpScratchReg3, MDisp(RSP, 8));
	MOVD_xmm(fpScratchReg4, MDisp(RSP, 12));

	if (cpu_info.bSSE4_1) {
		PMOVZXBD(fpScratchReg1, R(fpScratchReg1));
		PMOVZXBD(fpScratchReg2, R(fpScratchReg2));
		PMOVZXBD(fpScratchReg3, R(fpScratchReg3));
		PMOVZXBD(fpScratchReg4, R(fpScratchReg4));
	} else {
		PUNPCKLBW(fpScratchReg1, R(XMM0));
		PUNPCKLBW(fpScratchReg2, R(XMM0));
		PUNPCKLBW(fpScratchReg3, R(XMM0));
		PUNPCKLBW(fpScratchReg4, R(XMM0));
		PUNPCKLWD(fpScratchReg1, R(XMM0));
		PUNPCKLWD(fpScratchReg2, R(XMM0));
		PUNPCKLWD(fpScratchReg3, R(XMM0));
		PUNPCKLWD(fpScratchReg4, R(XMM0));
	}
	CVTDQ2PS(fpScratchReg1, R(fpScratchReg1));
	CVTDQ2PS(fpScratchReg2, R(fpScratchReg2));
	CVTDQ2PS(fpScratchReg3, R(fpScratchReg3));
	CVTDQ2PS(fpScratchReg4, R(fpScratchReg4));

	// Okay, now multiply the R sides by frac_u, and L by (256 - frac_u)...
	MOVD_xmm(fpScratchReg5, MDisp(RSP, 24));
	CVTDQ2PS(fpScratchReg5, R(fpScratchReg5));
	SHUFPS(fpScratchReg5, R(fpScratchReg5), _MM_SHUFFLE(0, 0, 0, 0));
	if (RipAccessible(by256)) {
		MULPS(fpScratchReg5, M(by256));  // rip accessible
	} else {
		Crash();  // TODO
	}
	MOVAPS(XMM0, M(ones));
	SUBPS(XMM0, R(fpScratchReg5));

	MULPS(fpScratchReg1, R(XMM0));
	MULPS(fpScratchReg2, R(fpScratchReg5));
	MULPS(fpScratchReg3, R(XMM0));
	MULPS(fpScratchReg4, R(fpScratchReg5));

	// Now set top=fpScratchReg1, bottom=fpScratchReg3.
	ADDPS(fpScratchReg1, R(fpScratchReg2));
	ADDPS(fpScratchReg3, R(fpScratchReg4));

	// Next, time for frac_v.
	MOVD_xmm(fpScratchReg5, MDisp(RSP, 32));
	CVTDQ2PS(fpScratchReg5, R(fpScratchReg5));
	SHUFPS(fpScratchReg5, R(fpScratchReg5), _MM_SHUFFLE(0, 0, 0, 0));
	MULPS(fpScratchReg5, M(by256));
	MOVAPS(XMM0, M(ones));
	SUBPS(XMM0, R(fpScratchReg5));

	MULPS(fpScratchReg1, R(XMM0));
	MULPS(fpScratchReg3, R(fpScratchReg5));

	// Still at the 255 scale, now we're interpolated.
	ADDPS(fpScratchReg1, R(fpScratchReg3));

	// Time to convert back to a single 32 bit value.
	CVTPS2DQ(fpScratchReg1, R(fpScratchReg1));
	PACKSSDW(fpScratchReg1, R(fpScratchReg1));
	PACKUSWB(fpScratchReg1, R(fpScratchReg1));
	MOVD_xmm(R(resultReg), fpScratchReg1);

	if (id.hasInvalidPtr) {
		SetJumpTarget(zeroSrc);
	}

	ADD(64, R(RSP), Imm8(24));
	POP(arg3Reg);
	POP(arg4Reg);
	POP(R12);
	POP(R13);
	POP(R14);
	POP(R15);

	RET();

	EndWrite();
	return (LinearFunc)start;
}
示例#18
0
文件: elf_load.c 项目: hoyori/panda
void
elf_init_program(void)
{
    char *base;
    int i;
    Elf_ehdr *ehdr;
    Elf_phdr *phdr;
    size_t size, total_size = 0;
    char *addr;
    uintptr_t tmp;

    /* TODO: manage ELF notes section */
    feval("0 state-valid !");
    feval("load-base");
    base = (char*)cell2pointer(POP());

    ehdr = (Elf_ehdr *)base;

    if (!is_elf(ehdr)) {
        debug("Not a valid ELF memory image\n");
        return;
    }

    phdr = (Elf_phdr *)(base + ehdr->e_phoff);

    for (i = 0; i < ehdr->e_phnum; i++) {

#if DEBUG
        debug("filesz: %08lX memsz: %08lX p_offset: %08lX "
              "p_vaddr %08lX\n",
              (unsigned long)phdr[i].p_filesz, (unsigned long)phdr[i].p_memsz,
              (unsigned long)phdr[i].p_offset, (unsigned long)phdr[i].p_vaddr );
#endif

        size = MIN(phdr[i].p_filesz, phdr[i].p_memsz);
        if (!size)
            continue;
#if !defined(CONFIG_SPARC32) && !defined(CONFIG_X86)
        if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) {
            printk("Ignoring failed claim for va %lx memsz %lx!\n",
                   (unsigned long)phdr[i].p_vaddr,
                   (unsigned long)phdr[i].p_memsz);
        }
#endif
        /* Workaround for archs where sizeof(int) != pointer size */
        tmp = phdr[i].p_vaddr;
        addr = (char *)tmp;

        memcpy(addr, base + phdr[i].p_offset, size);

        total_size += size;

#ifdef CONFIG_PPC
        flush_icache_range( addr, addr + size );
#endif
    }

    // Initialise saved-program-state
    PUSH(ehdr->e_entry);
    feval("saved-program-state >sps.entry !");
    PUSH(total_size);
    feval("saved-program-state >sps.file-size !");
    feval("elf saved-program-state >sps.file-type !");

    feval("-1 state-valid !");
}
示例#19
0
void
xcoff_init_program(void)
{
	char *base;
	COFF_filehdr_t *fhdr;
	COFF_aouthdr_t *ahdr;
	COFF_scnhdr_t *shdr;
	uint32_t offset;
	size_t total_size = 0;
	int i;

	feval("load-base");
	base = (char*)cell2pointer(POP());

	fhdr = (COFF_filehdr_t*)base;

	/* Is it an XCOFF file ? */
	if (!is_xcoff(fhdr)) {
		DPRINTF("Not a XCOFF file %02x\n", fhdr->f_magic);
		return;
	}

	/* Is it executable ? */
	if (fhdr->f_magic != 0x01DF &&
	    (fhdr->f_flags & COFF_F_EXEC) == 0) {
		DPRINTF("Not an executable XCOFF file %02x\n", fhdr->f_flags);
		return;
	}

	/* Optional header is a.out ? */
	if (fhdr->f_opthdr != sizeof(COFF_aouthdr_t)) {
		DPRINTF("AOUT optional error size mismatch in XCOFF file\n");
		return;
	}

        ahdr = (COFF_aouthdr_t*)(base + sizeof(COFF_filehdr_t));

	/* check a.out magic number */
	if (ahdr->magic != AOUT_MAGIC) {
		DPRINTF("Invalid AOUT optional header\n");
		return;
	}

	offset = sizeof(COFF_filehdr_t) + sizeof(COFF_aouthdr_t);

	DPRINTF("XCOFF file with %d sections\n", fhdr->f_nscns);

	for (i = 0; i < fhdr->f_nscns; i++) {

		DPRINTF("Read header at offset %0x\n", offset);

		shdr = (COFF_scnhdr_t*)(base + offset);

		DPRINTF("Initializing '%s' section from %0x %0x to %0x (%0x)\n",
			shdr->s_name, offset, shdr->s_scnptr,
			shdr->s_vaddr, shdr->s_size);

		if (strcmp(shdr->s_name, ".text") == 0) {

			memcpy((char*)(uintptr_t)shdr->s_vaddr, base + shdr->s_scnptr,
			       shdr->s_size);
			total_size += shdr->s_size;
#ifdef CONFIG_PPC
			flush_icache_range((char*)(uintptr_t)shdr->s_vaddr,
					 (char*)(uintptr_t)(shdr->s_vaddr + shdr->s_size));
#endif
		} else if (strcmp(shdr->s_name, ".data") == 0) {

			memcpy((char*)(uintptr_t)shdr->s_vaddr, base + shdr->s_scnptr,
			       shdr->s_size);
			total_size += shdr->s_size;

		} else if (strcmp(shdr->s_name, ".bss") == 0) {

			memset((void *)(uintptr_t)shdr->s_vaddr, 0, shdr->s_size);
			total_size += shdr->s_size;
		} else {
			DPRINTF("    Skip '%s' section\n", shdr->s_name);
		}
		offset += sizeof(COFF_scnhdr_t);
	}

	DPRINTF("XCOFF entry point: %x\n", *(uint32_t*)ahdr->entry);

	// Initialise load-state
	PUSH(*(uint32_t*)(uintptr_t)ahdr->entry);
	feval("load-state >ls.entry !");
	feval("xcoff load-state >ls.file-type !");

	arch_init_program();
	
	feval("-1 state-valid !");
}
示例#20
0
文件: api.c 项目: 44670/Project_CTR
yaml_document_start_event_initialize(yaml_event_t *event,
        yaml_titleVersion_directive_t *titleVersion_directive,
        yaml_tag_directive_t *tag_directives_start,
        yaml_tag_directive_t *tag_directives_end,
        int implicit)
{
    struct {
        yaml_error_type_t error;
    } context;
    yaml_mark_t mark = { 0, 0, 0 };
    yaml_titleVersion_directive_t *titleVersion_directive_copy = NULL;
    struct {
        yaml_tag_directive_t *start;
        yaml_tag_directive_t *end;
        yaml_tag_directive_t *top;
    } tag_directives_copy = { NULL, NULL, NULL };
    yaml_tag_directive_t value = { NULL, NULL };

    assert(event);          /* Non-NULL event object is expected. */
    assert((tag_directives_start && tag_directives_end) ||
            (tag_directives_start == tag_directives_end));
                            /* Valid tag directives are expected. */

    if (titleVersion_directive) {
        titleVersion_directive_copy = yaml_malloc(sizeof(yaml_titleVersion_directive_t));
        if (!titleVersion_directive_copy) goto error;
        titleVersion_directive_copy->major = titleVersion_directive->major;
        titleVersion_directive_copy->minor = titleVersion_directive->minor;
    }

    if (tag_directives_start != tag_directives_end) {
        yaml_tag_directive_t *tag_directive;
        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
            goto error;
        for (tag_directive = tag_directives_start;
                tag_directive != tag_directives_end; tag_directive ++) {
            assert(tag_directive->handle);
            assert(tag_directive->prefix);
            if (!yaml_check_utf8(tag_directive->handle,
                        strlen((char *)tag_directive->handle)))
                goto error;
            if (!yaml_check_utf8(tag_directive->prefix,
                        strlen((char *)tag_directive->prefix)))
                goto error;
            value.handle = yaml_strdup(tag_directive->handle);
            value.prefix = yaml_strdup(tag_directive->prefix);
            if (!value.handle || !value.prefix) goto error;
            if (!PUSH(&context, tag_directives_copy, value))
                goto error;
            value.handle = NULL;
            value.prefix = NULL;
        }
    }

    DOCUMENT_START_EVENT_INIT(*event, titleVersion_directive_copy,
            tag_directives_copy.start, tag_directives_copy.top,
            implicit, mark, mark);

    return 1;

error:
    yaml_free(titleVersion_directive_copy);
    while (!STACK_EMPTY(context, tag_directives_copy)) {
        yaml_tag_directive_t value = POP(context, tag_directives_copy);
        yaml_free(value.handle);
        yaml_free(value.prefix);
    }
    STACK_DEL(context, tag_directives_copy);
    yaml_free(value.handle);
    yaml_free(value.prefix);

    return 0;
}
示例#21
0
VALUE
rb_str_format(int argc, const VALUE *argv, VALUE fmt)
{
    rb_encoding *enc;
    const char *p, *end;
    char *buf;
    long blen, bsiz;
    VALUE result;

    long scanned = 0;
    int coderange = ENC_CODERANGE_7BIT;
    int width, prec, flags = FNONE;
    int nextarg = 1;
    int posarg = 0;
    int tainted = 0;
    VALUE nextvalue;
    VALUE tmp;
    VALUE str;
    volatile VALUE hash = Qundef;

#define CHECK_FOR_WIDTH(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "width given twice");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "width after precision"); \
    }
#define CHECK_FOR_FLAGS(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "flag after width");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "flag after precision"); \
    }

    ++argc;
    --argv;
    if (OBJ_TAINTED(fmt)) tainted = 1;
    StringValue(fmt);
    enc = rb_enc_get(fmt);
    fmt = rb_str_new4(fmt);
    p = RSTRING_PTR(fmt);
    end = p + RSTRING_LEN(fmt);
    blen = 0;
    bsiz = 120;
    result = rb_str_buf_new(bsiz);
    rb_enc_copy(result, fmt);
    buf = RSTRING_PTR(result);
    memset(buf, 0, bsiz);
    ENC_CODERANGE_SET(result, coderange);

    for (; p < end; p++) {
	const char *t;
	int n;
	ID id = 0;

	for (t = p; t < end && *t != '%'; t++) ;
	PUSH(p, t - p);
	if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
	    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &coderange);
	    ENC_CODERANGE_SET(result, coderange);
	}
	if (t >= end) {
	    /* end of fmt string */
	    goto sprint_exit;
	}
	p = t + 1;		/* skip `%' */

	width = prec = -1;
	nextvalue = Qundef;
      retry:
	switch (*p) {
	  default:
	    if (rb_enc_isprint(*p, enc))
		rb_raise(rb_eArgError, "malformed format string - %%%c", *p);
	    else
		rb_raise(rb_eArgError, "malformed format string");
	    break;

	  case ' ':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSPACE;
	    p++;
	    goto retry;

	  case '#':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSHARP;
	    p++;
	    goto retry;

	  case '+':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FPLUS;
	    p++;
	    goto retry;

	  case '-':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FMINUS;
	    p++;
	    goto retry;

	  case '0':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FZERO;
	    p++;
	    goto retry;

	  case '1': case '2': case '3': case '4':
	  case '5': case '6': case '7': case '8': case '9':
	    n = 0;
	    GETNUM(n, width);
	    if (*p == '$') {
		if (nextvalue != Qundef) {
		    rb_raise(rb_eArgError, "value given twice - %d$", n);
		}
		nextvalue = GETPOSARG(n);
		p++;
		goto retry;
	    }
	    CHECK_FOR_WIDTH(flags);
	    width = n;
	    flags |= FWIDTH;
	    goto retry;

	  case '<':
	  case '{':
	    {
		const char *start = p;
		char term = (*p == '<') ? '>' : '}';
		int len;

		for (; p < end && *p != term; ) {
		    p += rb_enc_mbclen(p, end, enc);
		}
		if (p >= end) {
		    rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
		}
#if SIZEOF_INT < SIZEOF_SIZE_T
		if ((size_t)(p - start) >= INT_MAX) {
		    const int message_limit = 20;
		    len = (int)(rb_enc_right_char_head(start, start + message_limit, p, enc) - start);
		    rb_enc_raise(enc, rb_eArgError,
				 "too long name (%"PRIdSIZE" bytes) - %.*s...%c",
				 (size_t)(p - start - 2), len, start, term);
		}
#endif
		len = (int)(p - start + 1); /* including parenthesis */
		if (id) {
		    rb_enc_raise(enc, rb_eArgError, "named%.*s after <%s>",
				 len, start, rb_id2name(id));
		}
		nextvalue = GETNAMEARG((id = rb_check_id_cstr(start + 1,
							      len - 2 /* without parenthesis */,
							      enc),
					ID2SYM(id)),
				       start, len, enc);
		if (nextvalue == Qundef) {
		    rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start);
		}
		if (term == '}') goto format_s;
		p++;
		goto retry;
	    }

	  case '*':
	    CHECK_FOR_WIDTH(flags);
	    flags |= FWIDTH;
	    GETASTER(width);
	    if (width < 0) {
		flags |= FMINUS;
		width = -width;
	    }
	    p++;
	    goto retry;

	  case '.':
	    if (flags & FPREC0) {
		rb_raise(rb_eArgError, "precision given twice");
	    }
	    flags |= FPREC|FPREC0;

	    prec = 0;
	    p++;
	    if (*p == '*') {
		GETASTER(prec);
		if (prec < 0) {	/* ignore negative precision */
		    flags &= ~FPREC;
		}
		p++;
		goto retry;
	    }

	    GETNUM(prec, precision);
	    goto retry;

	  case '\n':
	  case '\0':
	    p--;
	  case '%':
	    if (flags != FNONE) {
		rb_raise(rb_eArgError, "invalid format character - %%");
	    }
	    PUSH("%", 1);
	    break;

	  case 'c':
	    {
		VALUE val = GETARG();
		VALUE tmp;
		unsigned int c;
		int n;

		tmp = rb_check_string_type(val);
		if (!NIL_P(tmp)) {
		    if (rb_enc_strlen(RSTRING_PTR(tmp),RSTRING_END(tmp),enc) != 1) {
			rb_raise(rb_eArgError, "%%c requires a character");
		    }
		    c = rb_enc_codepoint_len(RSTRING_PTR(tmp), RSTRING_END(tmp), &n, enc);
		    RB_GC_GUARD(tmp);
		}
		else {
		    c = NUM2INT(val);
		    n = rb_enc_codelen(c, enc);
		}
		if (n <= 0) {
		    rb_raise(rb_eArgError, "invalid character");
		}
		if (!(flags & FWIDTH)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
		else if ((flags & FMINUS)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		    FILL(' ', width-1);
		}
		else {
		    FILL(' ', width-1);
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
	    }
	    break;

	  case 's':
	  case 'p':
	  format_s:
	    {
		VALUE arg = GETARG();
		long len, slen;

		if (*p == 'p') arg = rb_inspect(arg);
		str = rb_obj_as_string(arg);
		if (OBJ_TAINTED(str)) tainted = 1;
		len = RSTRING_LEN(str);
		rb_str_set_len(result, blen);
		if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
		    int cr = coderange;
		    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr);
		    ENC_CODERANGE_SET(result,
				      (cr == ENC_CODERANGE_UNKNOWN ?
				       ENC_CODERANGE_BROKEN : (coderange = cr)));
		}
		enc = rb_enc_check(result, str);
		if (flags&(FPREC|FWIDTH)) {
		    slen = rb_enc_strlen(RSTRING_PTR(str),RSTRING_END(str),enc);
		    if (slen < 0) {
			rb_raise(rb_eArgError, "invalid mbstring sequence");
		    }
		    if ((flags&FPREC) && (prec < slen)) {
			char *p = rb_enc_nth(RSTRING_PTR(str), RSTRING_END(str),
					     prec, enc);
			slen = prec;
			len = p - RSTRING_PTR(str);
		    }
		    /* need to adjust multi-byte string pos */
		    if ((flags&FWIDTH) && (width > slen)) {
			width -= (int)slen;
			if (!(flags&FMINUS)) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			CHECK(len);
			memcpy(&buf[blen], RSTRING_PTR(str), len);
			RB_GC_GUARD(str);
			blen += len;
			if (flags&FMINUS) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			rb_enc_associate(result, enc);
			break;
		    }
		}
		PUSH(RSTRING_PTR(str), len);
		RB_GC_GUARD(str);
		rb_enc_associate(result, enc);
	    }
	    break;

	  case 'd':
	  case 'i':
	  case 'o':
	  case 'x':
	  case 'X':
	  case 'b':
	  case 'B':
	  case 'u':
	    {
		volatile VALUE val = GETARG();
		char fbuf[32], nbuf[64], *s;
		const char *prefix = 0;
		int sign = 0, dots = 0;
		char sc = 0;
		long v = 0;
		int base, bignum = 0;
		int len;

		switch (*p) {
		  case 'd':
		  case 'i':
		  case 'u':
		    sign = 1; break;
		  case 'o':
		  case 'x':
		  case 'X':
		  case 'b':
		  case 'B':
		    if (flags&(FPLUS|FSPACE)) sign = 1;
		    break;
		}
		if (flags & FSHARP) {
		    switch (*p) {
		      case 'o':
			prefix = "0"; break;
		      case 'x':
			prefix = "0x"; break;
		      case 'X':
			prefix = "0X"; break;
		      case 'b':
			prefix = "0b"; break;
		      case 'B':
			prefix = "0B"; break;
		    }
		}

	      bin_retry:
		switch (TYPE(val)) {
		  case T_FLOAT:
		    if (FIXABLE(RFLOAT_VALUE(val))) {
			val = LONG2FIX((long)RFLOAT_VALUE(val));
			goto bin_retry;
		    }
		    val = rb_dbl2big(RFLOAT_VALUE(val));
		    if (FIXNUM_P(val)) goto bin_retry;
		    bignum = 1;
		    break;
		  case T_STRING:
		    val = rb_str_to_inum(val, 0, TRUE);
		    goto bin_retry;
		  case T_BIGNUM:
		    bignum = 1;
		    break;
		  case T_FIXNUM:
		    v = FIX2LONG(val);
		    break;
		  default:
		    val = rb_Integer(val);
		    goto bin_retry;
		}

		switch (*p) {
		  case 'o':
		    base = 8; break;
		  case 'x':
		  case 'X':
		    base = 16; break;
		  case 'b':
		  case 'B':
		    base = 2; break;
		  case 'u':
		  case 'd':
		  case 'i':
		  default:
		    base = 10; break;
		}

		if (!bignum) {
		    if (base == 2) {
			val = rb_int2big(v);
			goto bin_retry;
		    }
		    if (sign) {
			char c = *p;
			if (c == 'i') c = 'd'; /* %d and %i are identical */
			if (v < 0) {
			    v = -v;
			    sc = '-';
			    width--;
			}
			else if (flags & FPLUS) {
			    sc = '+';
			    width--;
			}
			else if (flags & FSPACE) {
			    sc = ' ';
			    width--;
			}
			snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
			snprintf(nbuf, sizeof(nbuf), fbuf, v);
			s = nbuf;
		    }
		    else {
			s = nbuf;
			if (v < 0) {
			    dots = 1;
			}
			snprintf(fbuf, sizeof(fbuf), "%%l%c", *p == 'X' ? 'x' : *p);
			snprintf(++s, sizeof(nbuf) - 1, fbuf, v);
			if (v < 0) {
			    char d = 0;

			    s = remove_sign_bits(s, base);
			    switch (base) {
			      case 16:
				d = 'f'; break;
			      case 8:
				d = '7'; break;
			    }
			    if (d && *s != d) {
				*--s = d;
			    }
			}
		    }
		    len = (int)strlen(s);
		}
		else {
		    if (sign) {
			tmp = rb_big2str(val, base);
			s = RSTRING_PTR(tmp);
			if (s[0] == '-') {
			    s++;
			    sc = '-';
			    width--;
			}
			else if (flags & FPLUS) {
			    sc = '+';
			    width--;
			}
			else if (flags & FSPACE) {
			    sc = ' ';
			    width--;
			}
		    }
		    else {
			if (!RBIGNUM_SIGN(val)) {
			    val = rb_big_clone(val);
			    rb_big_2comp(val);
			}
			tmp = rb_big2str0(val, base, RBIGNUM_SIGN(val));
			s = RSTRING_PTR(tmp);
			if (*s == '-') {
			    dots = 1;
			    if (base == 10) {
				rb_warning("negative number for %%u specifier");
			    }
			    s = remove_sign_bits(++s, base);
			    switch (base) {
			      case 16:
				if (s[0] != 'f') *--s = 'f'; break;
			      case 8:
				if (s[0] != '7') *--s = '7'; break;
			      case 2:
				if (s[0] != '1') *--s = '1'; break;
			    }
			}
		    }
		    len = rb_long2int(RSTRING_END(tmp) - s);
		}

		if (dots) {
		    prec -= 2;
		    width -= 2;
		}

		if (*p == 'X') {
		    char *pp = s;
		    int c;
		    while ((c = (int)(unsigned char)*pp) != 0) {
			*pp = rb_enc_toupper(c, enc);
			pp++;
		    }
		}
		if (prefix && !prefix[1]) { /* octal */
		    if (dots) {
			prefix = 0;
		    }
		    else if (len == 1 && *s == '0') {
			len = 0;
			if (flags & FPREC) prec--;
		    }
		    else if ((flags & FPREC) && (prec > len)) {
			prefix = 0;
		    }
		}
		else if (len == 1 && *s == '0') {
		    prefix = 0;
		}
		if (prefix) {
		    width -= (int)strlen(prefix);
		}
		if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
		    prec = width;
		    width = 0;
		}
		else {
		    if (prec < len) {
			if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
			prec = len;
		    }
		    width -= prec;
		}
		if (!(flags&FMINUS)) {
		    CHECK(width);
		    while (width-- > 0) {
			buf[blen++] = ' ';
		    }
		}
		if (sc) PUSH(&sc, 1);
		if (prefix) {
		    int plen = (int)strlen(prefix);
		    PUSH(prefix, plen);
		}
		CHECK(prec - len);
		if (dots) PUSH("..", 2);
		if (!bignum && v < 0) {
		    char c = sign_bits(base, p);
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		else if ((flags & (FMINUS|FPREC)) != FMINUS) {
		    char c;

		    if (!sign && bignum && !RBIGNUM_SIGN(val))
			c = sign_bits(base, p);
		    else
			c = '0';
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		PUSH(s, len);
		RB_GC_GUARD(tmp);
		CHECK(width);
		while (width-- > 0) {
		    buf[blen++] = ' ';
		}
	    }
	    break;

	  case 'f':
	  case 'g':
	  case 'G':
	  case 'e':
	  case 'E':
	  case 'a':
	  case 'A':
	    {
		VALUE val = GETARG();
		double fval;
		int i, need = 6;
		char fbuf[32];

		fval = RFLOAT_VALUE(rb_Float(val));
		if (isnan(fval) || isinf(fval)) {
		    const char *expr;

		    if (isnan(fval)) {
			expr = "NaN";
		    }
		    else {
			expr = "Inf";
		    }
		    need = (int)strlen(expr);
		    if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
			need++;
		    if ((flags & FWIDTH) && need < width)
			need = width;

		    CHECK(need + 1);
		    snprintf(&buf[blen], need + 1, "%*s", need, "");
		    if (flags & FMINUS) {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen++] = '-';
			else if (flags & FPLUS)
			    buf[blen++] = '+';
			else if (flags & FSPACE)
			    blen++;
			memcpy(&buf[blen], expr, strlen(expr));
		    }
		    else {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen + need - strlen(expr) - 1] = '-';
			else if (flags & FPLUS)
			    buf[blen + need - strlen(expr) - 1] = '+';
			else if ((flags & FSPACE) && need > width)
			    blen++;
			memcpy(&buf[blen + need - strlen(expr)], expr,
			       strlen(expr));
		    }
		    blen += strlen(&buf[blen]);
		    break;
		}

		fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
		need = 0;
		if (*p != 'e' && *p != 'E') {
		    i = INT_MIN;
		    frexp(fval, &i);
		    if (i > 0)
			need = BIT_DIGITS(i);
		}
		need += (flags&FPREC) ? prec : 6;
		if ((flags&FWIDTH) && need < width)
		    need = width;
		need += 20;

		CHECK(need);
		snprintf(&buf[blen], need, fbuf, fval);
		blen += strlen(&buf[blen]);
	    }
	    break;
	}
	flags = FNONE;
    }

  sprint_exit:
    RB_GC_GUARD(fmt);
    /* XXX - We cannot validate the number of arguments if (digit)$ style used.
     */
    if (posarg >= 0 && nextarg < argc) {
	const char *mesg = "too many arguments for format string";
	if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg);
	if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
    }
    rb_str_resize(result, blen);

    if (tainted) OBJ_TAINT(result);
    return result;
}
示例#22
0
int js0n (unsigned char *js, unsigned int len, unsigned short *out) {

  unsigned short prev = 0;
  unsigned char *cur, *end;
  int depth       = 0;
  int utf8_remain = 0;

  static const void *gostruct[] = {
    [0   ... 8]   = &&l_bad,
    [11  ... 12]  = &&l_bad,
    [14  ... 31]  = &&l_bad,
    [33]          = &&l_bad,
    [35  ... 43]  = &&l_bad,
    [46  ... 47]  = &&l_bad,
    [59  ... 90]  = &&l_bad,
    [92]          = &&l_bad,
    [94  ... 101] = &&l_bad,
    [103 ... 109] = &&l_bad,
    [111 ... 115] = &&l_bad,
    [117 ... 122] = &&l_bad,
    [124]         = &&l_bad,
    [126 ... 255] = &&l_bad,
    ['\t']        = &&l_loop,
    [' ']         = &&l_loop,
    ['\r']        = &&l_loop,
    ['\n']        = &&l_loop,
    ['"']         = &&l_qup,
    [':']         = &&l_loop,
    [',']         = &&l_loop,
    ['[']         = &&l_up, [']'] = &&l_down, // tracking [] and {} individually would allow fuller validation but is really messy
    ['{']         = &&l_up, ['}'] = &&l_down,
    ['-']         = &&l_bare,
    [48  ... 57]  = &&l_bare, // 0-9
    ['t']         = &&l_bare,
    ['f']         = &&l_bare,
    ['n']         = &&l_bare // true, false, null
  };

  static const void *gobare[] = {
    [0   ... 8]   = &&l_bad,
    [11  ... 12]  = &&l_bad,
    [14  ... 31]  = &&l_bad,
    [33  ... 43]  = &&l_loop,
    [45  ... 92]  = &&l_loop,
    [94  ... 124] = &&l_loop, // could be more pedantic/validation-checking
    [126]         = &&l_loop, // could be more pedantic/validation-checking
    ['\t']        = &&l_unbare,
    [' ']         = &&l_unbare,
    ['\r']        = &&l_unbare,
    ['\n']        = &&l_unbare,
    [',']         = &&l_unbare,
    [']']         = &&l_unbare,
    ['}']         = &&l_unbare,
    [127 ... 255] = &&l_bad
  };

  static const void *gostring[] = {
    [0   ... 31]  = &&l_bad,
    [127]         = &&l_bad,
    [32  ... 33]  = &&l_loop,
    [35  ... 91]  = &&l_loop,
    [93  ... 126] = &&l_loop,
    ['\\']        = &&l_esc,
    ['"']         = &&l_qdown,
    [128 ... 191] = &&l_bad,
    [192 ... 223] = &&l_utf8_2,
    [224 ... 239] = &&l_utf8_3,
    [240 ... 247] = &&l_utf8_4,
    [248 ... 255] = &&l_bad
  };

  static const void *goutf8_continue[] = {
    [0   ... 127] = &&l_bad,
    [128 ... 191] = &&l_utf_continue,
    [192 ... 255] = &&l_bad
  };

  static const void *goesc[] = {
    [0   ... 33]  = &&l_bad,
    [35  ... 46]  = &&l_bad,
    [48  ... 91]  = &&l_bad,
    [93  ... 97]  = &&l_bad,
    [99  ... 101] = &&l_bad,
    [103 ... 109] = &&l_bad,
    [111 ... 113] = &&l_bad,
    [115]         = &&l_bad,
    [118 ... 255] = &&l_bad,
    ['"']         = &&l_unesc,
    ['\\']        = &&l_unesc,
    ['/']         = &&l_unesc,
    ['b']         = &&l_unesc,
    ['f']         = &&l_unesc,
    ['n']         = &&l_unesc,
    ['r']         = &&l_unesc,
    ['t']         = &&l_unesc,
    ['u']         = &&l_unesc
  };

  static const void **go = gostruct;

  for (cur = js, end = js + len; cur < end; cur++) {
    goto *go[*cur];
    l_loop:;
  }

  return depth; // 0 if successful full parse, >0 for incomplete data

  l_bad:
    return 1;

  l_up:
    PUSH(0);
    ++depth;
    goto l_loop;

  l_down:
    --depth;
    CAP(0);
    goto l_loop;

  l_qup:
    PUSH(1);
    go=gostring;
    goto l_loop;

  l_qdown:
    CAP(-1);
    go=gostruct;
    goto l_loop;

  l_esc:
    go = goesc;
    goto l_loop;

  l_unesc:
    go = gostring;
    goto l_loop;

  l_bare:
    PUSH(0);
    go = gobare;
    goto l_loop;

  l_unbare:
    CAP(-1);
    go = gostruct;
    goto *go[*cur];

  l_utf8_2:
    go = goutf8_continue;
    utf8_remain = 1;
    goto l_loop;

  l_utf8_3:
    go = goutf8_continue;
    utf8_remain = 2;
    goto l_loop;

  l_utf8_4:
    go = goutf8_continue;
    utf8_remain = 3;
    goto l_loop;

  l_utf_continue:
    if (!--utf8_remain)
      go=gostring;
    goto l_loop;

}
示例#23
0
GLboolean _slang_assemble_function (slang_assemble_ctx *A, slang_function *fun)
{
	GLuint param_size, local_size;
	GLuint skip, cleanup;

	fun->address = A->file->count;

	if (fun->body == NULL)
	{
		/* jump to the actual function body - we do not know it, so add the instruction
		 * to fixup table */
		fun->fixups.table = (GLuint *) slang_alloc_realloc (fun->fixups.table,
			fun->fixups.count * sizeof (GLuint), (fun->fixups.count + 1) * sizeof (GLuint));
		if (fun->fixups.table == NULL)
			return GL_FALSE;
		fun->fixups.table[fun->fixups.count] = fun->address;
		fun->fixups.count++;
		if (!PUSH (A->file, slang_asm_jump))
			return GL_FALSE;
		return GL_TRUE;
	}
	else
	{
		GLuint i;

		/* resolve all fixup table entries and delete it */
		for (i = 0; i < fun->fixups.count; i++)
			A->file->code[fun->fixups.table[i]].param[0] = fun->address;
		slang_fixup_table_free (&fun->fixups);
	}

	/* At this point traverse function formal parameters and code to calculate
	 * total memory size to be allocated on the stack.
	 * During this process the variables will be assigned local addresses to
	 * reference them in the code.
	 * No storage optimizations are performed so exclusive scopes are not detected and shared. */

	/* calculate return value size */
	param_size = 0;
	if (fun->header.type.specifier.type != slang_spec_void)
		if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, &param_size))
			return GL_FALSE;
	A->local.ret_size = param_size;

	/* calculate formal parameter list size */
	if (!sizeof_variables (A, fun->parameters, 0, fun->param_count, &param_size))
		return GL_FALSE;

	/* calculate local variables size - take into account the four-byte return address and
	 * temporaries for various tasks (4 for addr and 16 for swizzle temporaries).
	 * these include variables from the formal parameter scope and from the code */
	A->local.addr_tmp = param_size + 4;
	A->local.swizzle_tmp = param_size + 4 + 4;
	local_size = param_size + 4 + 4 + 16;
	if (!sizeof_variables (A, fun->parameters, fun->param_count, fun->parameters->num_variables,
			&local_size))
		return GL_FALSE;
	if (!collect_locals (A, fun->body, &local_size))
		return GL_FALSE;

	/* allocate local variable storage */
	if (!PLAB (A->file, slang_asm_local_alloc, local_size - param_size - 4))
		return GL_FALSE;

	/* mark a new frame for function variable storage */
	if (!PLAB (A->file, slang_asm_enter, local_size))
		return GL_FALSE;

	/* jump directly to the actual code */
	skip = A->file->count;
	if (!push_new (A->file))
		return GL_FALSE;
	A->file->code[skip].type = slang_asm_jump;

	/* all "return" statements will be directed here */
	A->flow.function_end = A->file->count;
	cleanup = A->file->count;
	if (!push_new (A->file))
		return GL_FALSE;
	A->file->code[cleanup].type = slang_asm_jump;

	/* execute the function body */
	A->file->code[skip].param[0] = A->file->count;
	if (!_slang_assemble_operation (A, fun->body, /*slang_ref_freelance*/slang_ref_forbid))
		return GL_FALSE;

	/* this is the end of the function - restore the old function frame */
	A->file->code[cleanup].param[0] = A->file->count;
	if (!PUSH (A->file, slang_asm_leave))
		return GL_FALSE;

	/* free local variable storage */
	if (!PLAB (A->file, slang_asm_local_free, local_size - param_size - 4))
		return GL_FALSE;

	/* return from the function */
	if (!PUSH (A->file, slang_asm_return))
		return GL_FALSE;

	return GL_TRUE;
}
示例#24
0
static void connected_components() {
  int *color;
  int i;
  int clusters, singletons;

  CA(color, n_seq, sizeof(int));
  CA(back_edges, n_seq, sizeof(int *));
  CA(tree_edges, n_seq, sizeof(int *));
  CA(n_tedges, n_seq, sizeof(int));
  CA(n_bedges, n_seq, sizeof(int));


  n_components = 0;
  components = NULL;
  component_size = NULL;
  for(i=0;i<n_seq;i++) {
    if (color[i]) continue;
    if (chimeric[i]) continue;

    PUSH(components, n_components, sizeof(int *));
    PUSH(component_size, n_components, sizeof(int));
    components[n_components] = NULL;
    component_size[n_components] = 0;
    cc_dfs_visit(color, components + n_components, 
		 component_size + n_components, i);
    n_components++;
  }


  fprintf(stderr,"Found %d connected components\n", n_components);
  CA(arti_points, n_seq, sizeof(int));
  n_arti = 0;
  clusters = singletons = 0;

  for(i=0;i<n_components;i++) {
    int j;

    if (component_size[i] > 1) {

      fprintf(stdout,">Cluster %d (%d sequences)\n",clusters,
	      component_size[i]);

      scan_arti_points(i);
      if (database_name) {
	for(j=0;j<component_size[i];j++) {
	  fprintf(stdout,"%s ",seqname_data + 
		  seqmeta[components[i][j]].name_pos);
	}
      } else {
	for(j=0;j<component_size[i];j++) {
	  fprintf(stdout,"%d ",components[i][j]);
	}
      }
      fprintf(stdout,"\n");
      clusters++;
    } else {
      singletons++;
    }
  }

  fprintf(stdout,">Singletons (%d sequences)\n", singletons);
  if (database_name) {
    for(i=0;i<n_components;i++) {
      if (component_size[i] == 1) {
	fprintf(stdout,"%s ",seqname_data + 
		seqmeta[components[i][0]].name_pos);
      }
    }
  } else {
    for(i=0;i<n_components;i++) {
      if (component_size[i] == 1) {
	fprintf(stdout,"%d ",components[i][0]);
      }
    }
  }
  fprintf(stdout,"\n");

  free(color);
  free(back_edges);
  free(tree_edges);
  free(n_tedges);
  free(n_bedges);
  fprintf(stderr,"Clusters %d Singletons %d\n",clusters,singletons);
}
示例#25
0
GLboolean _slang_assemble_function_call (slang_assemble_ctx *A, slang_function *fun,
	slang_operation *params, GLuint param_count, GLboolean assignment)
{
	GLuint i;
	slang_swizzle p_swz[64];
	slang_ref_type p_ref[64];

	/* TODO: fix this, allocate dynamically */
	if (param_count > 64)
		return GL_FALSE;

	/* make room for the return value, if any */
	if (fun->header.type.specifier.type != slang_spec_void)
	{
		GLuint ret_size = 0;

		if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size))
			return GL_FALSE;
		if (!PLAB (A->file, slang_asm_local_alloc, ret_size))
			return GL_FALSE;
	}

	/* push the actual parameters on the stack */
	for (i = 0; i < param_count; i++)
	{
		if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
			fun->parameters->variables[i].type.qualifier == slang_qual_out)
		{
			if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
				return GL_FALSE;
			/* TODO: optimize the "out" parameter case */
			if (!_slang_assemble_operation (A, &params[i], slang_ref_force))
				return GL_FALSE;
			p_swz[i] = A->swz;
			p_ref[i] = A->ref;
			if (!PUSH (A->file, slang_asm_addr_copy))
				return GL_FALSE;
			if (!PUSH (A->file, slang_asm_addr_deref))
				return GL_FALSE;
			if (i == 0 && assignment)
			{
				/* duplicate the resulting address */
				if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
					return GL_FALSE;
				if (!PUSH (A->file, slang_asm_addr_deref))
					return GL_FALSE;
			}
			if (!_slang_dereference (A, &params[i]))
				return GL_FALSE;
		}
		else
		{
			if (!_slang_assemble_operation (A, &params[i], slang_ref_forbid))
				return GL_FALSE;
			p_swz[i] = A->swz;
			p_ref[i] = A->ref;
		}
	}

	/* call the function */
	if (!PLAB (A->file, slang_asm_call, fun->address))
		return GL_FALSE;

	/* pop the parameters from the stack */
	for (i = param_count; i > 0; i--)
	{
		GLuint j = i - 1;

		A->swz = p_swz[j];
		A->ref = p_ref[j];
		if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
			fun->parameters->variables[j].type.qualifier == slang_qual_out)
		{
			/* for output parameter copy the contents of the formal parameter
			 * back to the original actual parameter */
			if (!_slang_assemble_assignment (A, &params[j]))
				return GL_FALSE;
			/* pop the actual parameter's address */
			if (!PLAB (A->file, slang_asm_local_free, 4))
				return GL_FALSE;
		}
		else
		{
			/* pop the value of the parameter */
			if (!_slang_cleanup_stack (A, &params[j]))
				return GL_FALSE;
		}
	}

	return GL_TRUE;
}
示例#26
0
文件: sprintf.c 项目: nhinze/rhodes
VALUE
rb_str_format(int argc, const VALUE *argv, VALUE fmt)
{
    enum {default_float_precision = 6};
    rb_encoding *enc;
    const char *p, *end;
    char *buf;
    long blen, bsiz;
    VALUE result;

    long scanned = 0;
    int coderange = ENC_CODERANGE_7BIT;
    int width, prec, flags = FNONE;
    int nextarg = 1;
    int posarg = 0;
    int tainted = 0;
    VALUE nextvalue;
    VALUE tmp;
    VALUE str;
    volatile VALUE hash = Qundef;

#define CHECK_FOR_WIDTH(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "width given twice");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "width after precision"); \
    }
#define CHECK_FOR_FLAGS(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "flag after width");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "flag after precision"); \
    }

    ++argc;
    --argv;
    if (OBJ_TAINTED(fmt)) tainted = 1;
    StringValue(fmt);
    enc = rb_enc_get(fmt);
    fmt = rb_str_new4(fmt);
    p = RSTRING_PTR(fmt);
    end = p + RSTRING_LEN(fmt);
    blen = 0;
    bsiz = 120;
    result = rb_str_buf_new(bsiz);
    rb_enc_copy(result, fmt);
    buf = RSTRING_PTR(result);
    memset(buf, 0, bsiz);
    ENC_CODERANGE_SET(result, coderange);

    for (; p < end; p++) {
	const char *t;
	int n;
	VALUE sym = Qnil;

	for (t = p; t < end && *t != '%'; t++) ;
	PUSH(p, t - p);
	if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
	    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &coderange);
	    ENC_CODERANGE_SET(result, coderange);
	}
	if (t >= end) {
	    /* end of fmt string */
	    goto sprint_exit;
	}
	p = t + 1;		/* skip `%' */

	width = prec = -1;
	nextvalue = Qundef;
      retry:
	switch (*p) {
	  default:
	    if (rb_enc_isprint(*p, enc))
		rb_raise(rb_eArgError, "malformed format string - %%%c", *p);
	    else
		rb_raise(rb_eArgError, "malformed format string");
	    break;

	  case ' ':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSPACE;
	    p++;
	    goto retry;

	  case '#':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSHARP;
	    p++;
	    goto retry;

	  case '+':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FPLUS;
	    p++;
	    goto retry;

	  case '-':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FMINUS;
	    p++;
	    goto retry;

	  case '0':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FZERO;
	    p++;
	    goto retry;

	  case '1': case '2': case '3': case '4':
	  case '5': case '6': case '7': case '8': case '9':
	    n = 0;
	    GETNUM(n, width);
	    if (*p == '$') {
		if (nextvalue != Qundef) {
		    rb_raise(rb_eArgError, "value given twice - %d$", n);
		}
		nextvalue = GETPOSARG(n);
		p++;
		goto retry;
	    }
	    CHECK_FOR_WIDTH(flags);
	    width = n;
	    flags |= FWIDTH;
	    goto retry;

	  case '<':
	  case '{':
	    {
		const char *start = p;
		char term = (*p == '<') ? '>' : '}';
		int len;

		for (; p < end && *p != term; ) {
		    p += rb_enc_mbclen(p, end, enc);
		}
		if (p >= end) {
		    rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
		}
#if SIZEOF_INT < SIZEOF_SIZE_T
		if ((size_t)(p - start) >= INT_MAX) {
		    const int message_limit = 20;
		    len = (int)(rb_enc_right_char_head(start, start + message_limit, p, enc) - start);
		    rb_enc_raise(enc, rb_eArgError,
				 "too long name (%"PRIdSIZE" bytes) - %.*s...%c",
				 (size_t)(p - start - 2), len, start, term);
		}
#endif
		len = (int)(p - start + 1); /* including parenthesis */
		if (sym != Qnil) {
		    rb_enc_raise(enc, rb_eArgError, "named%.*s after <%"PRIsVALUE">",
				 len, start, rb_sym2str(sym));
		}
		CHECKNAMEARG(start, len, enc);
		get_hash(&hash, argc, argv);
		sym = rb_check_symbol_cstr(start + 1,
					   len - 2 /* without parenthesis */,
					   enc);
		if (!NIL_P(sym)) nextvalue = rb_hash_lookup2(hash, sym, Qundef);
		if (nextvalue == Qundef) {
		    if (NIL_P(sym)) {
			sym = rb_sym_intern(start + 1,
					    len - 2 /* without parenthesis */,
					    enc);
		    }
		    nextvalue = rb_hash_default_value(hash, sym);
		    if (NIL_P(nextvalue)) {
			rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start);
		    }
		}
		if (term == '}') goto format_s;
		p++;
		goto retry;
	    }

	  case '*':
	    CHECK_FOR_WIDTH(flags);
	    flags |= FWIDTH;
	    GETASTER(width);
	    if (width < 0) {
		flags |= FMINUS;
		width = -width;
	    }
	    p++;
	    goto retry;

	  case '.':
	    if (flags & FPREC0) {
		rb_raise(rb_eArgError, "precision given twice");
	    }
	    flags |= FPREC|FPREC0;

	    prec = 0;
	    p++;
	    if (*p == '*') {
		GETASTER(prec);
		if (prec < 0) {	/* ignore negative precision */
		    flags &= ~FPREC;
		}
		p++;
		goto retry;
	    }

	    GETNUM(prec, precision);
	    goto retry;

	  case '\n':
	  case '\0':
	    p--;
	  case '%':
	    if (flags != FNONE) {
		rb_raise(rb_eArgError, "invalid format character - %%");
	    }
	    PUSH("%", 1);
	    break;

	  case 'c':
	    {
		VALUE val = GETARG();
		VALUE tmp;
		unsigned int c;
		int n;

		tmp = rb_check_string_type(val);
		if (!NIL_P(tmp)) {
		    if (rb_enc_strlen(RSTRING_PTR(tmp),RSTRING_END(tmp),enc) != 1) {
			rb_raise(rb_eArgError, "%%c requires a character");
		    }
		    c = rb_enc_codepoint_len(RSTRING_PTR(tmp), RSTRING_END(tmp), &n, enc);
		    RB_GC_GUARD(tmp);
		}
		else {
		    c = NUM2INT(val);
		    n = rb_enc_codelen(c, enc);
		}
		if (n <= 0) {
		    rb_raise(rb_eArgError, "invalid character");
		}
		if (!(flags & FWIDTH)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
		else if ((flags & FMINUS)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		    if (width > 1) FILL(' ', width-1);
		}
		else {
		    if (width > 1) FILL(' ', width-1);
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
	    }
	    break;

	  case 's':
	  case 'p':
	  format_s:
	    {
		VALUE arg = GETARG();
		long len, slen;

		if (*p == 'p') {
		    str = rb_inspect(arg);
		}
		else {
		    str = rb_obj_as_string(arg);
		}
		if (OBJ_TAINTED(str)) tainted = 1;
		len = RSTRING_LEN(str);
		rb_str_set_len(result, blen);
		if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
		    int cr = coderange;
		    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr);
		    ENC_CODERANGE_SET(result,
				      (cr == ENC_CODERANGE_UNKNOWN ?
				       ENC_CODERANGE_BROKEN : (coderange = cr)));
		}
		enc = rb_enc_check(result, str);
		if (flags&(FPREC|FWIDTH)) {
		    slen = rb_enc_strlen(RSTRING_PTR(str),RSTRING_END(str),enc);
		    if (slen < 0) {
			rb_raise(rb_eArgError, "invalid mbstring sequence");
		    }
		    if ((flags&FPREC) && (prec < slen)) {
			char *p = rb_enc_nth(RSTRING_PTR(str), RSTRING_END(str),
					     prec, enc);
			slen = prec;
			len = p - RSTRING_PTR(str);
		    }
		    /* need to adjust multi-byte string pos */
		    if ((flags&FWIDTH) && (width > slen)) {
			width -= (int)slen;
			if (!(flags&FMINUS)) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			CHECK(len);
			memcpy(&buf[blen], RSTRING_PTR(str), len);
			RB_GC_GUARD(str);
			blen += len;
			if (flags&FMINUS) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			rb_enc_associate(result, enc);
			break;
		    }
		}
		PUSH(RSTRING_PTR(str), len);
		RB_GC_GUARD(str);
		rb_enc_associate(result, enc);
	    }
	    break;

	  case 'd':
	  case 'i':
	  case 'o':
	  case 'x':
	  case 'X':
	  case 'b':
	  case 'B':
	  case 'u':
	    {
		volatile VALUE val = GETARG();
                int valsign;
		char nbuf[64], *s;
		const char *prefix = 0;
		int sign = 0, dots = 0;
		char sc = 0;
		long v = 0;
		int base, bignum = 0;
		int len;

		switch (*p) {
		  case 'd':
		  case 'i':
		  case 'u':
		    sign = 1; break;
		  case 'o':
		  case 'x':
		  case 'X':
		  case 'b':
		  case 'B':
		    if (flags&(FPLUS|FSPACE)) sign = 1;
		    break;
		}
		if (flags & FSHARP) {
		    switch (*p) {
		      case 'o':
			prefix = "0"; break;
		      case 'x':
			prefix = "0x"; break;
		      case 'X':
			prefix = "0X"; break;
		      case 'b':
			prefix = "0b"; break;
		      case 'B':
			prefix = "0B"; break;
		    }
		}

	      bin_retry:
		switch (TYPE(val)) {
		  case T_FLOAT:
		    if (FIXABLE(RFLOAT_VALUE(val))) {
			val = LONG2FIX((long)RFLOAT_VALUE(val));
			goto bin_retry;
		    }
		    val = rb_dbl2big(RFLOAT_VALUE(val));
		    if (FIXNUM_P(val)) goto bin_retry;
		    bignum = 1;
		    break;
		  case T_STRING:
		    val = rb_str_to_inum(val, 0, TRUE);
		    goto bin_retry;
		  case T_BIGNUM:
		    bignum = 1;
		    break;
		  case T_FIXNUM:
		    v = FIX2LONG(val);
		    break;
		  default:
		    val = rb_Integer(val);
		    goto bin_retry;
		}

		switch (*p) {
		  case 'o':
		    base = 8; break;
		  case 'x':
		  case 'X':
		    base = 16; break;
		  case 'b':
		  case 'B':
		    base = 2; break;
		  case 'u':
		  case 'd':
		  case 'i':
		  default:
		    base = 10; break;
		}

                if (base != 10) {
                    int numbits = ffs(base)-1;
                    size_t abs_nlz_bits;
                    size_t numdigits = rb_absint_numwords(val, numbits, &abs_nlz_bits);
                    long i;
                    if (INT_MAX-1 < numdigits) /* INT_MAX is used because rb_long2int is used later. */
                        rb_raise(rb_eArgError, "size too big");
                    if (sign) {
                        if (numdigits == 0)
                            numdigits = 1;
                        tmp = rb_str_new(NULL, numdigits);
                        valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
                                1, CHAR_BIT-numbits, INTEGER_PACK_BIG_ENDIAN);
                        for (i = 0; i < RSTRING_LEN(tmp); i++)
                            RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
                        s = RSTRING_PTR(tmp);
                        if (valsign < 0) {
                            sc = '-';
                            width--;
                        }
                        else if (flags & FPLUS) {
                            sc = '+';
                            width--;
                        }
                        else if (flags & FSPACE) {
                            sc = ' ';
                            width--;
                        }
                    }
                    else {
                        /* Following conditional "numdigits++" guarantees the
                         * most significant digit as
                         * - '1'(bin), '7'(oct) or 'f'(hex) for negative numbers
                         * - '0' for zero
                         * - not '0' for positive numbers.
                         *
                         * It also guarantees the most significant two
                         * digits will not be '11'(bin), '77'(oct), 'ff'(hex)
                         * or '00'.  */
                        if (numdigits == 0 ||
                                ((abs_nlz_bits != (size_t)(numbits-1) ||
                                  !rb_absint_singlebit_p(val)) &&
                                 (!bignum ? v < 0 : BIGNUM_NEGATIVE_P(val))))
                            numdigits++;
                        tmp = rb_str_new(NULL, numdigits);
                        valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
                                1, CHAR_BIT-numbits, INTEGER_PACK_2COMP | INTEGER_PACK_BIG_ENDIAN);
                        for (i = 0; i < RSTRING_LEN(tmp); i++)
                            RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
                        s = RSTRING_PTR(tmp);
                        dots = valsign < 0;
                    }
                    len = rb_long2int(RSTRING_END(tmp) - s);
                }
                else if (!bignum) {
                    valsign = 1;
                    if (v < 0) {
                        v = -v;
                        sc = '-';
                        width--;
                        valsign = -1;
                    }
                    else if (flags & FPLUS) {
                        sc = '+';
                        width--;
                    }
                    else if (flags & FSPACE) {
                        sc = ' ';
                        width--;
                    }
                    snprintf(nbuf, sizeof(nbuf), "%ld", v);
                    s = nbuf;
		    len = (int)strlen(s);
		}
		else {
                    tmp = rb_big2str(val, 10);
                    s = RSTRING_PTR(tmp);
                    valsign = 1;
                    if (s[0] == '-') {
                        s++;
                        sc = '-';
                        width--;
                        valsign = -1;
                    }
                    else if (flags & FPLUS) {
                        sc = '+';
                        width--;
                    }
                    else if (flags & FSPACE) {
                        sc = ' ';
                        width--;
                    }
		    len = rb_long2int(RSTRING_END(tmp) - s);
		}

		if (dots) {
		    prec -= 2;
		    width -= 2;
		}

		if (*p == 'X') {
		    char *pp = s;
		    int c;
		    while ((c = (int)(unsigned char)*pp) != 0) {
			*pp = rb_enc_toupper(c, enc);
			pp++;
		    }
		}
		if (prefix && !prefix[1]) { /* octal */
		    if (dots) {
			prefix = 0;
		    }
		    else if (len == 1 && *s == '0') {
			len = 0;
			if (flags & FPREC) prec--;
		    }
		    else if ((flags & FPREC) && (prec > len)) {
			prefix = 0;
		    }
		}
		else if (len == 1 && *s == '0') {
		    prefix = 0;
		}
		if (prefix) {
		    width -= (int)strlen(prefix);
		}
		if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
		    prec = width;
		    width = 0;
		}
		else {
		    if (prec < len) {
			if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
			prec = len;
		    }
		    width -= prec;
		}
		if (!(flags&FMINUS)) {
		    CHECK(width);
		    while (width-- > 0) {
			buf[blen++] = ' ';
		    }
		}
		if (sc) PUSH(&sc, 1);
		if (prefix) {
		    int plen = (int)strlen(prefix);
		    PUSH(prefix, plen);
		}
		CHECK(prec - len);
		if (dots) PUSH("..", 2);
		if (!sign && valsign < 0) {
		    char c = sign_bits(base, p);
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		else if ((flags & (FMINUS|FPREC)) != FMINUS) {
		    while (len < prec--) {
			buf[blen++] = '0';
		    }
		}
		PUSH(s, len);
		RB_GC_GUARD(tmp);
		CHECK(width);
		while (width-- > 0) {
		    buf[blen++] = ' ';
		}
	    }
	    break;

	  case 'f':
	    {
		VALUE val = GETARG(), num, den;
		int sign = (flags&FPLUS) ? 1 : 0, zero = 0;
		long len, done = 0;
		int prefix = 0;
		if (FIXNUM_P(val) || RB_TYPE_P(val, T_BIGNUM)) {
		    den = INT2FIX(1);
		    num = val;
		}
		else if (RB_TYPE_P(val, T_RATIONAL)) {
		    den = rb_rational_den(val);
		    num = rb_rational_num(val);
		}
		else {
		    nextvalue = val;
		    goto float_value;
		}
		if (!(flags&FPREC)) prec = default_float_precision;
		if (FIXNUM_P(num)) {
		    if ((SIGNED_VALUE)num < 0) {
			long n = -FIX2LONG(num);
			num = LONG2FIX(n);
			sign = -1;
		    }
		}
		else if (rb_num_negative_p(num)) {
		    sign = -1;
		    num = rb_funcallv(num, idUMinus, 0, 0);
		}
		if (den != INT2FIX(1) || prec > 1) {
		    const ID idDiv = rb_intern("div");
		    VALUE p10 = rb_int_positive_pow(10, prec);
		    VALUE den_2 = rb_funcall(den, idDiv, 1, INT2FIX(2));
		    num = rb_funcallv(num, '*', 1, &p10);
		    num = rb_funcallv(num, '+', 1, &den_2);
		    num = rb_funcallv(num, idDiv, 1, &den);
		}
		else if (prec >= 0) {
		    zero = prec;
		}
		val = rb_obj_as_string(num);
		len = RSTRING_LEN(val) + zero;
		if (prec >= len) len = prec + 1; /* integer part 0 */
		if (sign || (flags&FSPACE)) ++len;
		if (prec > 0) ++len; /* period */
		CHECK(len > width ? len : width);
		if (sign || (flags&FSPACE)) {
		    buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' ';
		    prefix++;
		    done++;
		}
		len = RSTRING_LEN(val) + zero;
		t = RSTRING_PTR(val);
		if (len > prec) {
		    memcpy(&buf[blen], t, len - prec);
		    blen += len - prec;
		    done += len - prec;
		}
		else {
		    buf[blen++] = '0';
		    done++;
		}
		if (prec > 0) {
		    buf[blen++] = '.';
		    done++;
		}
		if (zero) {
		    FILL('0', zero);
		    done += zero;
		}
		else if (prec > len) {
		    FILL('0', prec - len);
		    memcpy(&buf[blen], t, len);
		    blen += len;
		    done += prec;
		}
		else if (prec > 0) {
		    memcpy(&buf[blen], t + len - prec, prec);
		    blen += prec;
		    done += prec;
		}
		if ((flags & FWIDTH) && width > done) {
		    int fill = ' ';
		    long shifting = 0;
		    if (!(flags&FMINUS)) {
			shifting = done;
			if (flags&FZERO) {
			    shifting -= prefix;
			    fill = '0';
			}
			blen -= shifting;
			memmove(&buf[blen + width - done], &buf[blen], shifting);
		    }
		    FILL(fill, width - done);
		    blen += shifting;
		}
		RB_GC_GUARD(val);
		break;
	    }
	  case 'g':
	  case 'G':
	  case 'e':
	  case 'E':
	    /* TODO: rational support */
	  case 'a':
	  case 'A':
	  float_value:
	    {
		VALUE val = GETARG();
		double fval;
		int i, need;
		char fbuf[32];

		fval = RFLOAT_VALUE(rb_Float(val));
		if (isnan(fval) || isinf(fval)) {
		    const char *expr;

		    if (isnan(fval)) {
			expr = "NaN";
		    }
		    else {
			expr = "Inf";
		    }
		    need = (int)strlen(expr);
		    if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
			need++;
		    if ((flags & FWIDTH) && need < width)
			need = width;

		    CHECK(need + 1);
		    snprintf(&buf[blen], need + 1, "%*s", need, "");
		    if (flags & FMINUS) {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen++] = '-';
			else if (flags & FPLUS)
			    buf[blen++] = '+';
			else if (flags & FSPACE)
			    blen++;
			memcpy(&buf[blen], expr, strlen(expr));
		    }
		    else {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen + need - strlen(expr) - 1] = '-';
			else if (flags & FPLUS)
			    buf[blen + need - strlen(expr) - 1] = '+';
			else if ((flags & FSPACE) && need > width)
			    blen++;
			memcpy(&buf[blen + need - strlen(expr)], expr,
			       strlen(expr));
		    }
		    blen += strlen(&buf[blen]);
		    break;
		}

		fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
		need = 0;
		if (*p != 'e' && *p != 'E') {
		    i = INT_MIN;
		    frexp(fval, &i);
		    if (i > 0)
			need = BIT_DIGITS(i);
		}
		need += (flags&FPREC) ? prec : default_float_precision;
		if ((flags&FWIDTH) && need < width)
		    need = width;
		need += 20;

		CHECK(need);
		snprintf(&buf[blen], need, fbuf, fval);
		blen += strlen(&buf[blen]);
	    }
	    break;
	}
	flags = FNONE;
    }

  sprint_exit:
    RB_GC_GUARD(fmt);
    /* XXX - We cannot validate the number of arguments if (digit)$ style used.
     */
    if (posarg >= 0 && nextarg < argc) {
	const char *mesg = "too many arguments for format string";
	if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg);
	if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
    }
    rb_str_resize(result, blen);

    if (tainted) OBJ_TAINT(result);
    return result;
}
示例#27
0
static GLboolean handle_subscript (slang_assemble_ctx *A, slang_assembly_typeinfo *tie,
	slang_assembly_typeinfo *tia, slang_operation *op, slang_ref_type ref)
{
	GLuint asize = 0, esize = 0;

	/* get type info of the master expression (matrix, vector or an array */
	if (!_slang_typeof_operation (A, &op->children[0], tia))
		return GL_FALSE;
	if (!sizeof_variable (A, &tia->spec, slang_qual_none, tia->array_len, &asize))
		return GL_FALSE;

	/* get type info of the result (matrix column, vector row or array element) */
	if (!_slang_typeof_operation (A, op, tie))
		return GL_FALSE;
	if (!sizeof_variable (A, &tie->spec, slang_qual_none, 0, &esize))
		return GL_FALSE;

	/* assemble the master expression */
	if (!_slang_assemble_operation (A, &op->children[0], ref))
		return GL_FALSE;

	/* when indexing an l-value swizzle, push the swizzle_tmp */
	if (ref == slang_ref_force && tia->is_swizzled)
		if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
			return GL_FALSE;

	/* assemble the subscript expression */
	if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid))
		return GL_FALSE;

	if (ref == slang_ref_force && tia->is_swizzled)
	{
		GLuint i;

		/* copy the swizzle indexes to the swizzle_tmp */
		for (i = 0; i < tia->swz.num_components; i++)
		{
			if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16))
				return GL_FALSE;
			if (!PLAB (A->file, slang_asm_addr_push, i * 4))
				return GL_FALSE;
			if (!PUSH (A->file, slang_asm_addr_add))
				return GL_FALSE;
			if (!PLAB (A->file, slang_asm_addr_push, tia->swz.swizzle[i]))
				return GL_FALSE;
			if (!PUSH (A->file, slang_asm_addr_copy))
				return GL_FALSE;
			if (!PLAB (A->file, slang_asm_local_free, 4))
				return GL_FALSE;
		}

		/* offset the pushed swizzle_tmp address and dereference it */
		if (!PUSH (A->file, slang_asm_int_to_addr))
			return GL_FALSE;
		if (!PLAB (A->file, slang_asm_addr_push, 4))
			return GL_FALSE;
		if (!PUSH (A->file, slang_asm_addr_multiply))
			return GL_FALSE;
		if (!PUSH (A->file, slang_asm_addr_add))
			return GL_FALSE;
		if (!PUSH (A->file, slang_asm_addr_deref))
			return GL_FALSE;
	}
	else
	{
		/* convert the integer subscript to a relative address */
		if (!PUSH (A->file, slang_asm_int_to_addr))
			return GL_FALSE;
	}

	if (!PLAB (A->file, slang_asm_addr_push, esize))
		return GL_FALSE;
	if (!PUSH (A->file, slang_asm_addr_multiply))
		return GL_FALSE;

	if (ref == slang_ref_force)
	{
		/* offset the base address with the relative address */
		if (!PUSH (A->file, slang_asm_addr_add))
			return GL_FALSE;
	}
	else
	{
		GLuint i;

		/* move the selected element to the beginning of the master expression */
		for (i = 0; i < esize; i += 4)
			if (!PLAB2 (A->file, slang_asm_float_move, asize - esize + i + 4, i + 4))
				return GL_FALSE;
		if (!PLAB (A->file, slang_asm_local_free, 4))
			return GL_FALSE;

		/* free the rest of the master expression */
		if (!PLAB (A->file, slang_asm_local_free, asize - esize))
			return GL_FALSE;
	}

	return GL_TRUE;
}
示例#28
0
int tinyjson_parse_err(const char* json, int length, struct tinyjson_token *out, int max_tokens) {
	const unsigned char* cur;
	const unsigned char* end;
	struct tinyjson_token* out_end  = out + max_tokens;
	unsigned char (*st)[256] = &st_struct;
	int utf8_remain = 0;
	int depth = 0;
	struct tinyjson_token dummy[2];
	struct tinyjson_token* current = out;
	int ntokens = 0;

	end = (unsigned char*)json+length;
	for (cur = (unsigned char*)json; cur < end; ++cur) {
		const enum opcode opcode = (enum opcode)(*st)[*cur];
		switch (opcode) {
		case op_bad:
			return -1;

		case op_up:
			PUSH(0);
			if (depth == 1)
				current->type = (*cur) == '[' ? MYJSON_TOKEN_ARRAY : MYJSON_TOKEN_OBJECT;
			++depth;
			break;

		case op_down:
			--depth;
			CAP(0);
			break;

		case op_quote_up:
			PUSH(1);
			if (depth == 1)
				current->type = MYJSON_TOKEN_STRING;
			st = &st_string;
			break;

		case op_quote_down:
			st = &st_struct;
			CAP(-1);
			break;

		case op_escape:
			st = &st_escape;
			break;

		case op_unescape:
			st = &st_string;
			break;

		case op_bare:
			PUSH(0);
			if (depth == 1)
				current->type = MYJSON_TOKEN_LITERAL;
			st = &st_bare;
			break;

		case op_unbare:
			CAP(-1);
			--cur;
			st = &st_struct;
			break;

		case op_utf8_2:
			utf8_remain = 1;
			st = &st_utf8cont;
			break;

		case op_utf8_3:
			utf8_remain = 2;
			break;

		case op_utf8_4:
			utf8_remain = 3;
			break;

		case op_utf8_continue:
			if (--utf8_remain == 0)
				st = &st_struct;
			break;

		case op_loop:
			break;
		}
	}

	return ntokens;
}
示例#29
0
/* The central entry point for the emulator interrupt. This is used by
 * different special programs to call the emulator from VM86 space. 
 * Look at emuint.h for definitions and a list of the currently defined
 * subfunctions.
 * To call emuint from VM86 space do:
 *	push ax		   Save original ax value (*must be done* !)
 *	mov  ah, funcnum   Emuint function number to ah
 *	mov  al, subfunc   Subfunction number, optional, depening on func
 *	int  0xff		
 *	..
 *	..
 * Emuint saves the function and subfunction numbers internally, then
 * pops ax off the stack and calls the function handler with the original
 * value in ax.
 */
void
emuint(regcontext_t *REGS)
{
    u_short func, subfunc;

    /* Remove function number from stack */
    func = R_AH;
    subfunc = R_AL;

    R_AX = POP(REGS);

    /* Call the function handler, subfunction is ignored, if unused */
    switch (func)
    {
	/* The redirector call */
	case EMU_REDIR:
	    intff(REGS);
	    break;

	/* EMS call, used by emsdriv.sys */
	case EMU_EMS:
	{
	    switch (subfunc) 
	    {
	    	case EMU_EMS_CTL:
		    R_AX = (u_short)ems_init();
		    break;

	    	case EMU_EMS_CALL:
		    ems_entry(REGS);
		    break;

		default:
		    debug(D_ALWAYS, "Undefined subfunction for EMS call\n");
		    break;
	    }
	    break;
	}

	default:
	    debug(D_ALWAYS, "Emulator interrupt called with undefined function %02x\n", func);

            /* 
             * XXX
             * temporary backwards compatibility with instbsdi.exe
             * remove after a while.
             */
            fprintf(stderr, "***\n*** WARNING - unknown emuint function\n");
            fprintf(stderr, "*** Continuing; assuming instbsdi redirector.\n");
            fprintf(stderr, "*** Please install the new redirector");
            fprintf(stderr, " `redir.com' as soon as possible.\n");
            fprintf(stderr, "*** This compatibility hack is not permanent.\n");
            fprintf(stderr, "***\n");
            PUSH(R_AX, REGS);
            R_BX = R_ES;
            R_DX = R_DI;
            R_DI = R_DS;
            intff(REGS);
	    break;
    }
}
示例#30
0
// START FUNC DECL
void
qsort___ORDR_____TYPE__ (
	    void *const pbase, 
	    size_t total_elems, 
	    size_t size, 
	    __compar_fn_t cmp
	    )
// STOP FUNC DECL
{
  register char *base_ptr = (char *) pbase;
  if ( size != sizeof(__TYPE2__) ) { exit(1); }

  const size_t max_thresh = MAX_THRESH * size;

  if (total_elems == 0) {
    /* Avoid lossage with unsigned arithmetic below.  */
    return;
  }

  if ( total_elems > MAX_THRESH ) {
    char *lo = base_ptr;
    char *hi = &lo[size * (total_elems - 1)];
    stack_node stack[STACK_SIZE];
    stack_node *top = stack;

    PUSH (NULL, NULL);

    while (STACK_NOT_EMPTY) {
      char *left_ptr;
      char *right_ptr;

      /* Select median value from among LO, MID, and HI. Rearrange
	 LO and HI so the three values are sorted. This lowers the
	 probability of picking a pathological pivot value and
	 skips a comparison for both the LEFT_PTR and RIGHT_PTR in
	 the while loops. */

      char *mid = lo + size * ((hi - lo) / size >> 1);

      // if ( (*cmp) ((void *) mid, (void *) lo) < 0) {
      if ( *((__TYPE2__ *)mid) __ORDR2__ *((__TYPE2__ *)lo) ) {
	SWAP (mid, lo, size);
      }
      // if ( (*cmp) ((void *) hi, (void *) mid) < 0) {
      if ( *((__TYPE2__ *)hi) __ORDR2__ *((__TYPE2__ *)mid) ) {
	SWAP (mid, hi, size);
      }
      else {
	goto jump_over;
      }
      // if ( (*cmp) ((void *) mid, (void *) lo) < 0) {
      if ( *((__TYPE2__ *)mid) __ORDR2__ *((__TYPE2__ *)lo) ) {
	SWAP (mid, lo, size);
      }
    jump_over:;

      left_ptr  = lo + size;
      right_ptr = hi - size;

      /* Here's the famous ``collapse the walls'' section of quicksort.
	 Gotta like those tight inner loops!  They are the main reason
	 that this algorithm runs much faster than others. */
      do {
	// while ((*cmp) ((void *) left_ptr, (void *) mid) < 0) {
	while ( *((__TYPE2__ *)left_ptr) __ORDR2__ *((__TYPE2__ *)mid) ) {
	  left_ptr += size;
	}

	// while ((*cmp) ((void *) mid, (void *) right_ptr) < 0) {
	while ( *((__TYPE2__ *)mid) __ORDR2__ *((__TYPE2__ *)right_ptr) ) {
	  right_ptr -= size;
	}

	if (left_ptr < right_ptr) {
	  SWAP (left_ptr, right_ptr, size);
	  if (mid == left_ptr) {
	    mid = right_ptr;
	  }
	  else if (mid == right_ptr) {
	    mid = left_ptr;
	  }
	  left_ptr += size;
	  right_ptr -= size;
	}
	else if (left_ptr == right_ptr) {
	  left_ptr += size;
	  right_ptr -= size;
	  break;
	}
      } while (left_ptr <= right_ptr);

      /* Set up pointers for next iteration.  First determine whether
	 left and right partitions are below the threshold size.  If so,
	 ignore one or both.  Otherwise, push the larger partition's
	 bounds on the stack and continue sorting the smaller one. */

      if ((size_t) (right_ptr - lo) <= max_thresh) {
	if ((size_t) (hi - left_ptr) <= max_thresh) {
	  /* Ignore both small partitions. */
	  POP (lo, hi);
	}
	else {
	  /* Ignore small left partition. */
	  lo = left_ptr;
	}
      }
      else if ((size_t) (hi - left_ptr) <= max_thresh) {
	/* Ignore small right partition. */
	hi = right_ptr;
      }
      else if ((right_ptr - lo) > (hi - left_ptr)) {
	/* Push larger left partition indices. */
	PUSH (lo, right_ptr);
	lo = left_ptr;
      }
      else {
	/* Push larger right partition indices. */
	PUSH (left_ptr, hi);
	hi = right_ptr;
      }
    }
  }