static int _emailaddr_cmp(emailaddr *a, emailaddr *b) { int res; res = strnncmp(a->data, a->local_offset, b->data, b->local_offset); if (res != 0) return res; res = strnncmp(a->data + a->local_offset, VARSIZE(a) - offsetof(emailaddr, data) - a->local_offset, b->data + b->local_offset, VARSIZE(b) - offsetof(emailaddr, data) - b->local_offset); return res; }
int main(void) { int res; pthread_t a_thread; void *thread_result; res = sem_init(&bin_sem, 0, 0); if(res != 0) { perror("Semaphore initialization failed"); exit(EXIT_FAILURE); } res = pthread_create(&a_thread, NULL, thread_function, NULL); if(res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); } printf("Input some text. Enter 'end' to finish\n"); while(strnncmp("end", work_area, 3) != 0) { fgets(work_area, WORK_SIZE, stdin); sem_post(&bin_sem); } printf("\nWaiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if(res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } printf("Thread joined\n"); sem_destroy(&bin_sem); exit(EXIT_SUCCESS); }
static LTI *aa_find(LTI **t,char *name,int len,int *insert) { // find/insert node into t LTI *lti=NULL; int iter=(*insert)&ITER; int dir=(*insert)&1; if ((*t)==&aa_sentinel) lti=((*insert)&INSERT)?(*t)=LTI_init(NEW(LTI),name,len):NULL; else { int delta=0; for (int i=0;delta==0 && i<PREVIEWLEN && i<len && i<(*t)->len;i++) delta=name[i]-(*t)->preview[i]; if (!delta) // preview matched, compare full strings delta=strnncmp(name,len,(*t)->name,(*t)->len); int deltadir=delta<0?LEFT:RIGHT; // turn LTZ/Z/GTZ into left/right/right if (delta) { if (LTI_invalid(lti=aa_find(&(*t)->lnk[deltadir],name,len,insert)) && iter && dir!=deltadir) lti=*t; } else if (iter) // matches, but find next smaller/larger lti=aa_most((*t)->lnk[dir],!dir); else // return match lti=(*t),(*insert)=0; } if ((*insert)&INSERT) { // rebalance if necessary aa_skew(t); aa_split(t); } return lti; }
/* Like strcmp(S1, S2), but limit length of S1 to SZ1 and of S2 to SZ2. */ static int strnncmp(char *s1, size_t sz1, char *s2, size_t sz2) { int res; if (sz1 == sz2) return strncmp(s1, s2, sz2); if (sz1 < sz2) return -strnncmp(s2, sz2, s1, sz1); res = strncmp(s1, s2, sz2); return res ? res : s1[sz2]; }
// remove is non-aa-canonical... // a: traverse down to leaf, looking for matches along the way // b: if there's a match, clip leaf and return thru to matching node // c: matching node swaps, and then returns matching node to caller static LTI *aa_remove(LTI **t,char *name,int len,int match) { LTI *result=NULL; if (LTI_invalid(*t)) return &aa_sentinel; // descend tree, finding matching node ("toremove") and then "next-greater" leaf ("tokeep") int delta=0; for (int i=0;delta==0 && i<PREVIEWLEN && i<len && i<(*t)->len;i++) delta=name[i]-(*t)->preview[i]; if (!delta) // preview matched, compare full strings delta=strnncmp(name,len,(*t)->name,(*t)->len); result=aa_remove(&(*t)->lnk[delta<0?LEFT:RIGHT],name,len,match|!delta); if (!delta) { // matching node if (result!=&aa_sentinel) { // swap with leaf... result->lnk[LEFT]=(*t)->lnk[LEFT]; result->lnk[RIGHT]=(*t)->lnk[RIGHT]; (*t)->lnk[LEFT]=&aa_sentinel; (*t)->lnk[RIGHT]=&aa_sentinel; } LTI *newresult=(*t); (*t)=result; result=newresult; } else if (match && result==&aa_sentinel) { result=*t; *t=&aa_sentinel; } cleanup: // on the way back, re rebalance if (!LTI_invalid(*t)) { if (((*t)->lnk[LEFT]->level < ((*t)->level-1)) || ((*t)->lnk[RIGHT]->level < ((*t)->level-1))) { (*t)->level--; if ((*t)->lnk[RIGHT]->level > (*t)->level) (*t)->lnk[RIGHT]->level = (*t)->level; aa_skew(t); aa_skew(&(*t)->lnk[RIGHT]); aa_skew(&(*t)->lnk[RIGHT]->lnk[RIGHT]); aa_split(t); aa_split(&(*t)->lnk[RIGHT]); } } done: return result; }
/* * Evaluate compiled conditions in array @np[@ncond]. * Return non-zero iff they are all true. * @ptr points to a context object of the type that was used to compile * the conditions. */ int nstr_exec(struct nscstr *np, int ncond, void *ptr) { int i, op, cmp; enum nsc_type optype; struct valstr lft, rgt; for (i = 0; i < ncond; ++i) { op = np[i].operator; optype = np[i].optype; if (np[i].lft.val_cat == NSC_NOCAT || np[i].rgt.val_cat == NSC_NOCAT) return 0; lft = np[i].lft; nstr_eval(&lft, player->cnum, ptr, optype); rgt = np[i].rgt; nstr_eval(&rgt, player->cnum, ptr, optype); if (CANT_HAPPEN(lft.val_type != optype || rgt.val_type != optype)) return 0; switch (optype) { case NSC_LONG: if (!EVAL(op, lft.val_as.lng, rgt.val_as.lng)) return 0; break; case NSC_DOUBLE: if (!EVAL(op, lft.val_as.dbl, rgt.val_as.dbl)) return 0; break; case NSC_STRING: cmp = strnncmp(lft.val_as.str.base, lft.val_as.str.maxsz, rgt.val_as.str.base, rgt.val_as.str.maxsz); if (!EVAL(op, cmp, 0)) return 0; break; default: CANT_REACH(); return 0; } } return 1; }