/* Render an object to text. */ static char *print_object(cJSON * item, int depth, int fmt, printbuffer * p) { char **entries = 0, **names = 0; char *out = 0, *ptr, *ret, *str; int len = 7, i = 0, j; cJSON *child = item->child; int numentries = 0, fail = 0; size_t tmplen = 0; /* Count the number of entries. */ while (child) numentries++, child = child->next; /* Explicitly handle empty object case */ if (!numentries) { if (p) out = ensure(p, fmt ? depth + 4 : 3); else out = (char *) cJSON_malloc(fmt ? depth + 4 : 3); if (!out) return 0; ptr = out; *ptr++ = '{'; if (fmt) { *ptr++ = '\n'; for (i = 0; i < depth - 1; i++) *ptr++ = '\t'; } *ptr++ = '}'; *ptr++ = 0; return out; } if (p) { /* Compose the output: */ i = p->offset; len = fmt ? 2 : 1; ptr = ensure(p, len + 1); if (!ptr) return 0; *ptr++ = '{'; if (fmt) *ptr++ = '\n'; *ptr = 0; p->offset += len; child = item->child; depth++; while (child) { if (fmt) { ptr = ensure(p, depth); if (!ptr) return 0; for (j = 0; j < depth; j++) *ptr++ = '\t'; p->offset += depth; } print_string_ptr(child->string, p); p->offset = update(p); len = fmt ? 2 : 1; ptr = ensure(p, len); if (!ptr) return 0; *ptr++ = ':'; if (fmt) *ptr++ = '\t'; p->offset += len; print_value(child, depth, fmt, p); p->offset = update(p); len = (fmt ? 1 : 0) + (child->next ? 1 : 0); ptr = ensure(p, len + 1); if (!ptr) return 0; if (child->next) *ptr++ = ','; if (fmt) *ptr++ = '\n'; *ptr = 0; p->offset += len; child = child->next; } ptr = ensure(p, fmt ? (depth + 1) : 2); if (!ptr) return 0; if (fmt) for (i = 0; i < depth - 1; i++) *ptr++ = '\t'; *ptr++ = '}'; *ptr = 0; out = (p->buffer) + i; } else { /* Allocate space for the names and the objects */ entries = (char **) cJSON_malloc(numentries * sizeof(char *)); if (!entries) return 0; names = (char **) cJSON_malloc(numentries * sizeof(char *)); if (!names) { cJSON_free(entries); return 0; } memset(entries, 0, sizeof(char *) * numentries); memset(names, 0, sizeof(char *) * numentries); /* Collect all the results into our arrays: */ child = item->child; depth++; if (fmt) len += depth; while (child) { names[i] = str = print_string_ptr(child->string, 0); entries[i++] = ret = print_value(child, depth, fmt, 0); if (str && ret) len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); else fail = 1; child = child->next; } /* Try to allocate the output string */ if (!fail) out = (char *) cJSON_malloc(len); if (!out) fail = 1; /* Handle failure */ if (fail) { for (i = 0; i < numentries; i++) { if (names[i]) cJSON_free(names[i]); if (entries[i]) cJSON_free(entries[i]); } cJSON_free(names); cJSON_free(entries); return 0; } /* Compose the output: */ *out = '{'; ptr = out + 1; if (fmt) *ptr++ = '\n'; *ptr = 0; for (i = 0; i < numentries; i++) { if (fmt) for (j = 0; j < depth; j++) *ptr++ = '\t'; tmplen = strlen(names[i]); memcpy(ptr, names[i], tmplen); ptr += tmplen; *ptr++ = ':'; if (fmt) *ptr++ = '\t'; strcpy(ptr, entries[i]); ptr += strlen(entries[i]); if (i != numentries - 1) *ptr++ = ','; if (fmt) *ptr++ = '\n'; *ptr = 0; cJSON_free(names[i]); cJSON_free(entries[i]); } cJSON_free(names); cJSON_free(entries); if (fmt) for (i = 0; i < depth - 1; i++) *ptr++ = '\t'; *ptr++ = '}'; *ptr++ = 0; } return out; }
static void mbrpipe_set_volume(signed int volume) { mbrpipe_volume = ensure(volume,-100,100); }
static void mbrpipe_set_pitch(signed int pitch) { mbrpipe_pitch = ensure(pitch,-100,100); }
int gt_bitPackStringInt64_unit_test(GtError *err) { BitString bitStore = NULL; BitString bitStoreCopy = NULL; uint64_t *randSrc = NULL; /*< create random ints here for input as bit * store */ uint64_t *randCmp = NULL; /*< used for random ints read back */ unsigned *numBitsList = NULL; size_t i, numRnd; BitOffset offsetStart, offset; int had_err = 0; offset = offsetStart = random()%(sizeof (uint64_t) * CHAR_BIT); numRnd = random() % (MAX_RND_NUMS_uint64_t + 1); gt_log_log("offset=%lu, numRnd=%lu\n", (long unsigned)offsetStart, (long unsigned)numRnd); { BitOffset numBits = sizeof (uint64_t) * CHAR_BIT * numRnd + offsetStart; randSrc = gt_malloc(sizeof (uint64_t)*numRnd); bitStore = gt_malloc(bitElemsAllocSize(numBits) * sizeof (BitElem)); bitStoreCopy = gt_calloc(bitElemsAllocSize(numBits), sizeof (BitElem)); randCmp = gt_malloc(sizeof (uint64_t)*numRnd); } /* first test unsigned types */ gt_log_log("gt_bsStoreUInt64/gt_bsGetUInt64: "); for (i = 0; i < numRnd; ++i) { #if 64 > 32 && LONG_BIT < 64 uint64_t v = randSrc[i] = (uint64_t)random() << 32 | random(); #else /* 64 > 32 && LONG_BIT < 64 */ uint64_t v = randSrc[i] = random(); #endif /* 64 > 32 && LONG_BIT < 64 */ int bits = gt_requiredUInt64Bits(v); gt_bsStoreUInt64(bitStore, offset, bits, v); offset += bits; } offset = offsetStart; for (i = 0; i < numRnd; ++i) { uint64_t v = randSrc[i]; int bits = gt_requiredUInt64Bits(v); uint64_t r = gt_bsGetUInt64(bitStore, offset, bits); ensure(had_err, r == v); if (had_err) { gt_log_log("Expected %"PRIu64", got %"PRIu64", i = %lu\n", v, r, (unsigned long)i); freeResourcesAndReturn(had_err); } offset += bits; } gt_log_log("passed\n"); if (numRnd > 0) { uint64_t v = randSrc[0], r = 0; unsigned numBits = gt_requiredUInt64Bits(v); BitOffset i = offsetStart + numBits; uint64_t mask = ~(uint64_t)0; if (numBits < 64) mask = ~(mask << numBits); gt_log_log("bsSetBit, gt_bsClearBit, bsToggleBit, gt_bsGetBit: "); while (v) { int lowBit = v & 1; v >>= 1; ensure(had_err, lowBit == (r = gt_bsGetBit(bitStore, --i))); if (had_err) { gt_log_log("Expected %d, got %d, i = %llu\n", lowBit, (int)r, (unsigned long long)i); freeResourcesAndReturn(had_err); } } i = offsetStart + numBits; gt_bsClear(bitStoreCopy, offsetStart, numBits, random()&1); v = randSrc[0]; while (i) { int lowBit = v & 1; v >>= 1; if (lowBit) bsSetBit(bitStoreCopy, --i); else gt_bsClearBit(bitStoreCopy, --i); } v = randSrc[0]; r = gt_bsGetUInt64(bitStoreCopy, offsetStart, numBits); ensure(had_err, r == v); if (had_err) { gt_log_log("Expected %"PRIu64", got %"PRIu64"\n", v, r); freeResourcesAndReturn(had_err); } for (i = 0; i < numBits; ++i) bsToggleBit(bitStoreCopy, offsetStart + i); r = gt_bsGetUInt64(bitStoreCopy, offsetStart, numBits); ensure(had_err, r == (v = (~v & mask))); if (had_err) { gt_log_log("Expected %"PRIu64", got %"PRIu64"\n", v, r); freeResourcesAndReturn(had_err); } gt_log_log("passed\n"); }
FGuid FSequencer::AddSpawnableForAssetOrClass( UObject* Object, UObject* CounterpartGamePreviewObject ) { FGuid NewSpawnableGuid; if( ObjectBindingManager->AllowsSpawnableObjects() ) { // Grab the MovieScene that is currently focused. We'll add our Blueprint as an inner of the // MovieScene asset. UMovieScene* OwnerMovieScene = GetFocusedMovieScene(); // @todo sequencer: Undo doesn't seem to be working at all const FScopedTransaction Transaction( LOCTEXT("UndoAddingObject", "Add Object to MovieScene") ); // Use the class as the spawnable's name if this is an actor class, otherwise just use the object name (asset) const bool bIsActorClass = Object->IsA( AActor::StaticClass() ) && !Object->HasAnyFlags( RF_ArchetypeObject ); const FName AssetName = bIsActorClass ? Object->GetClass()->GetFName() : Object->GetFName(); // Inner objects don't need a name (it will be auto-generated by the UObject system), but we want one in this case // because the class of any actors that are created from this Blueprint may end up being user-facing. const FName BlueprintName = MakeUniqueObjectName( OwnerMovieScene, UBlueprint::StaticClass(), AssetName ); // Use the asset name as the initial spawnable name const FString NewSpawnableName = AssetName.ToString(); // @todo sequencer: Need UI to allow user to rename these slots // Create our new blueprint! UBlueprint* NewBlueprint = NULL; { // @todo sequencer: Add support for forcing specific factories for an asset UActorFactory* FactoryToUse = NULL; if( bIsActorClass ) { // Placing an actor class directly:: FactoryToUse = GEditor->FindActorFactoryForActorClass( Object->GetClass() ); } else { // Placing an asset FactoryToUse = FActorFactoryAssetProxy::GetFactoryForAssetObject( Object ); } if( FactoryToUse != NULL ) { // Create the blueprint NewBlueprint = FactoryToUse->CreateBlueprint( Object, OwnerMovieScene, BlueprintName ); } else if( bIsActorClass ) { // We don't have a factory, but we can still try to create a blueprint for this actor class NewBlueprint = FKismetEditorUtilities::CreateBlueprint( Object->GetClass(), OwnerMovieScene, BlueprintName, EBlueprintType::BPTYPE_Normal, UBlueprint::StaticClass(), UBlueprintGeneratedClass::StaticClass() ); } } if( ensure( NewBlueprint != NULL ) ) { if( NewBlueprint->GeneratedClass != NULL && FBlueprintEditorUtils::IsActorBased( NewBlueprint ) ) { AActor* ActorCDO = CastChecked< AActor >( NewBlueprint->GeneratedClass->ClassDefaultObject ); // If we have a counterpart object, then copy the properties from that object back into our blueprint's CDO // @todo sequencer livecapture: This isn't really good enough to handle complex actors. The dynamically-spawned actor could have components that // were created in its construction script or via straight-up C++ code. Instead what we should probably do is duplicate the PIE actor and generate // our CDO from that duplicate. It could get pretty complex though. if( CounterpartGamePreviewObject != NULL ) { AActor* CounterpartGamePreviewActor = CastChecked< AActor >( CounterpartGamePreviewObject ); CopyActorProperties( CounterpartGamePreviewActor, ActorCDO ); } else { // Place the new spawnable in front of the camera (unless we were automatically created from a PIE actor) PlaceActorInFrontOfCamera( ActorCDO ); } } NewSpawnableGuid = OwnerMovieScene->AddSpawnable( NewSpawnableName, NewBlueprint, CounterpartGamePreviewObject ); if (IsShotFilteringOn()) { AddUnfilterableObject(NewSpawnableGuid); } } } return NewSpawnableGuid; }
void FSlateFileDialogsStyle::Shutdown() { FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); ensure(StyleInstance.IsUnique()); StyleInstance.Reset(); }
void testObj::test<1>(void) { const FormatterConfig::Wrapper w(value_); ensure("invalid value type", w.isValue() ); }
void testObj::test<11>(void) { const RegExp re("ab+", false); ensure("case-insensitive regexp does not match valid string", re.check("AB") ); }
void testObj::test<12>(void) { const RegExp re("ab+", false); ensure("case-insensitive regexp matches invalid string", re.check("A") ); }
void FPLUGIN_NAMEStyle::Shutdown() { FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); ensure(StyleInstance.IsUnique()); StyleInstance.Reset(); }
void lllogininstance_object::test<2>() { set_test_name("Test User TOS/Critical message Interaction"); const std::string test_uri = "testing-uri"; // Test default connect. logininstance->connect(test_uri, agentCredential); // connect should call LLLogin::connect to init gLoginURI and gLoginCreds. ensure_equals("Default connect uri", gLoginURI, "testing-uri"); ensure_equals("Default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false); ensure_equals("Default for read critical", gLoginCreds["params"]["read_critical"].asBoolean(), false); // TOS failure response. LLSD response; response["state"] = "offline"; response["change"] = "fail.login"; response["progress"] = 0.0; response["transfer_rate"] = 7; response["data"]["reason"] = "tos"; gTestPump.post(response); ensure_equals("TOS Dialog type", gTOSType, "message_tos"); ensure("TOS callback given", gTOSReplyPump != 0); gTOSReplyPump->post(false); // Call callback denying TOS. ensure("No TOS, failed auth", logininstance->authFailure()); // Start again. logininstance->connect(test_uri, agentCredential); gTestPump.post(response); // Fail for tos again. gTOSReplyPump->post(true); // Accept tos, should reconnect w/ agree_to_tos. ensure_equals("Accepted agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), true); ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess()); // Fail connection, attempt connect again. // The new request should have reset agree to tos to default. response["data"]["reason"] = "key"; // bad creds. gTestPump.post(response); ensure("TOS auth failure", logininstance->authFailure()); logininstance->connect(test_uri, agentCredential); ensure_equals("Reset to default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false); // Critical Message failure response. logininstance->connect(test_uri, agentCredential); response["data"]["reason"] = "critical"; // Change response to "critical message" gTestPump.post(response); ensure_equals("TOS Dialog type", gTOSType, "message_critical"); ensure("TOS callback given", gTOSReplyPump != 0); gTOSReplyPump->post(true); ensure_equals("Accepted read critical message", gLoginCreds["params"]["read_critical"].asBoolean(), true); ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess()); // Fail then attempt new connection response["data"]["reason"] = "key"; // bad creds. gTestPump.post(response); ensure("TOS auth failure", logininstance->authFailure()); logininstance->connect(test_uri, agentCredential); ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false); }
void testObj::test<2>(void) { const LimitedNULLString<10> ls(NULL); ensure("unable to stroe NULL", ls.get()==NULL); }
void testObj::test<13>(void) { const LimitedNULLString<10> ls1(NULL); const LimitedNULLString<10> ls2(NULL); ensure("NULL stirngs differ", ls1==ls2); }
void object::test<1>() { // TODO - mloskot - discuss about adding default constructor ensure("NOTE: Coordinate has no default constructor.", true); }
void testObj::test<8>(void) { const RegExp re("ab*", true); ensure("regexp does not match valid string", re.check("a") ); }
void testObj::test<1>(void) { const RegExp re("", true); ensure("string does not match empty regexp", re.check("abc") ); }
void UK2Node_Composite::PostPasteNode() { Super::PostPasteNode(); //@TODO: Should verify that each node in the composite can be pasted into this new graph successfully (CanPasteHere) if (BoundGraph != NULL) { UEdGraph* ParentGraph = CastChecked<UEdGraph>(GetOuter()); ensure(BoundGraph != ParentGraph); // Update the InputSinkNode / OutputSourceNode pointers to point to the new graph TSet<UEdGraphNode*> BoundaryNodes; for (int32 NodeIndex = 0; NodeIndex < BoundGraph->Nodes.Num(); ++NodeIndex) { UEdGraphNode* Node = BoundGraph->Nodes[NodeIndex]; //Remove this node if it should not exist more then one in blueprint if(UK2Node_Event* Event = Cast<UK2Node_Event>(Node)) { UBlueprint* BP = FBlueprintEditorUtils::FindBlueprintForGraphChecked(BoundGraph); if(FBlueprintEditorUtils::FindOverrideForFunction(BP, Event->EventReference.GetMemberParentClass(Event), Event->EventReference.GetMemberName())) { FBlueprintEditorUtils::RemoveNode(BP, Node, true); NodeIndex--; continue; } } BoundaryNodes.Add(Node); if (Node->GetClass() == UK2Node_Tunnel::StaticClass()) { // Exactly a tunnel node, should be the entrance or exit node UK2Node_Tunnel* Tunnel = CastChecked<UK2Node_Tunnel>(Node); if (Tunnel->bCanHaveInputs && !Tunnel->bCanHaveOutputs) { OutputSourceNode = Tunnel; Tunnel->InputSinkNode = this; } else if (Tunnel->bCanHaveOutputs && !Tunnel->bCanHaveInputs) { InputSinkNode = Tunnel; Tunnel->OutputSourceNode = this; } else { ensureMsgf(false, *LOCTEXT("UnexpectedTunnelNode", "Unexpected tunnel node '%s' in cloned graph '%s' (both I/O or neither)").ToString(), *Tunnel->GetName(), *GetName()); } } } RenameBoundGraphCloseToName(BoundGraph->GetName()); ensure(BoundGraph->SubGraphs.Find(ParentGraph) == INDEX_NONE); //Nested composites will already be in the SubGraph array if(ParentGraph->SubGraphs.Find(BoundGraph) == INDEX_NONE) { ParentGraph->SubGraphs.Add(BoundGraph); } FEdGraphUtilities::PostProcessPastedNodes(BoundaryNodes); } }
void testObj::test<2>(void) { const RegExp re("x", true); ensure("string does not match valid regexp", re.check("axc") ); }
void SGameplayTagQueryWidget::Construct(const FArguments& InArgs, const TArray<FEditableGameplayTagQueryDatum>& EditableTagQueries) { ensure(EditableTagQueries.Num() > 0); TagQueries = EditableTagQueries; bReadOnly = InArgs._ReadOnly; OnSaveAndClose = InArgs._OnSaveAndClose; OnCancel = InArgs._OnCancel; // Tag the assets as transactional so they can support undo/redo for (int32 AssetIdx = 0; AssetIdx < TagQueries.Num(); ++AssetIdx) { UObject* TagQueryOwner = TagQueries[AssetIdx].TagQueryOwner.Get(); if (TagQueryOwner) { TagQueryOwner->SetFlags(RF_Transactional); } } // build editable query object tree from the runtime query data UEditableGameplayTagQuery* const EQ = CreateEditableQuery(*TagQueries[0].TagQuery); EditableQuery = EQ; // create details view for the editable query object FDetailsViewArgs ViewArgs; ViewArgs.bAllowSearch = false; ViewArgs.bHideSelectionTip = true; ViewArgs.bShowActorLabel = false; FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor"); Details = PropertyModule.CreateDetailView(ViewArgs); Details->SetObject(EQ); ChildSlot [ SNew(SScaleBox) .HAlign(EHorizontalAlignment::HAlign_Left) .VAlign(EVerticalAlignment::VAlign_Top) .StretchDirection(EStretchDirection::DownOnly) .Stretch(EStretch::ScaleToFit) .Content() [ SNew(SBorder) .BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder")) [ SNew(SVerticalBox) + SVerticalBox::Slot() .AutoHeight() .VAlign(VAlign_Top) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() [ SNew(SButton) .IsEnabled(!bReadOnly) .OnClicked(this, &SGameplayTagQueryWidget::OnSaveAndCloseClicked) .Text(LOCTEXT("GameplayTagQueryWidget_SaveAndClose", "Save and Close")) ] + SHorizontalBox::Slot() .AutoWidth() [ SNew(SButton) .OnClicked(this, &SGameplayTagQueryWidget::OnCancelClicked) .Text(LOCTEXT("GameplayTagQueryWidget_Cancel", "Close Without Saving")) ] ] // to delete! + SVerticalBox::Slot() [ Details.ToSharedRef() ] ] ] ]; }
void testObj::test<3>(void) { const RegExp re("^full$", true); ensure("exact regexp does not match", re.check("full") ); }
void testObj::test<2>(void) { const FormatterConfig::Wrapper w(param1_); ensure("invalid argument type", w.isArgument() ); ensure_equals("invalid argument's value", w.argument(), "p1"); }
void testObj::test<4>(void) { const RegExp re("^full$", true); ensure("exact regexp matches different string", re.check("not full")==false ); }
void UTankAimingComponent::Initialize(UTankBarrel* barrelToSet, UTankTurret *turretToSet) { if (!ensure(barrelToSet && turretToSet)) { return; } barrel = barrelToSet; turret = turretToSet; }
void testObj::test<5>(void) { const RegExp re("ABC", true); ensure("exact regexp does not match", re.check("xx abc yy")==false ); }
void FBaseToolkit::BringToolkitToFront() { if( ensure( ToolkitHost.IsValid() ) ) { // Bring the host window to front ToolkitHost.Pin()->BringToFront(); // First, figure out what the foreground tab is in each tab stack we have tabs docked inside of TSet< SDockTabStack* > TabStacksWithOurTabsForegrounded; { for( auto CurSpotIt( ToolkitTabsInSpots.CreateConstIterator() ); CurSpotIt; ++CurSpotIt ) { const auto& TabsForSpot = CurSpotIt.Value(); for( auto CurTabIt( TabsForSpot.CreateConstIterator() ); CurTabIt; ++CurTabIt ) { const auto& PinnedTab = CurTabIt->Pin(); if( PinnedTab.IsValid() ) { if( PinnedTab->IsForeground() ) { const auto& TabStack = PinnedTab->GetParentDockTabStack(); if( TabStack.IsValid() ) { TabStacksWithOurTabsForegrounded.Add( TabStack.Get() ); } } } } } } // @todo toolkit major: Also draw user's attention when clicked? // @todo toolkit major: If any of the tabs are in their own floating windows, these should be brought to front // Now, make sure that our tabs are foregrounded in their respective stacks! // NOTE: We don't want to push tabs to the front that are in a stack where one of our other tabs is already front-most for( auto CurSpotIt( ToolkitTabsInSpots.CreateConstIterator() ); CurSpotIt; ++CurSpotIt ) { const auto& TabsForSpot = CurSpotIt.Value(); for( auto CurTabIt( TabsForSpot.CreateConstIterator() ); CurTabIt; ++CurTabIt ) { const auto& PinnedTab = CurTabIt->Pin(); if( PinnedTab.IsValid() ) { const auto& TabStack = PinnedTab->GetParentDockTabStack(); if( TabStack.IsValid() ) { // Only foreground if we don't already have a tab foregrounded in this tab's stack if( !TabStacksWithOurTabsForegrounded.Contains( TabStack.Get() ) ) { PinnedTab->BringToFrontInParent(); // Take note that we've foregrounded a tab in this stack, no need to do that again TabStacksWithOurTabsForegrounded.Add( TabStack.Get() ); } } else { // Just do what we can to foreground ourselves PinnedTab->BringToFrontInParent(); } } } } // Tell the toolkit its been brought to the fore - give it a chance to update anything it needs to ToolkitBroughtToFront(); } }
void testObj::test<6>(void) { const RegExp re("a\\d{2}[bc]", true); ensure("regexp does not match matching string", re.check("a12c") ); }
static void mbrpipe_set_rate(signed int rate) { mbrpipe_rate = ensure(rate,-100,100); }
void testObj::test<7>(void) { const RegExp re("a\\d{2}[bc]", true); ensure("regexp matches invalid string", re.check("a2c")==false ); }
static void *mbrpipe_speak_routine(void *nothing) { char *buf; int len; char *msg; char *outbuf; int outlen,outpos; char rdbuf[4096]; char icon[64]; int n,bg; log_msg(OTTS_LOG_DEBUG, MODULE_NAME": speaking thread starting...\n"); set_speaking_thread_parameters(); buf=g_malloc(len=512); while (1) { sem_wait(mbrpipe_semaphore); log_msg(OTTS_LOG_DEBUG, MODULE_NAME": Semaphore on\n"); mbrpipe_stopped = 0; mbrpipe_speaking = 1; module_report_event_begin(); msg = *mbrpipe_message; log_msg(OTTS_LOG_DEBUG, MODULE_NAME": To say: %s\n", msg); buf = NULL; len = 0; if (!MbrpipeSpeakerSingleShot) { /* old wave may still exist after stop */ while((n=read(from_tts[0],rdbuf,4096))>0) { log_msg(OTTS_LOG_DEBUG, MODULE_NAME ": DISCARD %d",n); } } while (1) { if (mbrpipe_stopped) { log_msg(OTTS_LOG_DEBUG, MODULE_NAME ": Stop in child, terminating"); mbrpipe_speaking = 0; module_report_event_stop(); break; } if (!msg || !*msg || mbrpipe_get_msgpart( dumb_conf,mbrpipe_message_type, &msg,icon,&buf,&len, mbrpipe_cap_mode,MbrpipeDelimiters, mbrpipe_punct,MbrpipePunctuationSome)) { mbrpipe_speaking = 0; if (mbrpipe_stopped) module_report_event_stop(); else module_report_event_end(); break; } if (icon[0]) mbrpipe_play_icon(icon); if (!buf || !*buf) continue; if (detilde) remove_tilde_escapes(buf); log_msg(OTTS_LOG_DEBUG, MODULE_NAME ": Speak buffer is %s", buf); if (MbrpipeSpeakerSingleShot) { if (tts_fork(NULL)<0) { break; } } write(to_tts[1],buf,strlen(buf)); write(to_tts[1],"\n",1); if (MbrpipeSpeakerSingleShot) { close(to_tts[1]); } log_msg(OTTS_LOG_DEBUG, MODULE_NAME": Wrote"); outlen=0; outpos=0; outbuf=NULL; for (bg=0;;bg=1) { struct timeval tv; fd_set rdfs; int retval,n; if (!MbrpipeSpeakerSingleShot) { FD_ZERO(&rdfs); FD_SET(from_tts[0],&rdfs); tv.tv_sec=0; tv.tv_usec=(bg)?10000:100000; retval=select(from_tts[0]+1,&rdfs,NULL,NULL,&tv); log_msg(OTTS_LOG_DEBUG, MODULE_NAME ": Select %d", retval); if (retval<0) { break; } if (!retval) break; } n=read(from_tts[0],rdbuf,4096); log_msg(OTTS_LOG_DEBUG, MODULE_NAME ": Read %d", n); if (n<=0) break; if (!outlen) { outlen=n+1024; outbuf=g_malloc(outlen); } else if (outpos+n+1>=outlen) { outlen=outpos+n+1024; outbuf=g_realloc(outbuf,outlen); } memcpy(outbuf+outpos,rdbuf,n); outpos+=n; } if (MbrpipeSpeakerSingleShot) { close(from_tts[0]); } if (!outbuf) continue; outbuf[outpos]=0; for (;;) { if (mbrpipe_stopped) break; if (MbrpipeCleanOutput) { char *c=mbrpipe_cleaned_buffer(outbuf); g_free(outbuf); outbuf=c; } otts_mbrolaSpeak(omh,outbuf,mbrpipe_rate,mbrpipe_pitch,mbrpipe_volume,ensure(MbrpipeContrastLevel,-100,100)); g_free(outbuf); outlen=0; outpos=0; outbuf=NULL; if (mbrpipe_stopped || MbrpipeSpeakerSingleShot) break; n=read(from_tts[0],rdbuf,4096); if (n<0) break; outlen=n+1024; outbuf=g_malloc(outlen); memcpy(outbuf+outpos,rdbuf,n); outpos=n; for (;;) { n=read(from_tts[0],rdbuf,4096); if (n<=0) break; if (outpos+n+1>=outlen) { outlen=outpos+n+1024; outbuf=g_realloc(outbuf,outlen); } memcpy(outbuf+outpos,rdbuf,n); outpos+=n; } outbuf[outpos]=0; } if (mbrpipe_stopped) { log_msg(OTTS_LOG_DEBUG, MODULE_NAME ": Stop in child, terminating"); if (outbuf) g_free(outbuf); mbrpipe_speaking = 0; module_report_event_stop(); break; } } mbrpipe_speaking = 0; mbrpipe_stopped = 0; } mbrpipe_speaking = 0; log_msg(OTTS_LOG_DEBUG, MODULE_NAME": speaking thread ended...\n"); pthread_exit(NULL); }
/* Render an array to text */ static char *print_array(cJSON * item, int depth, int fmt, printbuffer * p) { char **entries; char *out = 0, *ptr, *ret; int len = 5; cJSON *child = item->child; int numentries = 0, i = 0, fail = 0; size_t tmplen = 0; /* How many entries in the array? */ while (child) numentries++, child = child->next; /* Explicitly handle numentries==0 */ if (!numentries) { if (p) out = ensure(p, 3); else out = (char *) cJSON_malloc(3); if (out) strcpy(out, "[]"); return out; } if (p) { /* Compose the output array. */ i = p->offset; ptr = ensure(p, 1); if (!ptr) return 0; *ptr = '['; p->offset++; child = item->child; while (child && !fail) { print_value(child, depth + 1, fmt, p); p->offset = update(p); if (child->next) { len = fmt ? 2 : 1; ptr = ensure(p, len + 1); if (!ptr) return 0; *ptr++ = ','; if (fmt) *ptr++ = ' '; *ptr = 0; p->offset += len; } child = child->next; } ptr = ensure(p, 2); if (!ptr) return 0; *ptr++ = ']'; *ptr = 0; out = (p->buffer) + i; } else { /* Allocate an array to hold the values for each */ entries = (char **) cJSON_malloc(numentries * sizeof(char *)); if (!entries) return 0; memset(entries, 0, numentries * sizeof(char *)); /* Retrieve all the results: */ child = item->child; while (child && !fail) { ret = print_value(child, depth + 1, fmt, 0); entries[i++] = ret; if (ret) len += strlen(ret) + 2 + (fmt ? 1 : 0); else fail = 1; child = child->next; } /* If we didn't fail, try to malloc the output string */ if (!fail) out = (char *) cJSON_malloc(len); /* If that fails, we fail. */ if (!out) fail = 1; /* Handle failure. */ if (fail) { for (i = 0; i < numentries; i++) if (entries[i]) cJSON_free(entries[i]); cJSON_free(entries); return 0; } /* Compose the output array. */ *out = '['; ptr = out + 1; *ptr = 0; for (i = 0; i < numentries; i++) { tmplen = strlen(entries[i]); memcpy(ptr, entries[i], tmplen); ptr += tmplen; if (i != numentries - 1) { *ptr++ = ','; if (fmt) *ptr++ = ' '; *ptr = 0; } cJSON_free(entries[i]); } cJSON_free(entries); *ptr++ = ']'; *ptr++ = 0; } return out; }