/* Main function to calculate items sequence */ int DpsCalcBoolItems(DPS_AGENT *query, DPS_RESULT *Res) { DPS_BOOLSTACK *s = DpsBoolStackInit(NULL); DPS_STACK_ITEM *items = Res->items, *res; DPS_WIDEWORD Word; size_t nitems = Res->nitems; size_t i, j; int first_time = (Res->WWList.nwords == 0); if (s == NULL) return DPS_STACK_ERR; if (nitems == 0) { Res->CoordList.Coords = Res->items[0].pbegin; Res->items[0].pbegin = NULL; Res->items[0].count = 0; /* Res->CoordList.ncoords = Res->items[0]->count;*/ DpsBoolStackFree(s); return DPS_OK; } for (i = 0; i < nitems; i++) { if (items[i].cmd != DPS_STACK_WORD) continue; if ((items[i].pbegin == NULL) && ((items[i].origin & DPS_WORD_ORIGIN_STOP) == 0)) { for(j = 0; j < i; j++) if (items[j].crcword == items[i].crcword) break; if (j < i) { items[i].count = items[j].count; items[i].pbegin = (DPS_URL_CRD_DB*)DpsMalloc((items[j].count + 1) * sizeof(DPS_URL_CRD_DB)); if (items[i].pbegin == NULL) { DpsLog(query, DPS_LOG_ERROR, "Can't alloc %d bytes %s:%d", (items[j].count + 1) * sizeof(DPS_URL_CRD_DB), __FILE__, __LINE__); DpsBoolStackFree(s); return DPS_STACK_ERR; } { register size_t z; for (z = 0; z < items[i].count; z++) { items[i].pbegin[z] = items[j].pbegin[z]; items[i].pbegin[z].coord &= 0xFFFFFF00; items[i].pbegin[z].coord += (items[i].wordnum & 0xFF); } } } } if (first_time) { Word.order = items[i].order; Word.count = items[i].count; Word.crcword = items[i].crcword; Word.word = items[i].word; Word.uword = items[i].uword; Word.origin = items[i].origin; DpsWideWordListAdd(&Res->WWList, &Word, DPS_WWL_LOOSE); } } #ifdef DEBUG_BOOL DpsLog(query, DPS_LOG_EXTRA, "--------"); for(i=0;i<nitems;i++){ DpsLog(query, DPS_LOG_EXTRA, "[%d].%d %c : %d -- %s", i, items[i].wordnum, item_type(items[i].cmd), items[i].count, (items[i].word == NULL) ? "<NULL>" : items[i].word); } DpsLog(query, DPS_LOG_EXTRA, "--------"); #endif for(i=0;i<nitems;i++){ int c; #ifdef DEBUG_BOOL DpsLog(query, DPS_LOG_EXTRA, ".[%d].%d %c : %d -- %s, (order_origin:%d)", i, items[i].wordnum, item_type(items[i].cmd), items[i].count, (items[i].word == NULL) ? "<NULL>" : items[i].word, items[i].order_origin); #endif switch(c=items[i].cmd){ case DPS_STACK_RIGHT: /* Perform till LEFT bracket */ while((TOPCMD(s) != DPS_STACK_LEFT) && (TOPCMD(s) != DPS_STACK_BOT)) if (DPS_OK != perform(query, Res, s, POPCMD(s))) { DpsBoolStackFree(s); return DPS_STACK_ERR; } /* Pop LEFT bracket itself */ if(TOPCMD(s) == DPS_STACK_LEFT) POPCMD(s); break; case DPS_STACK_OR: case DPS_STACK_AND: case DPS_STACK_NEAR: case DPS_STACK_ANYWORD: if (s->nastack > 1) while(c <= TOPCMD(s)) { if (DPS_OK != perform(query, Res, s, POPCMD(s))) { DpsBoolStackFree(s); return DPS_STACK_ERR; } } /* IMPORTANT! No break here! That's OK*/ /* Так надо ! */ case DPS_STACK_LEFT: case DPS_STACK_PHRASE_LEFT: case DPS_STACK_NOT: if (PUSHCMD(s,c) != DPS_OK) { DpsBoolStackFree(s); return DPS_STACK_ERR; } break; case DPS_STACK_PHRASE_RIGHT: /* perform till RIGHT phrase quote */ while((TOPCMD(s) != DPS_STACK_PHRASE_LEFT) && (TOPCMD(s) != DPS_STACK_BOT)) if (DPS_OK != perform(query, Res, s, POPCMD(s))) { DpsBoolStackFree(s); return DPS_STACK_ERR; } if (TOPCMD(s) == DPS_STACK_PHRASE_LEFT) perform(query, Res, s, POPCMD(s)); #ifdef DEBUG_BOOL DpsLog(query, DPS_LOG_EXTRA, "[%d] %c", i, item_type(items[i].cmd)); #endif break; case DPS_STACK_WORD: items[i].order_from = items[i].order_to = items[i].order; default: if (DPS_OK != PUSHARG(s, &items[i])) { DpsBoolStackFree(s); return DPS_STACK_ERR; } items[i].pbegin = items[i].plast = NULL; /*items[i].word = NULL; items[i].uword = NULL;*/ /* items[i].count = 0;*/ /* DpsStackItemFree(&items[i]);*/ /* if (DPS_OK != PUSHARG(s, (count[items[i].order]) ? 1UL : 0UL)) { DpsBoolStackFree(s); return DPS_STACK_ERR; }*/ break; } } while(TOPCMD(s) != DPS_STACK_BOT) { if (DPS_OK != perform(query, Res, s, POPCMD(s))) { DpsBoolStackFree(s); return DPS_STACK_ERR; } } res = POPARG(s); if (res != NULL) { Res->CoordList.Coords = res->pbegin; Res->CoordList.ncoords = res->count; res->pbegin = res->plast = NULL; /* res->count = 0;*/ DpsStackItemFree(res); } #ifdef DEBUG_BOOL DpsLog(query, DPS_LOG_EXTRA, "result: %x", res); #endif DpsBoolStackFree(s); return DPS_OK; }
/* Main function to calculate items sequence */ int UdmCalcBoolItems(UDM_STACK_ITEM *items, size_t nitems, char *count) { UDM_BOOLSTACK s; int res; size_t i; /* Init stack */ s.ncstack= 0; s.nastack= 0; s.mcstack= s.mastack = UDM_MAXSTACK; s.cstack= (int*)UdmMalloc(UDM_MAXSTACK * sizeof(int)); s.astack= (unsigned long*)UdmMalloc(UDM_MAXSTACK * sizeof(unsigned long)); #ifdef DEBUG_BOOL for (i= 0; i < nitems; i++) { fprintf(stderr, "[%d]cmd=%d arg=%d\n", i, items[i].cmd, (int)items[i].arg); } #endif #ifdef DEBUG_BOOL fprintf(stderr,"--------\n"); #endif for(i= 0; i < nitems; i++) { int c; #ifdef DEBUG_BOOL fprintf(stderr,".[%d] %c\n", i, item_type(items[i].cmd, items[i].arg)); #endif switch((c= items[i].cmd)) { case UDM_STACK_RIGHT: /* Perform till LEFT bracket */ while((TOPCMD(&s)!=UDM_STACK_LEFT)&&(TOPCMD(&s)!=UDM_STACK_BOT)) perform(&s,POPCMD(&s)); /* Pop LEFT bracket itself */ if(TOPCMD(&s)==UDM_STACK_LEFT) POPCMD(&s); break; case UDM_STACK_OR: case UDM_STACK_AND: while(c<=TOPCMD(&s)) perform(&s,POPCMD(&s)); /* IMPORTANT! No break here! That's OK*/ /* Так надо ! */ case UDM_STACK_LEFT: case UDM_STACK_NOT: PUSHCMD(&s,c); break; case UDM_STACK_PHRASE: PUSHARG(&s, (count[items[i+1].arg]) ? 1UL : 0UL); for (i++; items[i].cmd != UDM_STACK_PHRASE; i++) #ifdef DEBUG_BOOL fprintf(stderr,"[%d] %c\n", i, item_type(items[i].cmd, count[items[i].arg])); fprintf(stderr,"[%d] %c\n", i, item_type(items[i].cmd, count[items[i].arg])); #endif ; break; case UDM_STACK_STOP: PUSHARG(&s, 1UL); break; case UDM_STACK_WORD: PUSHARG(&s, (count[items[i].arg]) ? 1UL : 0UL); break; default: UDM_ASSERT(0); } } while(TOPCMD(&s) != UDM_STACK_BOT) perform(&s, POPCMD(&s)); res= POPARG(&s); UDM_FREE(s.cstack); UDM_FREE(s.astack); #ifdef DEBUG_BOOL fprintf(stderr, "result: %d\n", res); #endif return res; }