/* - doinsert - insert a sop into the strip */ static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos) { sopno sn; sop s; int i; /* avoid making error situations worse */ if (p->error != 0) return; sn = HERE(); EMIT(op, opnd); /* do checks, ensure space */ assert(HERE() == sn+1); s = p->strip[sn]; /* adjust paren pointers */ assert(pos > 0); for (i = 1; i < NPAREN; i++) { if (p->pbegin[i] >= pos) { p->pbegin[i]++; } if (p->pend[i] >= pos) { p->pend[i]++; } } memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], (HERE()-pos-1)*sizeof(sop)); p->strip[pos] = s; }
/* - p_bre - BRE parser top level, anchoring and concatenation * Giving end1 as OUT essentially eliminates the end1/end2 check. * * This implementation is a bit of a kludge, in that a trailing $ is first * taken as an ordinary character and then revised to be an anchor. The * only undesirable side effect is that '$' gets included as a character * category in such cases. This is fairly harmless; not worth fixing. * The amount of lookahead needed to avoid this kludge is excessive. */ static void p_bre(struct parse *p, int end1, /* first terminating character */ int end2) /* second terminating character */ { sopno start = HERE(); int first = 1; /* first subexpression? */ int wasdollar = 0; if (EAT('^')) { EMIT(OBOL, 0); p->g->iflags |= USEBOL; p->g->nbol++; } while (MORE() && !SEETWO(end1, end2)) { wasdollar = p_simp_re(p, first); first = 0; } if (wasdollar) { /* oops, that was a trailing anchor */ DROP(1); EMIT(OEOL, 0); p->g->iflags |= USEEOL; p->g->neol++; } REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ }
void TestYDebugBackend::testWhere() { // need to check debug output to see that one yzError() << HERE() << endl; yzError() << HERE() << endl; yzError() << LOCATION() << endl; yzError() << LOCATION() << endl; }
/** * \brief * De-initialises the context. * * This operation must be executed before application's termination. * It will free up all memory used. * * \param context * The context for this file, which must have been created with * a_apiInit. If context is NULL, this operation will fail. * * \return * Boolean value specifying whether the operation was successful. * * \see * a_apiContext a_apiInit */ int a_apiDeInit( a_apiContext context) { int result; FUNC("a_apiDeInit"); if (context) { if (context->keyContext) { HERE("keyDeInit(keyContext):"); a_keyDeInit(context->keyContext); } if (context->anlContext) { HERE("anlDeInit(anlContext):"); a_anlDeInit(context->anlContext); } if (context->stsContext) { HERE("stsDeInit(stsContext):"); a_stsDeInit(context->stsContext); } if (context->list) { HERE("lstDestroyList(list):"); a_lstDestroyList(context->list); } if (context->utlContext) { HERE("utlDeInit(utlContext):"); a_utlDeInit(context->utlContext); } if (context->bseContext) { HERE("bseDeInit(bseContext):"); a_bseDeInit(context->bseContext); } if (context->shmContext) { HERE("shmDetach(shmContext):"); a_shmDetach(context->shmContext); HERE("shmDestroy(shmContext):"); a_shmDestroyShm(context->shmContext); HERE("shmDeInit(shmContext):"); a_shmDeInit(context->shmContext); } if (context->shmName) { a_memFree(context->shmName); } if (context->dbName) { a_memFree(context->dbName); } HERE("a_memFree(context):"); a_memFree(context); result = 1; } else { result = 0; } return result; }
/* - p_ere - ERE parser top level, concatenation and alternation == static void p_ere(struct parse *p, int stop, size_t reclimit); */ static void p_ere( struct parse *p, int stop, /* character this ERE should end at */ size_t reclimit) { char c; sopno prevback = 0; /* pacify gcc */ sopno prevfwd = 0; /* pacify gcc */ sopno conc; int first = 1; /* is this the first alternative? */ _DIAGASSERT(p != NULL); if (reclimit++ > RECLIMIT || p->error == REG_ESPACE) { p->error = REG_ESPACE; return; } for (;;) { /* do a bunch of concatenated expressions */ conc = HERE(); while (MORE() && (c = PEEK()) != '|' && c != stop) p_ere_exp(p, reclimit); REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ if (!EAT('|')) break; /* NOTE BREAK OUT */ if (first) { INSERT(OCH_, conc); /* offset is wrong */ prevfwd = conc; prevback = conc; first = 0; } ASTERN(OOR1, prevback); prevback = THERE(); AHEAD(prevfwd); /* fix previous offset */ prevfwd = HERE(); EMIT(OOR2, 0); /* offset is very wrong */ } if (!first) { /* tail-end fixups */ AHEAD(prevfwd); ASTERN(O_CH, prevback); } assert(!MORE() || SEE(stop)); }
static aligned_t update(void *arg) { stencil_t *points = ((update_args_t *)arg)->points; size_t i = ((update_args_t *)arg)->i; size_t j = ((update_args_t *)arg)->j; size_t this_stage = ((update_args_t *)arg)->stage; size_t step = ((update_args_t *)arg)->step; size_t next_stage_id = next_stage(this_stage); // Perform local work perform_local_work(); aligned_t **prev = points->stage[prev_stage(this_stage)]; aligned_t sum = *(NORTH(prev, i, j)) + *(WEST(prev, i, j)) + *(HERE(prev, i, j)) + *(EAST(prev, i, j)) + *(SOUTH(prev, i, j)); // Empty the next stage for this index qthread_empty(&points->stage[next_stage_id][i][j]); // Update this point qthread_writeEF_const(&points->stage[this_stage][i][j], sum/NUM_NEIGHBORS); if (step < num_timesteps) { // Spawn next stage update_args_t args = {points, i, j, next_stage_id, step+1}; #ifdef BOUNDARY_SYNC qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, NUM_NEIGHBORS, NEIGHBORS(points->stage[this_stage],i,j)); #else if (i == 1) { // North edge if (j == 1) // West edge: EAST & SOUTH qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 2, EAST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j)); else if (j == points->M-2) // East edge: WEST & SOUTH qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 2, WEST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j)); else // Interior: WEST & EAST & SOUTH qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 3, WEST(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j)); } else if (i == points->N-2) { // South edge if (j == 1) // West edge: NORTH & EAST qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 2, NORTH(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j)); else if (j == points->M-2) // East edge: NORTH & WEST qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 2, NORTH(points->stage[this_stage],i,j), WEST(points->stage[this_stage],i,j)); else // Interior: NORTH & WEST & EAST qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 3, NORTH(points->stage[this_stage],i,j), WEST(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j)); } else { // Interior if (j == 1) // West edge: NORTH & EAST & SOUTH qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 3 , NORTH(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j)); else if (j == points->M-2) // East edge: NORTH & WEST & SOUTH qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 3, NORTH(points->stage[this_stage],i,j), WEST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j)); else // Interior: ALL qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 4, NORTH(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j), WEST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j)); } #endif } else qt_feb_barrier_enter(points->barrier); return 0; }
void free_devices(struct fpga_model* model) { struct fpga_tile* tile; int x, y, i; // leave model->rc untouched for (x = 0; x < model->x_width; x++) { for (y = 0; y < model->y_height; y++) { tile = YX_TILE(model, y, x); if (!tile->num_devs) continue; if (!tile->devs) { HERE(); continue; } for (i = 0; i < tile->num_devs; i++) { fdev_delete(model, y, x, tile->devs[i].type, fdev_typeidx(model, y, x, i)); } free(tile->devs); tile->devs = 0; tile->num_devs = 0; } } }
/* Part of a_apiPrepare: * Create a new Shared Memory Segment, with a new name, that * will not interfere with the original shared memory. */ static int a_apiPrepareCreateOwnShm( a_apiContext context) { FUNC("a_apiPrepareCreateOwnShm"); context->error = A_ERR_OK; a_shmAppShmName(context->shmContext, A_API_SHM_NAME_APPEND); HERE("shm name set"); assert(context->address); if (a_shmCreateShm(context->shmContext, context->address, context->size) ) { HERE("shm created"); if (a_shmAttach(context->shmContext) ) { HERE("shm attached"); if ( a_memCopyMem((void *)context->address, (void *)context->heapMem, context->size) ) { HERE("heap copied to our own shm"); } else { context->error = A_ERR_MEMCOPY_FAIL; HERE("copy from heap to our own shm failed"); } } else { context->error = A_ERR_SHM_ATTACH_FAIL; HERE("could not attach to shm"); } } else { context->error = A_ERR_SHM_CREATE_FAIL; HERE("could not create our own shm"); } return (context->error == A_ERR_OK) ? 1 : 0; }
/// Function name : resolveGameStringSubStrings // Description : Expands sub-strings within the source-text and strips out any comments // // CONST GAME_STRING* pGameString : [in] GameString currently being resolved // TCHAR* szOutput : [in/out] Output buffer // CONST UINT iOutputLength : [in] Length of output buffer, in characters // STACK* pHistoryStack : [in/out] Represents the 'chain' of GameStrings being resolved // ERROR_QUEUE* pErrorQueue : [in/out] ErrorQueue, may already contain errors // // Return Value : Number of sub-strings that could not be resolved // UINT resolveGameStringSubStrings(CONST GAME_STRING* pGameString, TCHAR* szOutput, CONST UINT iOutputLength, STACK* pHistoryStack, ERROR_QUEUE* pErrorQueue) { SUBSTRING* pSubString; // SubString iterator GAME_STRING* pSourceString; // First game string in the list TCHAR* szPreview; // Preview text for error reporting UINT iMissingSubstrings; // Prepare iMissingSubstrings = 0; /// [CHECK] Ensure sub-string is not self-referencial if (isValueInList(pHistoryStack, (LPARAM)pGameString)) { // Lookup initial GameString findListObjectByIndex(pHistoryStack, 0, (LPARAM&)pSourceString); // [ERROR] "Circular sub-string references detected in page %u, string %u : '%s'" generateQueuedError(pErrorQueue, HERE(IDS_GAME_STRING_SUBSTRING_RECURSIVE), pSourceString->iPageID, pSourceString->iID, szPreview = generateGameStringPreview(pGameString, 96)); utilDeleteString(szPreview); return FALSE; } // Prepare pSubString = createSubString(pGameString->szText); /// [STACK] Add GameString to history stack pushObjectOntoStack(pHistoryStack, (LPARAM)pGameString); /// Iterate through sub-strings while (findNextSubString(pGameString, pSubString, iMissingSubstrings, pHistoryStack, pErrorQueue)) { // Examine type switch (pSubString->eType) { /// [MISSION, TEXT] Append to output case SST_MISSION: case SST_LOOKUP: case SST_TEXT: StringCchCat(szOutput, MAX_STRING, pSubString->szText); break; /// [COMMENTS] Ignore case SST_COMMENT: // [SPECIAL CASE] Allow 'opening bracket' operator if (utilCompareString(pSubString->szText, "(")) StringCchCat(szOutput, MAX_STRING, pSubString->szText); break; } } // [STACK] Remove GameString from processing stack popObjectFromStack(pHistoryStack); // Cleanup deleteSubString(pSubString); return iMissingSubstrings; }
/* - p_ere - ERE parser top level, concatenation and alternation */ static void p_ere(struct parse *p, int stop) /* character this ERE should end at */ { char c; sopno prevback; sopno prevfwd; sopno conc; int first = 1; /* is this the first alternative? */ for (;;) { /* do a bunch of concatenated expressions */ conc = HERE(); while (MORE() && (c = PEEK()) != '|' && c != stop) p_ere_exp(p); REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ if (!EAT('|')) break; /* NOTE BREAK OUT */ if (first) { INSERT(OCH_, conc); /* offset is wrong */ prevfwd = conc; prevback = conc; first = 0; } ASTERN(OOR1, prevback); prevback = THERE(); AHEAD(prevfwd); /* fix previous offset */ prevfwd = HERE(); EMIT(OOR2, 0); /* offset is very wrong */ } if (!first) { /* tail-end fixups */ AHEAD(prevfwd); ASTERN(O_CH, prevback); } assert(!MORE() || SEE(stop)); }
/* - p_bre - BRE parser top level, anchoring and concatenation == static void p_bre(struct parse *p, int end1, \ == int end2, size_t reclimit); * Giving end1 as OUT essentially eliminates the end1/end2 check. * * This implementation is a bit of a kludge, in that a trailing $ is first * taken as an ordinary character and then revised to be an anchor. The * only undesirable side effect is that '$' gets included as a character * category in such cases. This is fairly harmless; not worth fixing. * The amount of lookahead needed to avoid this kludge is excessive. */ static void p_bre( struct parse *p, int end1, /* first terminating character */ int end2, /* second terminating character */ size_t reclimit) { sopno start; int first = 1; /* first subexpression? */ int wasdollar = 0; _DIAGASSERT(p != NULL); if (reclimit++ > RECLIMIT || p->error == REG_ESPACE) { p->error = REG_ESPACE; return; } start = HERE(); if (EAT('^')) { EMIT(OBOL, 0); p->g->iflags |= USEBOL; p->g->nbol++; } while (MORE() && !SEETWO(end1, end2)) { wasdollar = p_simp_re(p, first, reclimit); first = 0; } if (wasdollar) { /* oops, that was a trailing anchor */ DROP(1); EMIT(OEOL, 0); p->g->iflags |= USEEOL; p->g->neol++; } REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ }
void message_callback_json(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) { std::string payload((char *)message->payload,message->payloadlen); std::cout << HERE() << STR(message->topic) << ' ' << STR(payload) << '\n'; ReceiveStats* data_obj = reinterpret_cast<ReceiveStats*>(obj); uint64_t rx_nsec; get_timestamp(rx_nsec); std::lock_guard<std::mutex> guard(data_obj->mutex); uint64_t tx_nsec; get_payload_timestamp_json(message->payload, message->payloadlen, &tx_nsec); add_to_stats(data_obj, rx_nsec, tx_nsec, message->topic, message->payloadlen); report_stats(data_obj, rx_nsec); }
// функция переводит переменные *pkiller и *pvictim на хозяев, если это чармы void pk_translate_pair(CHAR_DATA * *pkiller, CHAR_DATA * *pvictim) { if (pkiller != NULL && pkiller[0] != NULL) if (IS_NPC(pkiller[0]) && pkiller[0]->master && AFF_FLAGGED(pkiller[0], AFF_CHARM) && IN_ROOM(pkiller[0]) == IN_ROOM(pkiller[0]->master)) pkiller[0] = pkiller[0]->master; if (pvictim != NULL && pvictim[0] != NULL) { if (IS_NPC(pvictim[0]) && pvictim[0]->master && (AFF_FLAGGED(pvictim[0], AFF_CHARM) || IS_HORSE(pvictim[0]))) if (IN_ROOM(pvictim[0]) == IN_ROOM(pvictim[0]->master)) pvictim[0] = pvictim[0]->master; if (!HERE(pvictim[0])) pvictim[0] = NULL; } }
/* - dupl - emit a duplicate of a bunch of sops */ static sopno /* start of duplicate */ dupl(struct parse *p, sopno start, /* from here */ sopno finish) /* to this less one */ { sopno ret = HERE(); sopno len = finish - start; assert(finish >= start); if (len == 0) return(ret); enlarge(p, p->ssize + len); /* this many unexpected additions */ assert(p->ssize >= p->slen + len); (void) memmove((char *)(p->strip + p->slen), (char *)(p->strip + start), (size_t)len*sizeof(sop)); p->slen += len; return(ret); }
transfer_function get_transfer_function( const options& op ) { std::string fn = op.require_as<std::string>("function"); if ( fn == "tanh" ) { ovec2d p = op.optional_as<ovec2d>("function_args", "1,1"); return transfer_function(functions::hyperbolic_tangent(p[0],p[1])); } else if ( fn == "linear" ) { ovector<real> p = op.optional_as<ovector<real>>("function_args", "1,0"); ZI_ASSERT(p.size()&&p.size()<3); if ( p.size() == 1 ) { return transfer_function(functions::linear(p[0])); } else if ( p.size() == 2 ) { return transfer_function(functions::linear(p[0], p[1])); } } else if ( fn == "rectify_linear" ) { return transfer_function(functions::rectify_linear()); } else if ( fn == "soft_sign" ) { return transfer_function(functions::soft_sign()); } else if ( fn == "logistics" ) { return transfer_function(functions::logistics()); } else if ( fn == "forward_logistics" ) { return transfer_function(functions::forward_logistics()); } throw std::logic_error(HERE() + "unknown function: " + fn); }
/* Part of a_apiPrepare: * Loads (fills) the memory on heap from file. * The actual loading is done in a_fil. */ static int a_apiPrepareLoadFile2Heap( a_apiContext context, char *memFname) { FUNC("a_apiPrepareLoadFile2Heap"); int result = 0; context->filContext = a_filInit(memFname, "", "", (c_address)NULL, 0); HERE("filContext initialised"); result = a_filReadHeader(context->filContext); if (result) { HERE("Header read success"); char *shmName = a_filGetShmName(context->filContext); char *dbName = a_filGetDbName(context->filContext); c_address address = a_filGetShmAddress(context->filContext); long size = a_filGetShmSize(context->filContext); if (shmName) { a_apiSetNewShmName(context, shmName); } if (dbName) { a_apiSetNewDbName(context, dbName); } if (address) { context->address = address; } if (size) { context->size = size; } if ((context->heapMem = (c_address)a_memAlloc(context->size)) != (c_address)NULL) { HERE("malloc success"); result = a_filFile2Heap(context->filContext, context->heapMem); if (result) { HERE("result of a_filFile2Heap: success"); } else { HERE("result of a_filFile2Heap: fail"); } } else { HERE("malloc fail"); result = 0; } } else { HERE("Header read fail"); } return result; }
Constraint_list * declare_constraint_list ( Sequence *S, char *name, int *L, int ne,FILE *fp, int **M) { Constraint_list *CL; CL=vcalloc (1, sizeof ( Constraint_list)); CL->S=S; CL->M=M; if ( name!=NULL) { sprintf ( CL->list_name, "%s", name); } CL->cpu=1; CL->fp=fp; if (L) { HERE ("The USE of L is now Deprecated with Constraint Lists"); exit (0); } CL->ne=ne; CL->entry_len=LIST_N_FIELDS; CL->el_size=sizeof (CLIST_TYPE); CL->matrices_list=declare_char(20,20); CL->weight_field=WE; if ( S)CL->seq_for_quadruplet=vcalloc ( S->nseq, sizeof (int)); CL->Prot_Blast=vcalloc ( 1, sizeof ( Blast_param)); CL->DNA_Blast=vcalloc ( 1, sizeof ( Blast_param)); CL->Pdb_Blast=vcalloc ( 1, sizeof ( Blast_param)); CL->TC=vcalloc (1, sizeof (TC_param)); //New data structure CL->residue_index=declare_residue_index (S); return CL; }
void SYSGEN() // SYSGEN { Exec("CR"); // call of word 0x26ee '(CR)' FREEZE(); // FREEZE _ro_RESTORE_rc_(); // (RESTORE) SYSUTIL(); // SYSUTIL INIT(); // INIT MAKE_st_NAME_gt_(); // MAKE<NAME> _ro_CS_ask__rc_(); // (CS?) Push(0x0100); Push(pp_DTA); // DTA _2_ex__2(); // 2!_2 DOS_dash_DTA(); // DOS-DTA HERE(); // HERE Push(Pop() - 0x0100); // 0x0100 - RECSIZE(); // RECSIZE Store(); // ! WRITENEXT(); // WRITENEXT _ro_SETUP_rc_(); // (SETUP) IsUNRAVEL(); // ?UNRAVEL CLOSE(); // CLOSE IsUNRAVEL(); // ?UNRAVEL }
int check_internal(btree_node *node, uint64_t min, uint64_t max){ int i; int leaf_status = is_leaf(node->children[0]); uint64_t true_max = max; max = node->keys[0]; for(i=0;i<node->n_keys+1;i++){ WARN_ON_ONCE(min > max); if(max > true_max){ HERE(); BREAKPOINT(); } if(leaf_status != is_leaf(node->children[i])){ HERE_FMT("All leaves are not the same depth"); return -1; } int err = check_node(node->children[i], min, max); if(err){ return err; } min = max; max = (i+1 == node->n_keys ? true_max : node->keys[i+1]); } return 0; }
/* - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op */ static void p_ere_exp(struct parse *p) { char c; sopno pos; int count; int count2; sopno subno; int wascaret = 0; assert(MORE()); /* caller should have ensured this */ c = GETNEXT(); pos = HERE(); switch (c) { case '(': REQUIRE(MORE(), REG_EPAREN); p->g->nsub++; subno = p->g->nsub; if (subno < NPAREN) p->pbegin[subno] = HERE(); EMIT(OLPAREN, subno); if (!SEE(')')) p_ere(p, ')'); if (subno < NPAREN) { p->pend[subno] = HERE(); assert(p->pend[subno] != 0); } EMIT(ORPAREN, subno); MUSTEAT(')', REG_EPAREN); break; #ifndef POSIX_MISTAKE case ')': /* happens only if no current unmatched ( */ /* * You may ask, why the ifndef? Because I didn't notice * this until slightly too late for 1003.2, and none of the * other 1003.2 regular-expression reviewers noticed it at * all. So an unmatched ) is legal POSIX, at least until * we can get it fixed. */ SETERROR(REG_EPAREN); break; #endif case '^': EMIT(OBOL, 0); p->g->iflags |= USEBOL; p->g->nbol++; wascaret = 1; break; case '$': EMIT(OEOL, 0); p->g->iflags |= USEEOL; p->g->neol++; break; case '|': SETERROR(REG_EMPTY); break; case '*': case '+': case '?': SETERROR(REG_BADRPT); break; case '.': if (p->g->cflags®_NEWLINE) nonnewline(p); else EMIT(OANY, 0); break; case '[': p_bracket(p); break; case '\\': REQUIRE(MORE(), REG_EESCAPE); c = GETNEXT(); ordinary(p, c); break; case '{': /* okay as ordinary except if digit follows */ REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT); /* FALLTHROUGH */ default: ordinary(p, c); break; } if (!MORE()) return; c = PEEK(); /* we call { a repetition if followed by a digit */ if (!( c == '*' || c == '+' || c == '?' || (c == '{' && MORE2() && isdigit((uch)PEEK2())) )) return; /* no repetition, we're done */ NEXT(); REQUIRE(!wascaret, REG_BADRPT); switch (c) { case '*': /* implemented as +? */ /* this case does not require the (y|) trick, noKLUDGE */ INSERT(OPLUS_, pos); ASTERN(O_PLUS, pos); INSERT(OQUEST_, pos); ASTERN(O_QUEST, pos); break; case '+': INSERT(OPLUS_, pos); ASTERN(O_PLUS, pos); break; case '?': /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ INSERT(OCH_, pos); /* offset slightly wrong */ ASTERN(OOR1, pos); /* this one's right */ AHEAD(pos); /* fix the OCH_ */ EMIT(OOR2, 0); /* offset very wrong... */ AHEAD(THERE()); /* ...so fix it */ ASTERN(O_CH, THERETHERE()); break; case '{': count = p_count(p); if (EAT(',')) { if (isdigit((uch)PEEK())) { count2 = p_count(p); REQUIRE(count <= count2, REG_BADBR); } else /* single number with comma */ count2 = INFINITY; } else /* just a single number */ count2 = count; repeat(p, pos, count, count2); if (!EAT('}')) { /* error heuristics */ while (MORE() && PEEK() != '}') NEXT(); REQUIRE(MORE(), REG_EBRACE); SETERROR(REG_BADBR); } break; } if (!MORE()) return; c = PEEK(); if (!( c == '*' || c == '+' || c == '?' || (c == '{' && MORE2() && isdigit((uch)PEEK2())) ) ) return; SETERROR(REG_BADRPT); }
main() { /* ADVENTURE (REV 2: 20 TREASURES) */ /* HISTORY: ORIGINAL IDEA & 5-TREASURE VERSION (ADVENTURES) BY WILLIE CROWTHER * 15-TREASURE VERSION (ADVENTURE) BY DON WOODS, APRIL-JUNE 1977 * 20-TREASURE VERSION (REV 2) BY DON WOODS, AUGUST 1978 * ERRATA FIXED: 78/12/25 */ /* LOGICAL VARIABLES: * * CLOSED SAYS WHETHER WE'RE ALL THE WAY CLOSED * CLOSNG SAYS WHETHER IT'S CLOSING TIME YET * CLSHNT SAYS WHETHER HE'S READ THE CLUE IN THE ENDGAME * LMWARN SAYS WHETHER HE'S BEEN WARNED ABOUT LAMP GOING DIM * NOVICE SAYS WHETHER HE ASKED FOR INSTRUCTIONS AT START-UP * PANIC SAYS WHETHER HE'S FOUND OUT HE'S TRAPPED IN THE CAVE * WZDARK SAYS WHETHER THE LOC HE'S LEAVING WAS DARK */ #include "funcs.h" /* READ THE DATABASE IF WE HAVE NOT YET DONE SO */ LINES = (long *)calloc(LINSIZ+1,sizeof(long)); if(!LINES){ printf("Not enough memory!\n"); exit(FALSE); } MAP2[1] = 0; if(!SETUP)initialise(); if(SETUP > 0) goto L1; /* UNLIKE EARLIER VERSIONS, ADVENTURE IS NO LONGER RESTARTABLE. (THIS * LETS US GET AWAY WITH MODIFYING THINGS SUCH AS OBJSND(BIRD) WITHOUT * HAVING TO BE ABLE TO UNDO THE CHANGES LATER.) IF A "USED" COPY IS * RERUN, WE COME HERE AND TELL THE PLAYER TO RUN A FRESH COPY. */ RSPEAK(201); exit(FALSE); /* START-UP, DWARF STUFF */ L1: SETUP= -1; I=RAN(-1); ZZWORD=RNDVOC(3,0)+MESH*2; NOVICE=YES(65,1,0); NEWLOC=1; LOC=1; LIMIT=330; if(NOVICE)LIMIT=1000; /* CAN'T LEAVE CAVE ONCE IT'S CLOSING (EXCEPT BY MAIN OFFICE). */ L2: if(!OUTSID(NEWLOC) || NEWLOC == 0 || !CLOSNG) goto L71; RSPEAK(130); NEWLOC=LOC; if(!PANIC)CLOCK2=15; PANIC=TRUE; /* SEE IF A DWARF HAS SEEN HIM AND HAS COME FROM WHERE HE WANTS TO GO. IF SO, * THE DWARF'S BLOCKING HIS WAY. IF COMING FROM PLACE FORBIDDEN TO PIRATE * (DWARVES ROOTED IN PLACE) LET HIM GET OUT (AND ATTACKED). */ L71: if(NEWLOC == LOC || FORCED(LOC) || CNDBIT(LOC,3)) goto L74; /* 73 */ for (I=1; I<=5; I++) { if(ODLOC[I] != NEWLOC || !DSEEN[I]) goto L73; NEWLOC=LOC; RSPEAK(2); goto L74; L73: /*etc*/ ; } /* end loop */ L74: LOC=NEWLOC; /* DWARF STUFF. SEE EARLIER COMMENTS FOR DESCRIPTION OF VARIABLES. REMEMBER * SIXTH DWARF IS PIRATE AND IS THUS VERY DIFFERENT EXCEPT FOR MOTION RULES. */ /* FIRST OFF, DON'T LET THE DWARVES FOLLOW HIM INTO A PIT OR A WALL. ACTIVATE * THE WHOLE MESS THE FIRST TIME HE GETS AS FAR AS THE HALL OF MISTS (LOC 15). * IF NEWLOC IS FORBIDDEN TO PIRATE (IN PARTICULAR, IF IT'S BEYOND THE TROLL * BRIDGE), BYPASS DWARF STUFF. THAT WAY PIRATE CAN'T STEAL RETURN TOLL, AND * DWARVES CAN'T MEET THE BEAR. ALSO MEANS DWARVES WON'T FOLLOW HIM INTO DEAD * END IN MAZE, BUT C'EST LA VIE. THEY'LL WAIT FOR HIM OUTSIDE THE DEAD END. */ if(LOC == 0 || FORCED(LOC) || CNDBIT(NEWLOC,3)) goto L2000; if(DFLAG != 0) goto L6000; if(INDEEP(LOC))DFLAG=1; goto L2000; /* WHEN WE ENCOUNTER THE FIRST DWARF, WE KILL 0, 1, OR 2 OF THE 5 DWARVES. IF * ANY OF THE SURVIVORS IS AT LOC, REPLACE HIM WITH THE ALTERNATE. */ L6000: if(DFLAG != 1) goto L6010; if(!INDEEP(LOC) || (PCT(95) && (!CNDBIT(LOC,4) || PCT(85)))) goto L2000; DFLAG=2; /* 6001 */ for (I=1; I<=2; I++) { J=1+RAN(5); L6001: if(PCT(50))DLOC[J]=0; } /* end loop */ /* 6002 */ for (I=1; I<=5; I++) { if(DLOC[I] == LOC)DLOC[I]=DALTLC; L6002: ODLOC[I]=DLOC[I]; } /* end loop */ RSPEAK(3); DROP(AXE,LOC); goto L2000; /* THINGS ARE IN FULL SWING. MOVE EACH DWARF AT RANDOM, EXCEPT IF HE'S SEEN US * HE STICKS WITH US. DWARVES STAY DEEP INSIDE. IF WANDERING AT RANDOM, * THEY DON'T BACK UP UNLESS THERE'S NO ALTERNATIVE. IF THEY DON'T HAVE TO * MOVE, THEY ATTACK. AND, OF COURSE, DEAD DWARVES DON'T DO MUCH OF ANYTHING. */ L6010: DTOTAL=0; ATTACK=0; STICK=0; /* 6030 */ for (I=1; I<=6; I++) { if(DLOC[I] == 0) goto L6030; /* FILL TK ARRAY WITH ALL THE PLACES THIS DWARF MIGHT GO. */ J=1; KK=DLOC[I]; KK=KEY[KK]; if(KK == 0) goto L6016; L6012: NEWLOC=MOD(IABS(TRAVEL[KK])/1000,1000); {long x = J-1; if(NEWLOC > 300 || !INDEEP(NEWLOC) || NEWLOC == ODLOC[I] || (J > 1 && NEWLOC == TK[x]) || J >= 20 || NEWLOC == DLOC[I] || FORCED(NEWLOC) || (I == 6 && CNDBIT(NEWLOC,3)) || IABS(TRAVEL[KK])/1000000 == 100) goto L6014;} TK[J]=NEWLOC; J=J+1; L6014: KK=KK+1; {long x = KK-1; if(TRAVEL[x] >= 0) goto L6012;} L6016: TK[J]=ODLOC[I]; if(J >= 2)J=J-1; J=1+RAN(J); ODLOC[I]=DLOC[I]; DLOC[I]=TK[J]; DSEEN[I]=(DSEEN[I] && INDEEP(LOC)) || (DLOC[I] == LOC || ODLOC[I] == LOC); if(!DSEEN[I]) goto L6030; DLOC[I]=LOC; if(I != 6) goto L6027; /* THE PIRATE'S SPOTTED HIM. HE LEAVES HIM ALONE ONCE WE'VE FOUND CHEST. K * COUNTS IF A TREASURE IS HERE. IF NOT, AND TALLY=1 FOR AN UNSEEN CHEST, LET * THE PIRATE BE SPOTTED. NOTE THAT PLACE(CHEST)=0 MIGHT MEAN THAT HE'S * THROWN IT TO THE TROLL, BUT IN THAT CASE HE'S SEEN THE CHEST (PROP=0). */ if(LOC == CHLOC || PROP[CHEST] >= 0) goto L6030; K=0; /* 6020 */ for (J=50; J<=MAXTRS; J++) { /* PIRATE WON'T TAKE PYRAMID FROM PLOVER ROOM OR DARK ROOM (TOO EASY!). */ if(J == PYRAM && (LOC == PLAC[PYRAM] || LOC == PLAC[EMRALD])) goto L6020; if(TOTING(J)) goto L6021; L6020: if(HERE(J))K=1; } /* end loop */ if(TALLY == 1 && K == 0 && PLACE[CHEST] == 0 && HERE(LAMP) && PROP[LAMP] == 1) goto L6025; if(ODLOC[6] != DLOC[6] && PCT(20))RSPEAK(127); goto L6030; L6021: if(PLACE[CHEST] != 0) goto L6022; /* INSTALL CHEST ONLY ONCE, TO INSURE IT IS THE LAST TREASURE IN THE LIST. */ MOVE(CHEST,CHLOC); MOVE(MESSAG,CHLOC2); L6022: RSPEAK(128); /* 6023 */ for (J=50; J<=MAXTRS; J++) { if(J == PYRAM && (LOC == PLAC[PYRAM] || LOC == PLAC[EMRALD])) goto L6023; if(AT(J) && FIXED[J] == 0)CARRY(J,LOC); if(TOTING(J))DROP(J,CHLOC); L6023: /*etc*/ ; } /* end loop */ L6024: DLOC[6]=CHLOC; ODLOC[6]=CHLOC; DSEEN[6]=FALSE; goto L6030; L6025: RSPEAK(186); MOVE(CHEST,CHLOC); MOVE(MESSAG,CHLOC2); goto L6024; /* THIS THREATENING LITTLE DWARF IS IN THE ROOM WITH HIM! */ L6027: DTOTAL=DTOTAL+1; if(ODLOC[I] != DLOC[I]) goto L6030; ATTACK=ATTACK+1; if(KNFLOC >= 0)KNFLOC=LOC; if(RAN(1000) < 95*(DFLAG-2))STICK=STICK+1; L6030: /*etc*/ ; } /* end loop */ /* NOW WE KNOW WHAT'S HAPPENING. LET'S TELL THE POOR SUCKER ABOUT IT. * NOTE THAT VARIOUS OF THE "KNIFE" MESSAGES MUST HAVE SPECIFIC RELATIVE * POSITIONS IN THE RSPEAK DATABASE. */ if(DTOTAL == 0) goto L2000; SETPRM(1,DTOTAL,0); RSPEAK(4+1/DTOTAL); if(ATTACK == 0) goto L2000; if(DFLAG == 2)DFLAG=3; SETPRM(1,ATTACK,0); K=6; if(ATTACK > 1)K=250; RSPEAK(K); SETPRM(1,STICK,0); RSPEAK(K+1+2/(1+STICK)); if(STICK == 0) goto L2000; OLDLC2=LOC; goto L99; /* DESCRIBE THE CURRENT LOCATION AND (MAYBE) GET NEXT COMMAND. */ /* PRINT TEXT FOR CURRENT LOC. */ L2000: if(LOC == 0) goto L99; KK=STEXT[LOC]; if(MOD(ABB[LOC],ABBNUM) == 0 || KK == 0)KK=LTEXT[LOC]; if(FORCED(LOC) || !DARK(0)) goto L2001; if(WZDARK && PCT(35)) goto L90; KK=RTEXT[16]; L2001: if(TOTING(BEAR))RSPEAK(141); SPEAK(KK); K=1; if(FORCED(LOC)) goto L8; if(LOC == 33 && PCT(25) && !CLOSNG)RSPEAK(7); /* PRINT OUT DESCRIPTIONS OF OBJECTS AT THIS LOCATION. IF NOT CLOSING AND * PROPERTY VALUE IS NEGATIVE, TALLY OFF ANOTHER TREASURE. RUG IS SPECIAL * CASE; ONCE SEEN, ITS PROP IS 1 (DRAGON ON IT) TILL DRAGON IS KILLED. * SIMILARLY FOR CHAIN; PROP IS INITIALLY 1 (LOCKED TO BEAR). THESE HACKS * ARE BECAUSE PROP=0 IS NEEDED TO GET FULL SCORE. */ if(DARK(0)) goto L2012; ABB[LOC]=ABB[LOC]+1; I=ATLOC[LOC]; L2004: if(I == 0) goto L2012; OBJ=I; if(OBJ > 100)OBJ=OBJ-100; if(OBJ == STEPS && TOTING(NUGGET)) goto L2008; if(PROP[OBJ] >= 0) goto L2006; if(CLOSED) goto L2008; PROP[OBJ]=0; if(OBJ == RUG || OBJ == CHAIN)PROP[OBJ]=1; TALLY=TALLY-1; /* NOTE: THERE USED TO BE A TEST HERE TO SEE WHETHER THE PLAYER HAD BLOWN IT * SO BADLY THAT HE COULD NEVER EVER SEE THE REMAINING TREASURES, AND IF SO * THE LAMP WAS ZAPPED TO 35 TURNS. BUT THE TESTS WERE TOO SIMPLE-MINDED; * THINGS LIKE KILLING THE BIRD BEFORE THE SNAKE WAS GONE (CAN NEVER SEE * JEWELRY), AND DOING IT "RIGHT" WAS HOPELESS. E.G., COULD CROSS TROLL * BRIDGE SEVERAL TIMES, USING UP ALL AVAILABLE TREASURES, BREAKING VASE, * USING COINS TO BUY BATTERIES, ETC., AND EVENTUALLY NEVER BE ABLE TO GET * ACROSS AGAIN. IF BOTTLE WERE LEFT ON FAR SIDE, COULD THEN NEVER GET EGGS * OR TRIDENT, AND THE EFFECTS PROPAGATE. SO THE WHOLE THING WAS FLUSHED. * ANYONE WHO MAKES SUCH A GROSS BLUNDER ISN'T LIKELY TO FIND EVERYTHING * ELSE ANYWAY (SO GOES THE RATIONALISATION). */ L2006: KK=PROP[OBJ]; if(OBJ == STEPS && LOC == FIXED[STEPS])KK=1; PSPEAK(OBJ,KK); L2008: I=LINK[I]; goto L2004; L2009: K=54; L2010: SPK=K; L2011: RSPEAK(SPK); L2012: VERB=0; OLDOBJ=OBJ; OBJ=0; /* CHECK IF THIS LOC IS ELIGIBLE FOR ANY HINTS. IF BEEN HERE LONG ENOUGH, * BRANCH TO HELP SECTION (ON LATER PAGE). HINTS ALL COME BACK HERE EVENTUALLY * TO FINISH THE LOOP. IGNORE "HINTS" < 4 (SPECIAL STUFF, SEE DATABASE NOTES). */ L2600: if(COND[LOC] < CONDS) goto L2603; /* 2602 */ for (HINT=1; HINT<=HNTMAX; HINT++) { if(HINTED[HINT]) goto L2602; if(!CNDBIT(LOC,HINT+10))HINTLC[HINT]= -1; HINTLC[HINT]=HINTLC[HINT]+1; if(HINTLC[HINT] >= HINTS[HINT][1]) goto L40000; L2602: /*etc*/ ; } /* end loop */ /* KICK THE RANDOM NUMBER GENERATOR JUST TO ADD VARIETY TO THE CHASE. ALSO, * IF CLOSING TIME, CHECK FOR ANY OBJECTS BEING TOTED WITH PROP < 0 AND SET * THE PROP TO -1-PROP. THIS WAY OBJECTS WON'T BE DESCRIBED UNTIL THEY'VE * BEEN PICKED UP AND PUT DOWN SEPARATE FROM THEIR RESPECTIVE PILES. DON'T * TICK CLOCK1 UNLESS WELL INTO CAVE (AND NOT AT Y2). */ L2603: if(!CLOSED) goto L2605; if(PROP[OYSTER] < 0 && TOTING(OYSTER))PSPEAK(OYSTER,1); /* 2604 */ for (I=1; I<=100; I++) { L2604: if(TOTING(I) && PROP[I] < 0)PROP[I]= -1-PROP[I]; } /* end loop */ L2605: WZDARK=DARK(0); if(KNFLOC > 0 && KNFLOC != LOC)KNFLOC=0; I=RAN(1); GETIN(WD1,WD1X,WD2,WD2X); /* EVERY INPUT, CHECK "FOOBAR" FLAG. IF ZERO, NOTHING'S GOING ON. IF POS, * MAKE NEG. IF NEG, HE SKIPPED A WORD, SO MAKE IT ZERO. */ L2607: FOOBAR=(FOOBAR>0 ? -FOOBAR : 0); TURNS=TURNS+1; if(TURNS != THRESH) goto L2608; SPEAK(TTEXT[TRNDEX]); TRNLUZ=TRNLUZ+TRNVAL[TRNDEX]/100000; TRNDEX=TRNDEX+1; THRESH= -1; if(TRNDEX <= TRNVLS)THRESH=MOD(TRNVAL[TRNDEX],100000)+1; L2608: if(VERB == SAY && WD2 > 0)VERB=0; if(VERB == SAY) goto L4090; if(TALLY == 0 && INDEEP(LOC) && LOC != 33)CLOCK1=CLOCK1-1; if(CLOCK1 == 0) goto L10000; if(CLOCK1 < 0)CLOCK2=CLOCK2-1; if(CLOCK2 == 0) goto L11000; if(PROP[LAMP] == 1)LIMIT=LIMIT-1; if(LIMIT <= 30 && HERE(BATTER) && PROP[BATTER] == 0 && HERE(LAMP)) goto L12000; if(LIMIT == 0) goto L12400; if(LIMIT <= 30) goto L12200; L19999: K=43; if(LIQLOC(LOC) == WATER)K=70; V1=VOCAB(WD1,-1); V2=VOCAB(WD2,-1); if(V1 == ENTER && (V2 == STREAM || V2 == 1000+WATER)) goto L2010; if(V1 == ENTER && WD2 > 0) goto L2800; if((V1 != 1000+WATER && V1 != 1000+OIL) || (V2 != 1000+PLANT && V2 != 1000+DOOR)) goto L2610; {long x = V2-1000; if(AT(x))WD2=MAKEWD(16152118);} L2610: if(V1 == 1000+CAGE && V2 == 1000+BIRD && HERE(CAGE) && HERE(BIRD))WD1=MAKEWD(301200308); L2620: if(WD1 != MAKEWD(23051920)) goto L2625; IWEST=IWEST+1; if(IWEST == 10)RSPEAK(17); L2625: if(WD1 != MAKEWD( 715) || WD2 == 0) goto L2630; IGO=IGO+1; if(IGO == 10)RSPEAK(276); L2630: I=VOCAB(WD1,-1); if(I == -1) goto L3000; K=MOD(I,1000); KQ=I/1000+1; switch (KQ-1) { case 0: goto L8; case 1: goto L5000; case 2: goto L4000; case 3: goto L2010; } BUG(22); /* GET SECOND WORD FOR ANALYSIS. */ L2800: WD1=WD2; WD1X=WD2X; WD2=0; goto L2620; /* GEE, I DON'T UNDERSTAND. */ L3000: SETPRM(1,WD1,WD1X); RSPEAK(254); goto L2600; /* VERB AND OBJECT ANALYSIS MOVED TO SEPARATE MODULE. */ L4000: I=4000; goto Laction; L4090: I=4090; goto Laction; L5000: I=5000; Laction: switch (action(I)) { case 2: goto L2; case 8: goto L8; case 2000: goto L2000; case 2009: goto L2009; case 2010: goto L2010; case 2011: goto L2011; case 2012: goto L2012; case 2600: goto L2600; case 2607: goto L2607; case 2630: goto L2630; case 2800: goto L2800; case 8000: goto L8000; case 18999: goto L18999; case 19000: goto L19000; } BUG(99); /* RANDOM INTRANSITIVE VERBS COME HERE. CLEAR OBJ JUST IN CASE (SEE "ATTACK"). */ L8000: SETPRM(1,WD1,WD1X); RSPEAK(257); OBJ=0; goto L2600; /* FIGURE OUT THE NEW LOCATION * * GIVEN THE CURRENT LOCATION IN "LOC", AND A MOTION VERB NUMBER IN "K", PUT * THE NEW LOCATION IN "NEWLOC". THE CURRENT LOC IS SAVED IN "OLDLOC" IN CASE * HE WANTS TO RETREAT. THE CURRENT OLDLOC IS SAVED IN OLDLC2, IN CASE HE * DIES. (IF HE DOES, NEWLOC WILL BE LIMBO, AND OLDLOC WILL BE WHAT KILLED * HIM, SO WE NEED OLDLC2, WHICH IS THE LAST PLACE HE WAS SAFE.) */ L8: KK=KEY[LOC]; NEWLOC=LOC; if(KK == 0)BUG(26); if(K == NUL) goto L2; if(K == BACK) goto L20; if(K == LOOK) goto L30; if(K == CAVE) goto L40; OLDLC2=OLDLOC; OLDLOC=LOC; L9: LL=IABS(TRAVEL[KK]); if(MOD(LL,1000) == 1 || MOD(LL,1000) == K) goto L10; if(TRAVEL[KK] < 0) goto L50; KK=KK+1; goto L9; L10: LL=LL/1000; L11: NEWLOC=LL/1000; K=MOD(NEWLOC,100); if(NEWLOC <= 300) goto L13; if(PROP[K] != NEWLOC/100-3) goto L16; L12: if(TRAVEL[KK] < 0)BUG(25); KK=KK+1; NEWLOC=IABS(TRAVEL[KK])/1000; if(NEWLOC == LL) goto L12; LL=NEWLOC; goto L11; L13: if(NEWLOC <= 100) goto L14; if(TOTING(K) || (NEWLOC > 200 && AT(K))) goto L16; goto L12; L14: if(NEWLOC != 0 && !PCT(NEWLOC)) goto L12; L16: NEWLOC=MOD(LL,1000); if(NEWLOC <= 300) goto L2; if(NEWLOC <= 500) goto L30000; RSPEAK(NEWLOC-500); NEWLOC=LOC; goto L2; /* SPECIAL MOTIONS COME HERE. LABELLING CONVENTION: STATEMENT NUMBERS NNNXX * (XX=00-99) ARE USED FOR SPECIAL CASE NUMBER NNN (NNN=301-500). */ L30000: NEWLOC=NEWLOC-300; switch (NEWLOC) { case 1: goto L30100; case 2: goto L30200; case 3: goto L30300; } BUG(20); /* TRAVEL 301. PLOVER-ALCOVE PASSAGE. CAN CARRY ONLY EMERALD. NOTE: TRAVEL * TABLE MUST INCLUDE "USELESS" ENTRIES GOING THROUGH PASSAGE, WHICH CAN NEVER * BE USED FOR ACTUAL MOTION, BUT CAN BE SPOTTED BY "GO BACK". */ L30100: NEWLOC=99+100-LOC; if(HOLDNG == 0 || (HOLDNG == 1 && TOTING(EMRALD))) goto L2; NEWLOC=LOC; RSPEAK(117); goto L2; /* TRAVEL 302. PLOVER TRANSPORT. DROP THE EMERALD (ONLY USE SPECIAL TRAVEL IF * TOTING IT), SO HE'S FORCED TO USE THE PLOVER-PASSAGE TO GET IT OUT. HAVING * DROPPED IT, GO BACK AND PRETEND HE WASN'T CARRYING IT AFTER ALL. */ L30200: DROP(EMRALD,LOC); goto L12; /* TRAVEL 303. TROLL BRIDGE. MUST BE DONE ONLY AS SPECIAL MOTION SO THAT * DWARVES WON'T WANDER ACROSS AND ENCOUNTER THE BEAR. (THEY WON'T FOLLOW THE * PLAYER THERE BECAUSE THAT REGION IS FORBIDDEN TO THE PIRATE.) IF * PROP(TROLL)=1, HE'S CROSSED SINCE PAYING, SO STEP OUT AND BLOCK HIM. * (STANDARD TRAVEL ENTRIES CHECK FOR PROP(TROLL)=0.) SPECIAL STUFF FOR BEAR. */ L30300: if(PROP[TROLL] != 1) goto L30310; PSPEAK(TROLL,1); PROP[TROLL]=0; MOVE(TROLL2,0); MOVE(TROLL2+100,0); MOVE(TROLL,PLAC[TROLL]); MOVE(TROLL+100,FIXD[TROLL]); JUGGLE(CHASM); NEWLOC=LOC; goto L2; L30310: NEWLOC=PLAC[TROLL]+FIXD[TROLL]-LOC; if(PROP[TROLL] == 0)PROP[TROLL]=1; if(!TOTING(BEAR)) goto L2; RSPEAK(162); PROP[CHASM]=1; PROP[TROLL]=2; DROP(BEAR,NEWLOC); FIXED[BEAR]= -1; PROP[BEAR]=3; OLDLC2=NEWLOC; goto L99; /* END OF SPECIALS. */ /* HANDLE "GO BACK". LOOK FOR VERB WHICH GOES FROM LOC TO OLDLOC, OR TO OLDLC2 * IF OLDLOC HAS FORCED-MOTION. K2 SAVES ENTRY -> FORCED LOC -> PREVIOUS LOC. */ L20: K=OLDLOC; if(FORCED(K))K=OLDLC2; OLDLC2=OLDLOC; OLDLOC=LOC; K2=0; if(K == LOC)K2=91; if(CNDBIT(LOC,4))K2=274; if(K2 == 0) goto L21; RSPEAK(K2); goto L2; L21: LL=MOD((IABS(TRAVEL[KK])/1000),1000); if(LL == K) goto L25; if(LL > 300) goto L22; J=KEY[LL]; if(FORCED(LL) && MOD((IABS(TRAVEL[J])/1000),1000) == K)K2=KK; L22: if(TRAVEL[KK] < 0) goto L23; KK=KK+1; goto L21; L23: KK=K2; if(KK != 0) goto L25; RSPEAK(140); goto L2; L25: K=MOD(IABS(TRAVEL[KK]),1000); KK=KEY[LOC]; goto L9; /* LOOK. CAN'T GIVE MORE DETAIL. PRETEND IT WASN'T DARK (THOUGH IT MAY "NOW" * BE DARK) SO HE WON'T FALL INTO A PIT WHILE STARING INTO THE GLOOM. */ L30: if(DETAIL < 3)RSPEAK(15); DETAIL=DETAIL+1; WZDARK=FALSE; ABB[LOC]=0; goto L2; /* CAVE. DIFFERENT MESSAGES DEPENDING ON WHETHER ABOVE GROUND. */ L40: K=58; if(OUTSID(LOC) && LOC != 8)K=57; RSPEAK(K); goto L2; /* NON-APPLICABLE MOTION. VARIOUS MESSAGES DEPENDING ON WORD GIVEN. */ L50: SPK=12; if(K >= 43 && K <= 50)SPK=52; if(K == 29 || K == 30)SPK=52; if(K == 7 || K == 36 || K == 37)SPK=10; if(K == 11 || K == 19)SPK=11; if(VERB == FIND || VERB == INVENT)SPK=59; if(K == 62 || K == 65)SPK=42; if(K == 17)SPK=80; RSPEAK(SPK); goto L2; /* "YOU'RE DEAD, JIM." * * IF THE CURRENT LOC IS ZERO, IT MEANS THE CLOWN GOT HIMSELF KILLED. WE'LL * ALLOW THIS MAXDIE TIMES. MAXDIE IS AUTOMATICALLY SET BASED ON THE NUMBER OF * SNIDE MESSAGES AVAILABLE. EACH DEATH RESULTS IN A MESSAGE (81, 83, ETC.) * WHICH OFFERS REINCARNATION; IF ACCEPTED, THIS RESULTS IN MESSAGE 82, 84, * ETC. THE LAST TIME, IF HE WANTS ANOTHER CHANCE, HE GETS A SNIDE REMARK AS * WE EXIT. WHEN REINCARNATED, ALL OBJECTS BEING CARRIED GET DROPPED AT OLDLC2 * (PRESUMABLY THE LAST PLACE PRIOR TO BEING KILLED) WITHOUT CHANGE OF PROPS. * THE LOOP RUNS BACKWARDS TO ASSURE THAT THE BIRD IS DROPPED BEFORE THE CAGE. * (THIS KLUGE COULD BE CHANGED ONCE WE'RE SURE ALL REFERENCES TO BIRD AND CAGE * ARE DONE BY KEYWORDS.) THE LAMP IS A SPECIAL CASE (IT WOULDN'T DO TO LEAVE * IT IN THE CAVE). IT IS TURNED OFF AND LEFT OUTSIDE THE BUILDING (ONLY IF HE * WAS CARRYING IT, OF COURSE). HE HIMSELF IS LEFT INSIDE THE BUILDING (AND * HEAVEN HELP HIM IF HE TRIES TO XYZZY BACK INTO THE CAVE WITHOUT THE LAMP!). * OLDLOC IS ZAPPED SO HE CAN'T JUST "RETREAT". */ /* THE EASIEST WAY TO GET KILLED IS TO FALL INTO A PIT IN PITCH DARKNESS. */ L90: RSPEAK(23); OLDLC2=LOC; /* OKAY, HE'S DEAD. LET'S GET ON WITH IT. */ L99: if(CLOSNG) goto L95; NUMDIE=NUMDIE+1; if(!YES(79+NUMDIE*2,80+NUMDIE*2,54)) score(0); if(NUMDIE == MAXDIE) score(0); PLACE[WATER]=0; PLACE[OIL]=0; if(TOTING(LAMP))PROP[LAMP]=0; /* 98 */ for (J=1; J<=100; J++) { I=101-J; if(!TOTING(I)) goto L98; K=OLDLC2; if(I == LAMP)K=1; DROP(I,K); L98: /*etc*/ ; } /* end loop */ LOC=3; OLDLOC=LOC; goto L2000; /* HE DIED DURING CLOSING TIME. NO RESURRECTION. TALLY UP A DEATH AND EXIT. */ L95: RSPEAK(131); NUMDIE=NUMDIE+1; score(0); /* HINTS */ /* COME HERE IF HE'S BEEN LONG ENOUGH AT REQUIRED LOC(S) FOR SOME UNUSED HINT. * HINT NUMBER IS IN VARIABLE "HINT". BRANCH TO QUICK TEST FOR ADDITIONAL * CONDITIONS, THEN COME BACK TO DO NEAT STUFF. GOTO 40010 IF CONDITIONS ARE * MET AND WE WANT TO OFFER THE HINT. GOTO 40020 TO CLEAR HINTLC BACK TO ZERO, * 40030 TO TAKE NO ACTION YET. */ L40000: switch (HINT-1) { case 0: goto L40100; case 1: goto L40200; case 2: goto L40300; case 3: goto L40400; case 4: goto L40500; case 5: goto L40600; case 6: goto L40700; case 7: goto L40800; case 8: goto L40900; case 9: goto L41000; } /* CAVE BIRD SNAKE MAZE DARK WITT URN WOODS OGRE * JADE */ BUG(27); L40010: HINTLC[HINT]=0; if(!YES(HINTS[HINT][3],0,54)) goto L2602; SETPRM(1,HINTS[HINT][2],HINTS[HINT][2]); RSPEAK(261); HINTED[HINT]=YES(175,HINTS[HINT][4],54); if(HINTED[HINT] && LIMIT > 30)LIMIT=LIMIT+30*HINTS[HINT][2]; L40020: HINTLC[HINT]=0; L40030: goto L2602; /* NOW FOR THE QUICK TESTS. SEE DATABASE DESCRIPTION FOR ONE-LINE NOTES. */ L40100: if(PROP[GRATE] == 0 && !HERE(KEYS)) goto L40010; goto L40020; L40200: if(PLACE[BIRD] == LOC && TOTING(ROD) && OLDOBJ == BIRD) goto L40010; goto L40030; L40300: if(HERE(SNAKE) && !HERE(BIRD)) goto L40010; goto L40020; L40400: if(ATLOC[LOC] == 0 && ATLOC[OLDLOC] == 0 && ATLOC[OLDLC2] == 0 && HOLDNG > 1) goto L40010; goto L40020; L40500: if(PROP[EMRALD] != -1 && PROP[PYRAM] == -1) goto L40010; goto L40020; L40600: goto L40010; L40700: if(DFLAG == 0) goto L40010; goto L40020; L40800: if(ATLOC[LOC] == 0 && ATLOC[OLDLOC] == 0 && ATLOC[OLDLC2] == 0) goto L40010; goto L40030; L40900: I=ATDWRF(LOC); if(I < 0) goto L40020; if(HERE(OGRE) && I == 0) goto L40010; goto L40030; L41000: if(TALLY == 1 && PROP[JADE] < 0) goto L40010; goto L40020; /* CAVE CLOSING AND SCORING */ /* THESE SECTIONS HANDLE THE CLOSING OF THE CAVE. THE CAVE CLOSES "CLOCK1" * TURNS AFTER THE LAST TREASURE HAS BEEN LOCATED (INCLUDING THE PIRATE'S * CHEST, WHICH MAY OF COURSE NEVER SHOW UP). NOTE THAT THE TREASURES NEED NOT * HAVE BEEN TAKEN YET, JUST LOCATED. HENCE CLOCK1 MUST BE LARGE ENOUGH TO GET * OUT OF THE CAVE (IT ONLY TICKS WHILE INSIDE THE CAVE). WHEN IT HITS ZERO, * WE BRANCH TO 10000 TO START CLOSING THE CAVE, AND THEN SIT BACK AND WAIT FOR * HIM TO TRY TO GET OUT. IF HE DOESN'T WITHIN CLOCK2 TURNS, WE CLOSE THE * CAVE; IF HE DOES TRY, WE ASSUME HE PANICS, AND GIVE HIM A FEW ADDITIONAL * TURNS TO GET FRANTIC BEFORE WE CLOSE. WHEN CLOCK2 HITS ZERO, WE BRANCH TO * 11000 TO TRANSPORT HIM INTO THE FINAL PUZZLE. NOTE THAT THE PUZZLE DEPENDS * UPON ALL SORTS OF RANDOM THINGS. FOR INSTANCE, THERE MUST BE NO WATER OR * OIL, SINCE THERE ARE BEANSTALKS WHICH WE DON'T WANT TO BE ABLE TO WATER, * SINCE THE CODE CAN'T HANDLE IT. ALSO, WE CAN HAVE NO KEYS, SINCE THERE IS A * GRATE (HAVING MOVED THE FIXED OBJECT!) THERE SEPARATING HIM FROM ALL THE * TREASURES. MOST OF THESE PROBLEMS ARISE FROM THE USE OF NEGATIVE PROP * NUMBERS TO SUPPRESS THE OBJECT DESCRIPTIONS UNTIL HE'S ACTUALLY MOVED THE * OBJECTS. */ /* WHEN THE FIRST WARNING COMES, WE LOCK THE GRATE, DESTROY THE BRIDGE, KILL * ALL THE DWARVES (AND THE PIRATE), REMOVE THE TROLL AND BEAR (UNLESS DEAD), * AND SET "CLOSNG" TO TRUE. LEAVE THE DRAGON; TOO MUCH TROUBLE TO MOVE IT. * FROM NOW UNTIL CLOCK2 RUNS OUT, HE CANNOT UNLOCK THE GRATE, MOVE TO ANY * LOCATION OUTSIDE THE CAVE, OR CREATE THE BRIDGE. NOR CAN HE BE * RESURRECTED IF HE DIES. NOTE THAT THE SNAKE IS ALREADY GONE, SINCE HE GOT * TO THE TREASURE ACCESSIBLE ONLY VIA THE HALL OF THE MT. KING. ALSO, HE'S * BEEN IN GIANT ROOM (TO GET EGGS), SO WE CAN REFER TO IT. ALSO ALSO, HE'S * GOTTEN THE PEARL, SO WE KNOW THE BIVALVE IS AN OYSTER. *AND*, THE DWARVES * MUST HAVE BEEN ACTIVATED, SINCE WE'VE FOUND CHEST. */ L10000: PROP[GRATE]=0; PROP[FISSUR]=0; /* 10010 */ for (I=1; I<=6; I++) { DSEEN[I]=FALSE; L10010: DLOC[I]=0; } /* end loop */ MOVE(TROLL,0); MOVE(TROLL+100,0); MOVE(TROLL2,PLAC[TROLL]); MOVE(TROLL2+100,FIXD[TROLL]); JUGGLE(CHASM); if(PROP[BEAR] != 3)DSTROY(BEAR); PROP[CHAIN]=0; FIXED[CHAIN]=0; PROP[AXE]=0; FIXED[AXE]=0; RSPEAK(129); CLOCK1= -1; CLOSNG=TRUE; goto L19999; /* ONCE HE'S PANICKED, AND CLOCK2 HAS RUN OUT, WE COME HERE TO SET UP THE * STORAGE ROOM. THE ROOM HAS TWO LOCS, HARDWIRED AS 115 (NE) AND 116 (SW). * AT THE NE END, WE PLACE EMPTY BOTTLES, A NURSERY OF PLANTS, A BED OF * OYSTERS, A PILE OF LAMPS, RODS WITH STARS, SLEEPING DWARVES, AND HIM. AT * THE SW END WE PLACE GRATE OVER TREASURES, SNAKE PIT, COVEY OF CAGED BIRDS, * MORE RODS, AND PILLOWS. A MIRROR STRETCHES ACROSS ONE WALL. MANY OF THE * OBJECTS COME FROM KNOWN LOCATIONS AND/OR STATES (E.G. THE SNAKE IS KNOWN TO * HAVE BEEN DESTROYED AND NEEDN'T BE CARRIED AWAY FROM ITS OLD "PLACE"), * MAKING THE VARIOUS OBJECTS BE HANDLED DIFFERENTLY. WE ALSO DROP ALL OTHER * OBJECTS HE MIGHT BE CARRYING (LEST HE HAVE SOME WHICH COULD CAUSE TROUBLE, * SUCH AS THE KEYS). WE DESCRIBE THE FLASH OF LIGHT AND TRUNDLE BACK. */ L11000: PROP[BOTTLE]=PUT(BOTTLE,115,1); PROP[PLANT]=PUT(PLANT,115,0); PROP[OYSTER]=PUT(OYSTER,115,0); OBJTXT[OYSTER]=3; PROP[LAMP]=PUT(LAMP,115,0); PROP[ROD]=PUT(ROD,115,0); PROP[DWARF]=PUT(DWARF,115,0); LOC=115; OLDLOC=115; NEWLOC=115; /* LEAVE THE GRATE WITH NORMAL (NON-NEGATIVE) PROPERTY. REUSE SIGN. */ I=PUT(GRATE,116,0); I=PUT(SIGN,116,0); OBJTXT[SIGN]=OBJTXT[SIGN]+1; PROP[SNAKE]=PUT(SNAKE,116,1); PROP[BIRD]=PUT(BIRD,116,1); PROP[CAGE]=PUT(CAGE,116,0); PROP[ROD2]=PUT(ROD2,116,0); PROP[PILLOW]=PUT(PILLOW,116,0); PROP[MIRROR]=PUT(MIRROR,115,0); FIXED[MIRROR]=116; /* 11010 */ for (I=1; I<=100; I++) { L11010: if(TOTING(I))DSTROY(I); } /* end loop */ RSPEAK(132); CLOSED=TRUE; goto L2; /* ANOTHER WAY WE CAN FORCE AN END TO THINGS IS BY HAVING THE LAMP GIVE OUT. * WHEN IT GETS CLOSE, WE COME HERE TO WARN HIM. WE GO TO 12000 IF THE LAMP * AND FRESH BATTERIES ARE HERE, IN WHICH CASE WE REPLACE THE BATTERIES AND * CONTINUE. 12200 IS FOR OTHER CASES OF LAMP DYING. 12400 IS WHEN IT GOES * OUT. EVEN THEN, HE CAN EXPLORE OUTSIDE FOR A WHILE IF DESIRED. */ L12000: RSPEAK(188); PROP[BATTER]=1; if(TOTING(BATTER))DROP(BATTER,LOC); LIMIT=LIMIT+2500; LMWARN=FALSE; goto L19999; L12200: if(LMWARN || !HERE(LAMP)) goto L19999; LMWARN=TRUE; SPK=187; if(PLACE[BATTER] == 0)SPK=183; if(PROP[BATTER] == 1)SPK=189; RSPEAK(SPK); goto L19999; L12400: LIMIT= -1; PROP[LAMP]=0; if(HERE(LAMP))RSPEAK(184); goto L19999; /* OH DEAR, HE'S DISTURBED THE DWARVES. */ L18999: RSPEAK(SPK); L19000: RSPEAK(136); score(0); }
/// Function name : findNextXMLToken // Description : Retrieve the next XML token from an XML string using an XML tokeniser // // XML_TOKENISER* pOutput : [in/out] XML Tokeniser containing the input string. On output this will contain the next token. // ERROR_STACK* &pError : [out] New Error message, if any // // Return Value : FALSE if there are no more tokens. /// NOTE: This function does not return FALSE if there is an error, you must check 'pError' for that. // BOOL findNextXMLToken(XML_TOKENISER* pOutput, ERROR_STACK* &pError) { CONST TCHAR *szTokenEnd, // Marks the end of the token *szTokenStart; // Marks the beginning of the token TRY { // Prepare szTokenStart = pOutput->szNextToken; pError = NULL; /// [NO MORE TOKENS] Return FALSE if (!szTokenStart OR !szTokenStart[0]) { pOutput->szText[0] = NULL; pOutput->iCount = NULL; return FALSE; } // Determine whether token is a tag or not pOutput->eType = (szTokenStart[0] == '<' ? XTT_OPENING_TAG : XTT_TEXT); // [CHECK] Is this a comment tag? if (utilCompareStringN(szTokenStart, "<!--", 4)) { /// [COMMENT] Search for the closing comment brace if (szTokenEnd = utilFindSubString(&szTokenStart[3], "-->")) { pOutput->eType = XTT_COMMENT_TAG; szTokenEnd += 2; // Position 'TokenEnd' at the '>' character } else // [ERROR] "An unclosed <%s> tag was detected in the attached XML snippet from line %d of '%s'" pError = generateDualError(HERE(IDS_XML_UNCLOSED_OPENING_TAG), TEXT("comment"), pOutput->iLineNumber, pOutput->szFileName); } // [CHECK] Is this a character-data block? else if (utilCompareStringN(szTokenStart, "<![CDATA[", 9)) { /// [CHARACTER DATA] Search for the closing character data brace if (szTokenEnd = utilFindSubString(&szTokenStart[3], "]]>")) { pOutput->eType = XTT_COMMENT_TAG; szTokenEnd += 2; // Position 'TokenEnd' at the '>' character } else // [ERROR] "An unclosed <%s> tag was detected in the attached XML snippet from line %d of '%s'" pError = generateDualError(HERE(IDS_XML_UNCLOSED_OPENING_TAG), TEXT("!CDATA"), pOutput->iLineNumber, pOutput->szFileName); } else /// [NON-COMMENT] Search for closing tag (or an illegal opening tag) szTokenEnd = utilFindCharacterInSet(&szTokenStart[1], "<>"); // [NON-FINAL TOKEN] if (!pError AND szTokenEnd) { // Examine token type switch (pOutput->eType) { /// [TAG] Determine tag type and extract without the angle brackets case XTT_OPENING_TAG: // [CHECK] Ensure tags finish with '>' if (szTokenEnd[0] == '<') { // [ERROR] "An unexpected opening tag '<' character was detected in the attached XML snippet from line %d of '%s'" pError = generateDualError(HERE(IDS_XML_UNEXPECTED_OPENING_BRACKET), pOutput->iLineNumber, pOutput->szFileName); break; } /// Identify tag type // [CLOSING] Indicated by the tag starting with '</' if (szTokenStart[1] == '/') pOutput->eType = XTT_CLOSING_TAG; // [SELF CLOSING] Indicated by the tag ending with '/>' else if (szTokenEnd[-1] == '/') pOutput->eType = XTT_SELF_CLOSING_TAG; // [COMMENT] Indicated by the tag starting with '<!' else if (szTokenStart[1] == '!') pOutput->eType = XTT_COMMENT_TAG; // [SCHEMA] Indicated by the tag starting with '<?' else if (szTokenStart[1] == '?') pOutput->eType = XTT_SCHEMA_TAG; // Fall through... /// [COMMENT TAG] Already identified, just copy the text case XTT_COMMENT_TAG: /// Copy and measure tag (without the special characters) switch (pOutput->eType) { /// [OPENING TAG] Copy without < and > case XTT_OPENING_TAG: pOutput->iCount = max(0, szTokenEnd - szTokenStart - 1); StringCchCopyN(pOutput->szText, MAX_STRING, &szTokenStart[1], pOutput->iCount); break; /// [CLOSING TAG] Copy without </ and > case XTT_CLOSING_TAG: pOutput->iCount = max(0, szTokenEnd - szTokenStart - 2); StringCchCopyN(pOutput->szText, MAX_STRING, &szTokenStart[2], pOutput->iCount); break; /// [SELF CLOSING TAG] Copy with < and /> case XTT_SELF_CLOSING_TAG: pOutput->iCount = max(0, szTokenEnd - szTokenStart - 2); StringCchCopyN(pOutput->szText, MAX_STRING, &szTokenStart[1], pOutput->iCount); break; /// [COMMENT TAG] Copy without <!-- and --> case XTT_COMMENT_TAG: pOutput->iCount = max(0, szTokenEnd - szTokenStart - 6); StringCchCopyN(pOutput->szText, MAX_STRING, &szTokenStart[4], pOutput->iCount); break; /// [SCHEMA TAG] Copy without <? and ?> case XTT_SCHEMA_TAG: pOutput->iCount = max(0, szTokenEnd - szTokenStart - 3); StringCchCopyN(pOutput->szText, MAX_STRING, &szTokenStart[2], pOutput->iCount); break; } // Set 'next token' as the character beyond the end of the tag pOutput->szNextToken = &szTokenEnd[1]; break; /// [TEXT] Extract tag and identify whitespace case XTT_TEXT: #ifdef BUG_FIX // [CHECK] Ensure text finishes with '<' if (szTokenEnd[0] == '>') { // [ERROR] "An unexpected closing tag '>' character was detected in the attached XML snippet from line %d of '%s'" pError = generateDualError(HERE(IDS_XML_UNEXPECTED_CLOSING_BRACKET), pOutput->iLineNumber, pOutput->szFileName); attachXMLToError(pError, szTokenStart); break; } #endif // [CHECK] Ensure text finishes with '<' if (szTokenEnd[0] == '>') /// [FIX] BUG:002 'You receieve multiple 'an unexpected close tag was detected' errors when loading scripts created by eXscriptor for the first time' { //// [ERROR] "An unexpected closing tag '>' character was detected in the attached XML snippet from line %d of '%s'" //pError = generateDualWarning(HERE(IDS_XML_UNEXPECTED_CLOSING_BRACKET), pOutput->iLineNumber, pOutput->szFileName); // Search for next opening character szTokenEnd = utilFindCharacter(&szTokenEnd[1], '<'); ASSERT(szTokenEnd); } // Measure text pOutput->iCount = (szTokenEnd - szTokenStart); /// [CHECK] Attempt to copy string if (pOutput->iCount >= MAX_STRING OR StringCchCopyN(pOutput->szText, MAX_STRING, szTokenStart, pOutput->iCount) != S_OK) // [ERROR] "A string exceeding 32,768 characters was detected on line %d of '%s', this is not supported by X-Studio" pError = generateDualError(HERE(IDS_XML_TEXT_EXCEEDS_BUFFER), pOutput->iLineNumber, pOutput->szFileName); // [CHECK] Check for character entities else if (utilFindSubString(pOutput->szText, "&#")) // [FOUND] Replace entities pOutput->iCount = performXMLCharacterEntityReplacement(pOutput->szText, pOutput->iCount); // Set 'next token' as the start of the next tag pOutput->szNextToken = szTokenEnd; break; } } // [FINAL TOKEN] Set the next token to NULL else { // Set next token to NULL pOutput->szNextToken = NULL; /// Extract final token text StringCchCopy(pOutput->szText, MAX_STRING, szTokenStart); pOutput->iCount = lstrlen(pOutput->szText); } /// [WHITESPACE] Determine whether text is whitespace if (pOutput->eType == XTT_TEXT AND isStringWhitespace(pOutput->szText)) pOutput->eType = XTT_WHITESPACE; /// [LINE NUMBER] Calculate the new line number pOutput->iLineNumber += calculateCharacterCountInString(pOutput->szText, '\n'); // [FIX] BUG:1018 'Errors produced by findNextXMLToken() don't have a Line number in any of the messages' /// [NEW TAG] Create node from token if (!pOutput->bBlocking AND (pOutput->eType == XTT_OPENING_TAG OR pOutput->eType == XTT_SELF_CLOSING_TAG)) pOutput->pNode = createXMLTreeNode(pOutput); // [ERROR] Append XML snippets to all errors if (pError) { // Append XML snippet generateOutputTextFromError(pError); attachXMLToError(pError, szTokenStart, (szTokenStart - pOutput->szSource)); // Skip beyond token pOutput->szNextToken = &szTokenEnd[1]; // Zero any existing token pOutput->szText[0] = NULL; pOutput->iCount = 0; } // Return TRUE to indicate there are more tokens, even if an error occurred return TRUE; } CATCH0("Unable to retrieve next token"); return FALSE; }
/// Function name : generateXMLTree // Description : Generate an XML Tree from an input string of XML // // CONST TCHAR* szXML : [in] Input string containing the XML // CONST UINT iInputLength : [in] Length of input string, in characters // CONST TCHAR* szFileName : [in] Filename [Only used for error reporting] // HWND hParentWnd : [in] Ignored // XML_TREE* &pOutput : [out] New XMLTree, You are responsible for destroying it // OPERATION_PROGRESS* pProgress : [in/out][optional] Operation progress object, if feedback is required // ERROR_QUEUE* pErrorQueue : [in/out] Error message queue // // Return Value : OR_SUCCESS - File was parsed successfully, any errors were ignored by the user // OR_ABORTED - File was NOT parsed successfully due to the user aborting after minor errors // BearScriptAPI OPERATION_RESULT generateXMLTree(CONST TCHAR* szXML, CONST UINT iInputLength, CONST TCHAR* szFileName, HWND hParentWnd, XML_TREE* &pOutput, OPERATION_PROGRESS* pProgress, ERROR_QUEUE* pErrorQueue) { OPERATION_RESULT eResult; // Operation result XML_TOKENISER* pToken; // XML token currently being processed XML_TAG_STACK* pStack; // XML parse stack XML_TREE_NODE* pCurrentNode; // Parent for the node currently being processed ERROR_STACK* pError; // Current error, if any // Prepare eResult = OR_SUCCESS; pError = NULL; __try { // Prepare pOutput = createXMLTree(); pCurrentNode = pOutput->pRoot; // Create parsing objects pToken = createXMLTokeniser(szFileName, szXML); pStack = createXMLTagStack(); // [OPTIONAL] Define progress based on the number of pages processed if (pProgress) updateOperationProgressMaximum(pProgress, iInputLength); // Iterate through tokens while (findNextXMLToken(pToken, pError)) { // Update progress object, if present if (pProgress) updateOperationProgressValue(pProgress, pToken->szNextToken - pToken->szSource); // [CHECK] Ensure token was parsed succesfully if (!pError) { switch (pToken->eType) { /// [COMMENT, SCHEMA, WHITESPACE] Ignore... case XTT_COMMENT_TAG: case XTT_CDATA_TAG: case XTT_SCHEMA_TAG: case XTT_WHITESPACE: continue; /// [TAG/TEXT] Process if unblocked, skip otherwise case XTT_OPENING_TAG: case XTT_SELF_CLOSING_TAG: case XTT_CLOSING_TAG: case XTT_TEXT: // [BLOCKING] Skip all tags until </sourcetext> is found if (pToken->bBlocking) { if (pToken->eType != XTT_CLOSING_TAG OR !utilCompareString(pToken->szText, "sourcetext")) continue; pToken->bBlocking = FALSE; } // Examine tag switch (pToken->eType) { /// [OPENING TAG] Add tag to stack + Add node to tree + Set as 'current node' case XTT_OPENING_TAG: // Push tag onto stack pushXMLTagStack(pStack, pToken); // Append new node to 'CurrentNode' + Update 'CurrentNode' appendChildToXMLTreeNode(pOutput, pCurrentNode, pToken->pNode); //pNewNode = createXMLTreeNode(pCurrentNode, pToken); pCurrentNode = pToken->pNode; // [BLOCK] Skip all tags within <sourcetext> if (utilCompareString(pToken->szText, "sourcetext")) pToken->bBlocking = TRUE; break; /// [SELF CLOSING TAG] Add node to tree case XTT_SELF_CLOSING_TAG: // Append new node to 'CurrentNode' appendChildToXMLTreeNode(pOutput, pCurrentNode, pToken->pNode); // pNewNode = createXMLTreeNode(pCurrentNode, pToken); break; /// [CLOSING TAG] Ensure tag matches the currently open tag case XTT_CLOSING_TAG: // [CHECK] Ensure stack isn't empty if (!getStackItemCount(pStack)) // [ERROR] "An unexpected closing tag </%s> was detected on line %d of '%s'" pError = generateDualError(HERE(IDS_XML_UNEXPECTED_CLOSING_TAG), pToken->szText, pToken->iLineNumber, pToken->szFileName); // [CHECK] Ensure tags match else if (utilCompareStringVariables(pToken->szText, topXMLTagStack(pStack))) { // [SUCCESS] Remove matching tag. Set parent as 'Current' popXMLTagStack(pStack); pCurrentNode = pCurrentNode->pParent; } else // [ERROR] "The closing tag </%s> on line %d does not match the currently open <%s> tag in '%s'" pError = generateDualError(HERE(IDS_XML_MISMATCHED_CLOSING_TAG), pToken->szText, pToken->iLineNumber, topXMLTagStack(pStack), pToken->szFileName); break; /// [TEXT] Save text in the current node case XTT_TEXT: // [CHECK] Ensure stack isn't empty / Node doesn't already have text if (getStackItemCount(pStack) AND !pCurrentNode->szText) // [SUCCESS] Save node text pCurrentNode->szText = utilDuplicateString(pToken->szText, pToken->iCount); else // [ERROR] "Unexpected text '%s' was detected on line %d of '%s'" pError = generateDualError(HERE(IDS_XML_UNEXPECTED_TEXT), pToken->szText, pToken->iLineNumber, pToken->szFileName); break; } // END: switch (pToken->eType) } // [DEBUG] //debugXMLToken(pToken); /// [SYNTAX ERROR] "A minor error has been detected in the syntax of the XML file '%s'" if (pError) { generateOutputTextFromError(pError); //enhanceError(pError, ERROR_ID(IDS_XML_MINOR_SYNTAX_ERROR), szFileName); attachXMLToError(pError, pToken->szNextToken, pToken->szNextToken - pToken->szSource); } } // END: if (!pError) /*else /// [PARSE ERROR] "A minor error has occurred while parsing the XML file '%s'" enhanceError(pError, ERROR_ID(IDS_XML_MINOR_PARSING_ERROR), szFileName);*/ // [ERROR] Abort if (pError) { pushErrorQueue(pErrorQueue, pError); eResult = OR_FAILURE; break; } } // END: while (findNextXMLToken(pToken, pError)) /// [CHECK] Detect any open tags remaining while (eResult == OR_SUCCESS AND getStackItemCount(pStack)) { // [WARNING] "An unclosed <%s> tag was detected on an unknown line of '%s'" pushErrorQueue(pErrorQueue, generateDualWarning(HERE(IDS_XML_UNCLOSED_TAG_REMAINING), topXMLTagStack(pStack), pToken->szFileName)); generateOutputTextFromLastError(pErrorQueue); popXMLTagStack(pStack); } // Cleanup and return result deleteXMLTagStack(pStack); deleteXMLTokeniser(pToken); return eResult; //// [ERROR] Destroy output tree //if (eResult != OR_SUCCESS) // deleteXMLTree(pOutput); } __except (pushException(pErrorQueue)) { EXCEPTION3("Unable to parse XML file '%s' at token '%s' on line %u", szFileName, pToken->szText, pToken->iLineNumber); return OR_FAILURE; } }
void plotSFspec(int iBr=0, int iBin=0, int doSave=0, double transLegendY_user=0., int vsEt=1) { TString fname; TString label1,label2,label3; TString sfKindLongStr; //TString sfKind; double transLegendX=-0.2; double transLegendY=-0.4; TString saveFileTag; label1="stat.error"; label2="stat.+syst.err."; label3="stat.+syst.err.+add.syst.err"; if (iBr==0) { fname="./egammaRECO.root"; sfKindLongStr="sf_RECO_ETBINS6ETABINS5"; saveFileTag="-cmpEgammaRECO"; transLegendX=-0.23; //transLegendY=-0.2; } if (iBr==1) { fname="./mediumID.root"; sfKindLongStr="sf_mediumID_ETBINS6ETABINS5"; saveFileTag="-cmpEgammaMediumID"; transLegendX=-0.23; //transLegendY=-0.2; } //if (!vsEt) saveFileTag.Append("-vsEta"); if (transLegendY_user!=0.) transLegendY=transLegendY_user; /* if (iBr==0) sfKind="ID"; else if (iBr==1) sfKind="RECO"; else if (iBr==2) sfKind="HLT"; else { std::cout << "iBr error\n"; return; } */ DYTools::TEtBinSet_t etBinSet=DetermineEtBinSet(sfKindLongStr); DYTools::TEtaBinSet_t etaBinSet=DetermineEtaBinSet(sfKindLongStr); int nEtBins=DYTools::getNEtBins(etBinSet); int nEtaBins=DYTools::getNEtaBins(etaBinSet); std::cout << "sets: "<< EtBinSetName(etBinSet) << "," << EtaBinSetName(etaBinSet) << "\n"; TString effKind =effDataKindString(sfKindLongStr); TString dataKind=effKind; TMatrixD *sf=NULL, *sf1ErrLo=NULL, *sf1ErrHi=NULL; TMatrixD *systRelErr=NULL, sf2ErrLo(nEtBins,nEtaBins), sf2ErrHi(nEtBins,nEtaBins); TMatrixD *systRelErrTot=NULL, sf3ErrLo(nEtBins,nEtaBins), sf3ErrHi(nEtBins,nEtaBins); // load the scale factors if (!loadEGammaEff(fname,"sf",&sf,&sf1ErrLo,&sf1ErrHi)) { std::cout << "failed to load EGammaSf\n"; return; } HERE("load egamma ok"); systRelErr=loadMatrix(fname,"sf_syst_rel_error_egamma",nEtBins,nEtaBins,1); if (!systRelErr) return; systRelErrTot=loadMatrix(fname,"sf_syst_rel_error",nEtBins,nEtaBins,1); if (!systRelErrTot) return; HERE("add errors"); addInQuadrature(*sf,*sf1ErrLo, *systRelErr, sf2ErrLo); addInQuadrature(*sf,*sf1ErrHi, *systRelErr, sf2ErrHi); addInQuadrature(*sf,*sf1ErrLo, *systRelErrTot, sf3ErrLo); addInQuadrature(*sf,*sf1ErrHi, *systRelErrTot, sf3ErrHi); HERE("create graphs"); TGraphAsymmErrors* gr1=getAsymGraph(vsEt, etBinSet,etaBinSet,iBin,*sf,*sf1ErrLo,*sf1ErrHi); gr1->GetXaxis()->SetMoreLogLabels(); gr1->GetXaxis()->SetNoExponent(); gr1->Print("range"); TGraphAsymmErrors* gr2=getAsymGraph(vsEt, etBinSet,etaBinSet,iBin,*sf,sf2ErrLo,sf2ErrHi); gr2->GetXaxis()->SetMoreLogLabels(); gr2->GetXaxis()->SetNoExponent(); gr2->Print("range"); TGraphAsymmErrors* gr3=getAsymGraph(vsEt, etBinSet,etaBinSet,iBin,*sf,sf3ErrLo,sf3ErrHi); gr3->GetXaxis()->SetMoreLogLabels(); gr3->GetXaxis()->SetNoExponent(); gr3->Print("range"); double *loc_etBinLimits=DYTools::getEtBinLimits(etBinSet); double *loc_etaBinLimits=DYTools::getEtaBinLimits(etaBinSet); int signedEta=DYTools::signedEtaBinning(etaBinSet); TString binStrForTitle=(vsEt) ? TString(Form(" %5.3lf #leq %s #leq %5.3lf",loc_etaBinLimits[iBin],(signedEta)?"#eta":"abs(#eta)",loc_etaBinLimits[iBin+1])) : TString(Form(" %2.0lf #leq #it{E}_{T} #leq %2.0lf GeV",loc_etBinLimits[iBin],loc_etBinLimits[iBin+1])); TString cpTitle=dataKind+ binStrForTitle; TString xAxisTitle="#it{E}_{T} [GeV]"; if (!vsEt) xAxisTitle=(signedEta) ? "#eta" : "|#eta|"; ComparisonPlot_t cp(ComparisonPlot_t::_ratioPlain,"comp",cpTitle, xAxisTitle,effKind + TString(" scale factor"),"ratio"); cp.SetRefIdx(-111); // no ratio plot if (vsEt) cp.SetLogx(); cp.AddLine(10.,1.,500.,1.,kBlack,2); TCanvas *cx=new TCanvas("cx","cx",600,600); SetSideSpaces(cx,0.05,0.,0.,0.02); gr1->GetYaxis()->SetTitleOffset(1.4); //cp.AddGraph(gr3,label3,"LPE",43); //kRed+3); cp.AddGraph(gr3,label3,"LPE",kRed); //kRed+3); cp.AddGraph(gr2,label2,"LPE",38); //kBlue+2); cp.AddGraph(gr1,label1," PE",kBlack,20); //24 cp.Draw(cx,0,"png",0); cp.TransLegend(transLegendX, transLegendY); cp.WidenLegend(0.25,0.); cx->Update(); // Save file if (saveFileTag.Length()) { TString outfname=TString("fig-sf-egamma-") + cpTitle; outfname.ReplaceAll(" #leq "," "); outfname.ReplaceAll(" ","_"); outfname.ReplaceAll("(#eta)","Eta"); outfname.ReplaceAll("#eta","eta"); outfname.ReplaceAll(".","_"); outfname.ReplaceAll("#it{E}_{T}","Et"); //fname.Append(".png"); std::cout << "outfname=" << outfname << "\n"; TString locOutDir=TString("plots") + saveFileTag; if (doSave) { locOutDir.ReplaceAll("--",""); SaveCanvas(cx,outfname,locOutDir); } else { std::cout << "... canvas not saved, as requested\n"; std::cout << " locOutDir=" << locOutDir << "\n"; } } return ; }
int testRooBayesUnf_verB(int analysisIs2D) { if (!DYTools::setup(analysisIs2D)) { std::cout << "failed to initialize the analysis\n"; return retCodeError; } const int markerCount=5; const TAttMarker markerV[markerCount] = { TAttMarker(kBlack,24,1.), TAttMarker(kBlue,20,0.9), TAttMarker(kRed+1,22,0.9), TAttMarker(kGreen+1,4,0.9), TAttMarker(kViolet,3,0.9) }; TString path="../../Results-DYee/root_files_reg/"; TString yieldFName=Form("yield/DY_j22_19712pb_ApplyEscale/bg-subtracted_yield_%dD__peak20140220.root",analysisIs2D+1); TString yieldField="signalYieldDDbkg"; TString yieldFieldSyst="signalYieldDDbkgSyst"; TH2D* h2SigYield=LoadHisto2D(yieldField,path+yieldFName,"",1); if (!h2SigYield) return retCodeError; printHisto(h2SigYield); TH2D* h2SigYieldSyst=LoadHisto2D(yieldFieldSyst,path+yieldFName,"",1); if (!h2SigYieldSyst) return retCodeError; //TString detRespFName=Form("constants/DY_j22_19712pb/detResponse_unfolding_constants%dD.root",analysisIs2D+1); TString detRespName="detResponse"; //detRespName="detResponseExact"; UnfoldingMatrix_t *detResponse= new UnfoldingMatrix_t(UnfoldingMatrix::_cDET_Response,detRespName); if (!detResponse) return retCodeError; TString constDirDef=path + TString("constants/DY_j22_19712pb/"); TString fnameTagDef=UnfoldingMatrix_t::generateFNameTag(DYTools::NO_SYST,0); int res=detResponse->autoLoadFromFile(constDirDef,fnameTagDef); //res=detResponse->autoLoadFromFile_forRooUnfold(constDirDef,fnameTagDef); if (!res) return retCodeError; TH2D* h2Unf= Clone(h2SigYield,"h2Unf"); TH2D* h2UnfSyst= Clone(h2SigYield,"h2UnfSyst"); if (!unfold_reco2true(h2Unf,*detResponse,h2SigYield)) return retCodeError; if (!unfold_reco2true(h2UnfSyst,*detResponse,h2SigYieldSyst)) return retCodeError; TH1D* hSigYield_flat= flattenHisto(h2SigYield,"hSigYield_flat"); TH1D* hUnfYield_flat= flattenHisto(h2Unf, "hUnfYield_flat"); TH1D* hSigYieldSyst_flat= flattenHisto(h2SigYieldSyst,"hSigYieldSyst_flat"); TH1D* hUnfYieldSyst_flat= flattenHisto(h2UnfSyst, "hUnfYieldSyst_flat"); // --------------------------------------------------------------------- // Study part // --------------------------------------------------------------------- // check randomization implementation if (0) { UnfoldingMatrix_t Urnd(*detResponse,"Urnd"); if (!Urnd.randomizeMigrationMatrix(*detResponse,NULL,2,1)) return retCodeError; return retCodeStop; } // Closure test if (0) { UnfoldingMatrix_t *U= detResponse; TH2D* h2MCReco= createHisto2D(*U->getFinM(),U->getFinMerr(), "h2MCReco","h2MCReco",0,0,0.); TH1D* hMCReco_flat= flattenHisto(h2MCReco,"hMCReco_flat"); if (!hMCReco_flat) return retCodeError; TH2D* h2MCRecoUnf= Clone(h2MCReco,"h2MCRecoUnf"); if (!unfold_reco2true(h2MCRecoUnf,*detResponse,h2MCReco)) return retCodeError; TH2D* h2MCTrue= createHisto2D(*U->getIniM(),U->getIniMerr(), "h2MCTrue","h2MCTrue",0,0,0.); TH1D* hMCTrue_flat= flattenHisto(h2MCTrue,"hMCTrue_flat"); TH1D* hMCRecoUnf_flat= flattenHisto(h2MCRecoUnf,"hMCRecoUnf_flat"); ComparisonPlot_t *cp= new ComparisonPlot_t("cp","closure", "bin","count","ratio"); printZpeakCount(h2MCReco); printZpeakCount(h2MCTrue); printZpeakCount(h2MCRecoUnf); cp->AddHist1D(hMCReco_flat,"MC reco","LP",TAttMarker(kRed,5,1),1,0,1); cp->AddHist1D(hMCTrue_flat,"MC true (unf) distr", "LP",markerV[0],1,0,1); cp->AddHist1D(hMCRecoUnf_flat,"unf.yield (matrix inv.)", "LP",TAttMarker(kOrange,20,1.),1,0,1); // test TH2D if (1) for (int iStep=1; iStep<=4; ++iStep) { //if (iStep>1) break; TH2D *h2= Clone(h2MCReco,Form("h2Unf_iStep%d",iStep)); if (!doBayesUnfold(h2,NULL,*detResponse,h2MCReco,NULL, iStep)) { return retCodeError; } TH1D* h1= flattenHisto(h2,Form("hUnf_iStep%d_flat",iStep)); printZpeakCount(h1); cp->AddHist1D(h1, Form("rooUnf. (%d steps)",iStep), "LP",markerV[iStep%markerCount],iStep/markerCount+1,0,1); } // test HistoPair if (1) { HistoPair2D_t hpRec("hpRec"); hpRec.assignCentralVals(h2MCReco); for (int iStep=1; iStep<=4; ++iStep) { //if (iStep>1) break; HistoPair2D_t hpUnf(Form("hpUnf_iStep%d",iStep)); if (!doBayesUnfold(hpUnf,*detResponse,hpRec, iStep)) { return retCodeError; } TH1D* h1= flattenHisto(hpUnf.histo(),Form("hUnf_iStep%d_flat",iStep)); printZpeakCount(h1); cp->AddHist1D(h1, Form("rooUnf. (%d steps)",iStep), "LP",markerV[iStep%markerCount],iStep/markerCount+1,0,1); } } HERE("draw"); TCanvas *cx=new TCanvas("cx","cx",800,800); cp->Prepare2Pads(cx); cp->Draw(cx); cx->Update(); return retCodeStop; } // Unfolding test if (1) { UnfoldingMatrix_t *U= detResponse; TH2D* h2MCTrue= createHisto2D(*U->getIniM(),U->getIniMerr(), "h2MCTrue","h2MCTrue",0,0,0.); TH1D* hMCTrue_flat= flattenHisto(h2MCTrue,"hMCTrue_flat"); ComparisonPlot_t *cp= new ComparisonPlot_t("cp","unfolding", "bin","count","ratio"); cp->SetLogy(0); ComparisonPlot_t *cpErr= NULL; ComparisonPlot_t *cpErrSyst= NULL; if (1) { cpErr = new ComparisonPlot_t("cpErr","unfolding error", "bin","count error","ratio"); } if (0) { cpErrSyst = new ComparisonPlot_t("cpErrSyst","unfolding syst.error", "bin","count syst.error","ratio"); } if (1) { cp->AddHist1D(hSigYield_flat,"sig.yield","LP",TAttMarker(kRed,5,1),1,0,1); if (cpErr) { TH1D *h1SigYield_flatErr= Clone(hSigYield_flat,"h1SigYield_flatErr"); setErrorAsContent(h1SigYield_flatErr); cpErr->AddHist1D(h1SigYield_flatErr,"sig.yield","LP", TAttMarker(kRed,5,1),1,0,1); } } hMCTrue_flat->Scale(6.8); if (0) { cp->AddHist1D(hMCTrue_flat,"MC gen distr (scaled)", "LP",markerV[0],1,0,1); if (cpErr) { TH1D *hMCTrue_flatErr= Clone(hMCTrue_flat,"hMCTrue_flatErr"); setErrorAsContent(hMCTrue_flatErr); cpErr->AddHist1D(hMCTrue_flatErr,"MC gen distr (scaled)", "LP",markerV[0],1,0,1); } } if (0) { cp->AddHist1D(hUnfYield_flat,"unf.sig.yield (matrix inv.)", "LP",TAttMarker(kOrange,20,1.),1,0,1); if (cpErr) { TH1D* hUnfYield_flatErr= Clone(hUnfYield_flat,"hUnfYield_flatErr"); setErrorAsContent(hUnfYield_flatErr); cpErr->AddHist1D(hUnfYield_flatErr,"unf.sig.yield (matrix inv.)", "LP",TAttMarker(kOrange,20,1.),1,0,1); } if (cpErrSyst) { TH1D* hUnfYieldSyst_flatErr= Clone(hUnfYieldSyst_flat, "hUnfYieldSyst_flatErr"); setErrorAsContent(hUnfYieldSyst_flatErr); cpErrSyst->AddHist1D(hUnfYieldSyst_flatErr, "unf.sig.yield (matrix inv.)", "LP",TAttMarker(kOrange,20,1.),1,0,1); } } printZpeakCount(h2SigYield); printZpeakCount(hSigYield_flat); printZpeakCount(hUnfYield_flat); if (1) for (int iStep=1; iStep<=4; ++iStep) { //if (iStep!=4) continue; //if (iStep!=10) continue; //if (iStep%2==0) continue; //if (iStep>1) break; TH2D *h2= Clone(h2SigYield,Form("h2Unf_iStep%d",iStep)); if (!doBayesUnfold(h2,NULL,*detResponse,h2SigYield,NULL, iStep)) { return retCodeError; } TH1D* h1= flattenHisto(h2,Form("hUnf_iStep%d_flat",iStep)); printZpeakCount(h1); //std::cout << dashline << "iStep=" << iStep << "\n\n"; printHisto(h1); TString loc_label=Form("rooUnf. (%d steps)",iStep); cp->AddHist1D(h1, loc_label, "LP",markerV[iStep%markerCount],iStep/markerCount+1,0,1); if (cpErr) { TH1D *h1err= Clone(h1,Form("hErr_iStep%d",iStep)); setErrorAsContent(h1err); cpErr->AddHist1D(h1err, loc_label, "LP",markerV[iStep%markerCount],iStep/markerCount+1,0,1); } } // Test HistoPair if (0) { HistoPair2D_t hpSigYield("hpSigYield"); hpSigYield.assign(h2SigYield,h2SigYieldSyst,0); for (int iStep=1; iStep<=4; ++iStep) { if (iStep<2) continue; //if (iStep!=4) continue; //if (iStep!=10) continue; //if (iStep%2==0) continue; //if (iStep>1) break; HistoPair2D_t hpUnf(Form("hpUnf_iStep%d",iStep)); if (!doBayesUnfold(hpUnf,*detResponse,hpSigYield, iStep)) { return retCodeError; } TH1D* h1= flattenHisto(hpUnf.histo(),Form("hUnf_iStep%d_flat",iStep)); printZpeakCount(h1); //std::cout << dashline << "iStep=" << iStep << "\n\n"; printHisto(h1); TString loc_label=Form("rooUnf. (%d steps)",iStep); cp->AddHist1D(h1, loc_label, "LP",markerV[iStep%markerCount],iStep/markerCount+1,0,1); if (cpErr) { TH1D *h1err= Clone(h1,Form("hErr_iStep%d",iStep)); setErrorAsContent(h1err); cpErr->AddHist1D(h1err, loc_label, "LP",markerV[iStep%markerCount],iStep/markerCount+1,0,1); } if (cpErrSyst) { TH1D *h1errSyst_flat= flattenHisto(hpUnf.histoSystErr(), Form("h1errSyst_flat_iStep%d",iStep)); TH1D *h1errSyst= Clone(h1errSyst_flat,Form("hErrSyst_iStep%d",iStep)); setErrorAsContent(h1errSyst); cpErrSyst->AddHist1D(h1errSyst, loc_label, "LP",markerV[iStep%markerCount],iStep/markerCount+1,0,1); } } } HERE("draw"); TCanvas *cx=new TCanvas("cx","cx",800,800); cp->Prepare2Pads(cx); cp->Draw(cx); cx->Update(); if (cpErr) { TCanvas *cxErr=new TCanvas("cxErr","cxErr",800,800); cpErr->Prepare2Pads(cxErr); cpErr->Draw(cxErr); cxErr->Update(); } if (cpErrSyst) { TCanvas *cxErrSyst=new TCanvas("cxErrSyst","cxErrSyst",800,800); cpErrSyst->Prepare2Pads(cxErrSyst); cpErrSyst->Draw(cxErrSyst); cxErrSyst->Update(); } return retCodeStop; } return retCodeOk; }
/* Part of a_apiPrepare: * Copies Shared Memory to Heap */ static int a_apiPrepareCopyShm2Heap( a_apiContext context) { FUNC("a_apiPrepareCopyShm2Heap"); /* Use origShmContext for attaching the original shm: */ a_shmContext origShmContext; context->error = A_ERR_OK; origShmContext = a_shmInit(context->out, context->err, context->shmName); if ( a_shmAttach(origShmContext) ) { HERE("attached"); // shm is attached, now determine start address: context->address = a_shmGetShmAddress(origShmContext); HERE("startAddress acquired"); assert(context->address); if ( a_bseOpenBase(context->bseContext, context->address) ) { HERE("base opened"); context->size = (long)a_keyGetSize(context->keyContext, context->shmName); // printf("size: %ld (0x%X)\n", context->size, (unsigned int)context->size); HERE("size acquired, going to copy shm mem to heap:"); //printf("[a_apiPrepare] address = 0x%X, size = %ld (0x%X)\n", // (unsigned int)context->address, context->size, (unsigned int)context->size); // copy shm to heap: assert(context->size); if ((context->heapMem = (c_address)a_memAlloc(context->size)) != (c_address)NULL){ HERE("malloc succesful"); int cpyMemResult; a_utlStopWatchStart(context->utlContext); cpyMemResult = a_memCopyMem((void *)context->heapMem, (void *)context->address, context->size); a_utlStopWatchStop(context->utlContext); context->timerResults->shmCopyMicroSecs = a_utlGetStopWatchTimeMicroSecs(context->utlContext); context->timerResults->shmCopyMilSecs = a_utlGetStopWatchTimeMilSecs(context->utlContext); if (cpyMemResult) { HERE("mem cloned on heap"); // detach (original) shm if ( a_shmDetach(origShmContext) ) { HERE("original shm detached"); //printf("[a_apiPrepare] startAddress = 0x%X, size = 0x%X (%ld)\n", // (unsigned int)startAddress, (unsigned int)size, size); } else { context->error = A_ERR_SHM_DETACH_FAIL; HERE("?could not detach original shm"); } } else { context->error = A_ERR_MEMCOPY_FAIL; HERE("?copy from heap to shm failed"); } } else { HERE("?malloc failed"); context->error = A_ERR_MALLOC_FAIL; } } else { context->error = A_ERR_BASE_OPEN_FAIL; HERE("?base not opened"); } a_shmDeInit(origShmContext); HERE("original shm deinitialised"); } else { HERE("?could not attach to original shm"); context->error = A_ERR_SHM_ATTACH_FAIL; } return (context->error == A_ERR_OK) ? 1 : 0; }
/** * \brief * Prepares the AAPI. * * This operation prepares the AAPI for analysing. It will take * the following actions:\n * \arg Attaches to Shared Memory; * \arg Copies the Shared Memory to Heap, * \arg Detaches the Shared Memory, * \arg Creates a "Private" Shared Memory Segment and * Copies from Heap to the Private Shared Memory. * * \param context * This file's context * * \param memFname * File name of which a copy of the memory should be copied to. The * file may not already exist. If it does, this function will fail. * Specify NULL if you do not wish to save a copy. * * \param loadInsteadOfSave * Boolean setting for specifying you wish to load the shared memory * portion from a file (specified by \a memFname) instead of copying * from a currently existing shared memory segment. If the file does * not exist, this function will fail. If the file you are trying to * load with this operation was not created by this same function, * the outcome is undetermined. If \a memFname is NULL, this * parameter will be ignored. * * \return * Boolean value specifying this operation's success (1) or failure * (0). In case of failure, the internal \a errorno will be set. * * \see * a_apiContext */ int a_apiPrepare( a_apiContext context, char *memFname, int loadInsteadOfSave) { int result; FUNC("a_apiPrepare"); HERE("start"); assert(context); context->error = A_ERR_OK; if (memFname && loadInsteadOfSave) { HERE("want to load file into heap (instead of copy from shm)"); result = a_apiPrepareLoadFile2Heap(context, memFname); if (!result) { context->error = A_ERR_LOAD_FROM_FILE_FAIL; HERE("failed to load file into heap"); } else { HERE("file loaded into heap"); } } else { HERE("want to copy from shm"); result = a_apiPrepareCopyShm2Heap(context); if (!result) { HERE("failed to copy from shm to heap"); context->error = A_ERR_SHM_COPY_TO_HEAP_FAIL; } else { HERE("shm copied to heap"); } } if (result) { HERE("(we now have a copy on heap)"); if (memFname && !loadInsteadOfSave) { HERE("want to save heap to file"); result = a_apiPrepareSaveHeap2File(context, memFname); if (!result) { HERE("save heap to file failed"); context->error = A_ERR_SAVE_TO_FILE_FAIL; } else { HERE("heap to file saved"); } } if (result) { HERE("about to create our own shm"); if ( a_apiPrepareCreateOwnShm(context) ) { HERE("own shm created"); if ( a_bseOpenBase(context->bseContext, context->address) ) { HERE("base opened"); a_lstSetNewOccurrencesArraySize(context->list, a_bseGetStateProperty(context->bseContext, A_BSE_STATE_MAXUSED)); HERE("about to fill list"); // a_apiPatchShm(); a_utlStopWatchStart(context->utlContext); a_anlFillList(context->anlContext, a_bseGetBase(context->bseContext)); a_utlStopWatchStop(context->utlContext); context->timerResults->listFillMilSecs = a_utlGetStopWatchTimeMilSecs(context->utlContext); } else { context->error = A_ERR_BASE_OPEN_FAIL; HERE("open base failed"); } } else { context->error = A_ERR_SHM_CREATE_FAIL; HERE("creation of own shm failed"); } } } if (context->filContext) { a_filDeInit(context->filContext); } result = context->error == A_ERR_OK ? 1 : 0; return result; }
/* - p_simp_re - parse a simple RE, an atom possibly followed by a repetition */ static int /* was the simple RE an unbackslashed $? */ p_simp_re(struct parse *p, int starordinary) /* is a leading * an ordinary character? */ { int c; int count; int count2; sopno pos; int i; sopno subno; # define BACKSL (1<<CHAR_BIT) pos = HERE(); /* repetion op, if any, covers from here */ assert(MORE()); /* caller should have ensured this */ c = GETNEXT(); if (c == '\\') { REQUIRE(MORE(), REG_EESCAPE); c = BACKSL | GETNEXT(); } switch (c) { case '.': if (p->g->cflags®_NEWLINE) nonnewline(p); else EMIT(OANY, 0); break; case '[': p_bracket(p); break; case BACKSL|'{': SETERROR(REG_BADRPT); break; case BACKSL|'(': p->g->nsub++; subno = p->g->nsub; if (subno < NPAREN) p->pbegin[subno] = HERE(); EMIT(OLPAREN, subno); /* the MORE here is an error heuristic */ if (MORE() && !SEETWO('\\', ')')) p_bre(p, '\\', ')'); if (subno < NPAREN) { p->pend[subno] = HERE(); assert(p->pend[subno] != 0); } EMIT(ORPAREN, subno); REQUIRE(EATTWO('\\', ')'), REG_EPAREN); break; case BACKSL|')': /* should not get here -- must be user */ case BACKSL|'}': SETERROR(REG_EPAREN); break; case BACKSL|'1': case BACKSL|'2': case BACKSL|'3': case BACKSL|'4': case BACKSL|'5': case BACKSL|'6': case BACKSL|'7': case BACKSL|'8': case BACKSL|'9': i = (c&~BACKSL) - '0'; assert(i < NPAREN); if (p->pend[i] != 0) { assert(i <= p->g->nsub); EMIT(OBACK_, i); assert(p->pbegin[i] != 0); assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); assert(OP(p->strip[p->pend[i]]) == ORPAREN); (void) dupl(p, p->pbegin[i]+1, p->pend[i]); EMIT(O_BACK, i); } else SETERROR(REG_ESUBREG); p->g->backrefs = 1; break; case '*': REQUIRE(starordinary, REG_BADRPT); /* FALLTHROUGH */ default: ordinary(p, (char)c); break; } if (EAT('*')) { /* implemented as +? */ /* this case does not require the (y|) trick, noKLUDGE */ INSERT(OPLUS_, pos); ASTERN(O_PLUS, pos); INSERT(OQUEST_, pos); ASTERN(O_QUEST, pos); } else if (EATTWO('\\', '{')) { count = p_count(p); if (EAT(',')) { if (MORE() && isdigit((uch)PEEK())) { count2 = p_count(p); REQUIRE(count <= count2, REG_BADBR); } else /* single number with comma */ count2 = INFINITY; } else /* just a single number */ count2 = count; repeat(p, pos, count, count2); if (!EATTWO('\\', '}')) { /* error heuristics */ while (MORE() && !SEETWO('\\', '}')) NEXT(); REQUIRE(MORE(), REG_EBRACE); SETERROR(REG_BADBR); } } else if (c == '$') /* $ (but not \$) ends it */ return(1); return(0); }
/* - repeat - generate code for a bounded repetition, recursively if needed */ static void repeat(struct parse *p, sopno start, /* operand from here to end of strip */ int from, /* repeated from this number */ int to) /* to this number of times (maybe INFINITY) */ { sopno finish = HERE(); # define N 2 # define INF 3 # define REP(f, t) ((f)*8 + (t)) # define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) sopno copy; if (p->error != 0) /* head off possible runaway recursion */ return; assert(from <= to); switch (REP(MAP(from), MAP(to))) { case REP(0, 0): /* must be user doing this */ DROP(finish-start); /* drop the operand */ break; case REP(0, 1): /* as x{1,1}? */ case REP(0, N): /* as x{1,n}? */ case REP(0, INF): /* as x{1,}? */ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ INSERT(OCH_, start); /* offset is wrong... */ repeat(p, start+1, 1, to); ASTERN(OOR1, start); AHEAD(start); /* ... fix it */ EMIT(OOR2, 0); AHEAD(THERE()); ASTERN(O_CH, THERETHERE()); break; case REP(1, 1): /* trivial case */ /* done */ break; case REP(1, N): /* as x?x{1,n-1} */ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ INSERT(OCH_, start); ASTERN(OOR1, start); AHEAD(start); EMIT(OOR2, 0); /* offset very wrong... */ AHEAD(THERE()); /* ...so fix it */ ASTERN(O_CH, THERETHERE()); copy = dupl(p, start+1, finish+1); assert(copy == finish+4); repeat(p, copy, 1, to-1); break; case REP(1, INF): /* as x+ */ INSERT(OPLUS_, start); ASTERN(O_PLUS, start); break; case REP(N, N): /* as xx{m-1,n-1} */ copy = dupl(p, start, finish); repeat(p, copy, from-1, to-1); break; case REP(N, INF): /* as xx{n-1,INF} */ copy = dupl(p, start, finish); repeat(p, copy, from-1, to); break; default: /* "can't happen" */ SETERROR(REG_ASSERT); /* just in case */ break; } }
void compareRndYields(int analysisIs2D=1, TString conf="defaultAdHoc", int iBr=0, int doSave=0, TString *figName=NULL, TString *dirName=NULL) { if (!DYTools::setup(analysisIs2D)) { std::cout << "failed to initialize the analysis\n"; return; } //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== int totalErr=1; int loadSyst=1; int the_set=0; std::vector<TString> pathV; std::vector<TString> fnameV; std::vector<TString> fieldV; std::vector<TString> labelV; TString canvasSaveName, canvasSaveDir; std::vector<HistoPair2D_t*> csV; double set_ratio_y[2]; double transLegendX=(DYTools::study2D==1) ? -0.42 : -0.2; double transLegendY=0.; set_ratio_y[0]=1.00; set_ratio_y[1]=1.00; InputFileMgr_t inpMgr; if (!inpMgr.Load(conf)) return; DYTools::TRunMode_t runMode= DYTools::NORMAL_RUN; DYTools::TSystematicsStudy_t systModeRef, systMode1, systMode2, systModeV; systModeRef=DYTools::APPLY_ESCALE; systMode1 =DYTools::SYST_MODE_FAILURE; systMode2 =DYTools::SYST_MODE_FAILURE; systModeV =DYTools::SYST_MODE_FAILURE; int seedMin=inpMgr.userKeyValueAsInt("SEEDMIN"); int seedMax=inpMgr.userKeyValueAsInt("SEEDMAX"); int dSeed=1; unsigned int idxRndVec=(unsigned int)(-1); //-------------------------------------------------------------------------------------------------------------- // Define branches //============================================================================================================== TString extraTag; TString plotExtraTag; if ((iBr==0) || (iBr==1)) { // added on 2014.04.12 if (iBr==1) { seedMin=-111; seedMax= 111; dSeed= 222; } loadSyst=0; prepare(2,pathV,fnameV,fieldV,labelV); // Construct eventSelector, update mgr and plot directory systModeRef=DYTools::APPLY_ESCALE; EventSelector_t evtSelector1(inpMgr,runMode,systModeRef, extraTag, plotExtraTag, EventSelector::_selectDefault); pathV [0]=""; fnameV[0]=inpMgr.yieldFullFileName(-1,systModeRef,0); fieldV[0]="yields/hYield_data"; labelV[0]="Data with peak corr."; systMode1=DYTools::ESCALE_DIFF_0000; EventSelector_t evtSelector2(inpMgr,runMode,systMode1, extraTag, plotExtraTag, EventSelector::_selectDefault); pathV [1]=""; fnameV[1]=inpMgr.yieldFullFileName(-1,systMode1,0); fieldV[1]="yields/hYield_data"; labelV[1]="Data (regressed)"; prepare(int((seedMax-seedMin)/dSeed),pathV,fnameV,fieldV,labelV,0,0); systModeV=DYTools::ESCALE_STUDY_RND; idxRndVec=pathV.size(); for (int iseed=seedMin; iseed<=seedMax; iseed+=dSeed) { //if ((1 || (dSeed==1)) && (iseed-seedMin>79)) break; //if (iseed-seedMin>2) break; InputFileMgr_t inpMgrRnd(inpMgr); inpMgrRnd.editEnergyScaleTag().Append(Form("_RANDOMIZED%d",iseed)); EventSelector_t evtSelector3(inpMgrRnd,runMode,systModeV, extraTag, plotExtraTag, EventSelector::_selectDefault); pathV.push_back(""); fnameV.push_back(inpMgrRnd.yieldFullFileName(-1,systModeV,0)); fieldV.push_back("yields/hYield_data"); labelV.push_back(Form("Data rnd%d",iseed)); } transLegendX=(DYTools::study2D==1) ? -0.42 : -0.1; } //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== /* { canvasSaveName="fig-puStudy-"; canvasSaveDir="plots-puStudy"; transLegendX=(DYTools::study2D==1) ? -0.35 : -0.1; transLegendY=(DYTools::study2D==1) ? -0.55 : -0.0; set_ratio_y[0]=(DYTools::study2D==1) ? 0.9 : 0.96; set_ratio_y[1]=(DYTools::study2D==1) ? 1.1 : 1.04; } */ if (DYTools::study2D) { for (unsigned int i=0; i<fnameV.size(); ++i) { fnameV[i].ReplaceAll("preFsr_1D","preFsrDet_2D"); } } if (!loadHistoPairV(pathV,fnameV,fieldV,labelV, csV, loadSyst)) { std::cout << "failed to load data\n"; return; } std::vector<TH2D*> histoV; if (!convertHistoPairVec2HistoVec(csV, histoV, totalErr)) { std::cout << "failed to prepare histos\n"; return; } std::vector<ComparisonPlot_t*> cpV; std::vector<std::vector<TH1D*>*> hProfV; int delayDraw=1; TCanvas *cx=plotProfiles("cx",histoV,labelV,NULL,0,"observed yield counts", &hProfV, &cpV,delayDraw); if (!cx) { std::cout << "failed to create canvas with profiles\n"; return; } if (iBr==1) { // shift the notation HERE("shift the notation\n"); for (unsigned int ic=0; ic<cpV.size(); ++ic) { if (DYTools::study2D==0) cpV[ic]->SetLogy(1); TH1D* h1=cpV[ic]->GetHisto(0); h1->SetMarkerStyle(24); h1->SetMarkerColor(kBlue); h1->SetLineColor(kBlue); h1->SetLineStyle(2); TH1D* h2=cpV[ic]->GetHisto(1); h2->SetMarkerStyle(5); h2->SetMarkerColor(kGreen+1); h2->SetMarkerSize(1.5); h2->SetLineStyle(1); h2->SetLineColor(kGreen+1); TH1D* h3=cpV[ic]->GetHisto(2); h3->SetMarkerStyle(3); h3->SetMarkerColor(kOrange+1); h3->SetMarkerSize(1.5); h3->SetLineStyle(3); h3->SetLineColor(kOrange+1); TH1D* h4=cpV[ic]->GetHisto(3); h4->SetMarkerStyle(2); h4->SetMarkerColor(kRed); h4->SetLineStyle(2); h4->SetLineColor(kRed); } } for (unsigned int ic=0; ic<cpV.size(); ++ic) { ComparisonPlot_t *cp=cpV[ic]; cp->TransLegend(transLegendX,transLegendY); cp->SetRatioYRange(set_ratio_y[0], set_ratio_y[1]); if (DYTools::study2D) cp->Draw6(cx,1,ic+1); else cp->Draw(cx); } cx->Update(); // plot count dirstributions of a mass bin if (0 && (DYTools::study2D==0)) { std::cout << "hProfV.size()=" << hProfV.size() << "\n"; std::vector<TH1D*> hMassV; std::vector<TString> massStrV; massStrV.reserve(DYTools::nMassBins); for (int im=0; im<DYTools::nMassBins; ++im) { massStrV.push_back(Form("M_%1.0lf_%1.0lf", DYTools::massBinLimits[im],DYTools::massBinLimits[im+1])); } if (!createAnyH1Vec(hMassV,"hMassProf_",massStrV,200,-1e6,1e6, "yield count","count",1)) return; std::vector<TH1D*> *histos=hProfV[0]; for (int im=14; im<20; im++) { double avg=0.; int count=0; for (unsigned int ii=0; ii<histos->size(); ++ii) { avg+=(*histos)[ii]->GetBinContent(im); count++; } avg/=double(count); for (unsigned int ii=0; ii<histos->size(); ++ii) { hMassV[im]->Fill((*histos)[ii]->GetBinContent(im) - avg); } TString canvName=TString("canvProfAt_") + massStrV[im]; TCanvas *cm=new TCanvas(canvName,canvName,600,600); hMassV[im]->Draw(); cm->Update(); } } TString outName=canvasSaveName + DYTools::analysisTag; if (doSave) { SaveCanvas(cx,outName,canvasSaveDir); } else { std::cout << "would save to <" << outName << "> in <" << canvasSaveDir << ">\n"; } if (figName) *figName= outName; if (dirName) *dirName= canvasSaveDir; // Covariance study if (0) { std::vector<TH2D*> hRndVec; hRndVec.reserve(histoV.size()); for (unsigned int i=idxRndVec; i<histoV.size(); ++i) { hRndVec.push_back(histoV[i]); } int unbiasedEstimate=1; TH2D* avgDistr=createBaseH2("hYieldAvgDistr"); TMatrixD* cov= deriveCovMFromRndStudies(hRndVec,unbiasedEstimate,avgDistr); TMatrixD* corr=corrFromCov(*cov); TCanvas *canvCov= new TCanvas("ccov","ccov",900,900); AdjustFor2DplotWithHeight(canvCov); cov->Draw("COLZ"); canvCov->Update(); TCanvas *canvCorr= new TCanvas("ccorr","ccorr",900,900); AdjustFor2DplotWithHeight(canvCorr); corr->Draw("COLZ"); canvCorr->Update(); } return; }