/* Procedure servicing the ioctl */ long c2_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) { //TODO: Locking is probably required since we don't run under BKL anymore. // Although it isn't possible to open the c2 device twice, a single // process with multiple threads might be abble to issue simultaneous // ioctls() --DI long buf; unsigned char cbuf; int err=0,ret; if (_IOC_TYPE(cmd) != C2_IOC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > C2_IOC_MAXNR) return -ENOTTY; if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); else if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); if (err) return -EFAULT; switch(_IOC_NR(cmd)) { case _IOC_NR(C2_IOCRESET): //printk(KERN_ERR "C2_IOCRESET"); C2CK_reset(); return 0; case _IOC_NR(C2_IOCAWRITE): ret = __get_user(cbuf, (unsigned char *)arg); //printk(KERN_ERR "C2_IOCAWRITE: address=%u\n", cbuf); AddressWrite(cbuf); return ret; case _IOC_NR(C2_IOCDWRITE): ret = __get_user(buf, (long *)arg); //printk(KERN_ERR "C2_IOCDWRITE: len=%u, data=%u\n", (_IOC_SIZE(cmd)-1) & 3, buf); return DataWrite((_IOC_SIZE(cmd)-1) & 3, buf); case _IOC_NR(C2_IOCAREAD): cbuf=AddressRead(); //printk(KERN_ERR "C2_IOCAREAD: address=%u\n", cbuf); ret = __put_user(cbuf, (unsigned char *)arg); return ret; case _IOC_NR(C2_IOCDREAD): ret = DataRead((_IOC_SIZE(cmd)-1) & 3, &buf); if(ret) return ret; //printk(KERN_ERR "C2_IOCDREAD: len=%u, data=%u\n", (_IOC_SIZE(cmd)-1) & 3, buf); ret = __put_user(buf, (long *)arg); return ret; case _IOC_NR(C2_IOCQRESET): //printk(KERN_ERR "C2_IOCQRESET"); C2CK_ENA(); C2CK_low_pulse(); /* a "quick reset" is just a low pulse, less than 20us */ C2CK_DIS(); return 0; case _IOC_NR(C2_IOCIRQCHK): //printk(KERN_ERR "C2_IOCIRQCHK"); return CheckForInterrupts(); default: return -ENOTTY; } }
int evaluate_target(CorpusList *corp, /* the corpus */ FieldType t_id, /* the field to set */ FieldType base, /* where to start the search */ int inclusive, /* including or excluding the base */ SearchStrategy strategy, /* disambiguation rule: which item */ Constrainttree constr, /* the constraint */ enum ctxtdir direction, /* context direction */ int units, /* number of units */ char *attr_name) /* name of unit */ { Attribute *attr; int *table; Context context; int i, line, lbound, rbound; int excl_start, excl_end; int nr_evals; int percentage, new_percentage; /* for ProgressBar */ /* ------------------------------------------------------------ */ assert(corp); /* consistency check */ assert(t_id == TargetField || t_id == KeywordField || t_id == MatchField || t_id == MatchEndField); if (!constr) { cqpmessage(Error, "Constraing pattern missing in 'set target' command."); return 0; } if (corp->size <= 0) { cqpmessage(Error, "Corpus is empty."); return 0; } /* * check whether the base field specification is ok */ switch(base) { case MatchField: case MatchEndField: if (corp->range == NULL) { cqpmessage(Error, "No ranges for start of search"); return 0; } break; case TargetField: if (corp->targets == NULL) { cqpmessage(Error, "Can't start from base TARGET, none defined"); return 0; } break; case KeywordField: if (corp->keywords == NULL) { cqpmessage(Error, "Can't start from base KEYWORD, none defined"); return 0; } break; default: cqpmessage(Error, "Illegal base field (#%d) in 'set target' command.", base); return 0; } if (units <= 0) { cqpmessage(Error, "Invalid search space (%d units) in 'set target' command.", units); return 0; } /* THIS SHOULD BE UNNECESSARY, BECAUSE THE GRAMMAR MAKES SURE THE SUBCORPUS EXISTS & IS LOADED */ /* if (!access_corpus(corp)) { */ /* cqpmessage(Error, "Can't access named query %s.", corp->name); */ /* return 0; */ /* } */ context.size = units; context.direction = direction; if ((strcasecmp(attr_name, "word") == 0) || (strcasecmp(attr_name, "words") == 0)) { attr = find_attribute(corp->corpus, DEFAULT_ATT_NAME, ATT_POS, NULL); context.type = word; context.attrib = NULL; } else { attr = find_attribute(corp->corpus, attr_name, ATT_STRUC, NULL); context.type = structure; context.attrib = attr; } if (attr == NULL) { cqpmessage(Error, "Can't find attribute %s.%s", corp->mother_name, attr_name); return 0; } if (progress_bar) { progress_bar_clear_line(); progress_bar_message(1, 1, " preparing"); } table = (int *)cl_calloc(corp->size, sizeof(int)); EvaluationIsRunning = 1; nr_evals = 0; percentage = -1; for (line = 0; line < corp->size && EvaluationIsRunning; line++) { if (progress_bar) { new_percentage = floor(0.5 + (100.0 * line) / corp->size); if (new_percentage > percentage) { percentage = new_percentage; progress_bar_percentage(0, 0, percentage); } } table[line] = -1; switch(base) { case MatchField: excl_start = corp->range[line].start; excl_end = corp->range[line].end; if ((corp->range[line].start == corp->range[line].end) || inclusive) { if (calculate_ranges(corp, corp->range[line].start, context, &lbound, &rbound) == False) { Rprintf( "Can't compute boundaries for range #%d", line); lbound = rbound = -1; } } else { int dummy; if (calculate_ranges(corp, corp->range[line].start, context, &lbound, &dummy) == False) { Rprintf( "Can't compute left search space boundary match #%d", line); lbound = rbound = -1; } else if (calculate_ranges(corp, corp->range[line].end, context, &dummy, &rbound) == False) { Rprintf( "Can't compute right search space boundary match #%d", line); lbound = rbound = -1; } } break; case MatchEndField: excl_start = excl_end = corp->range[line].end; if (excl_start >= 0) { if (calculate_ranges(corp, corp->range[line].end, context, &lbound, &rbound) == False) { Rprintf( "Can't compute search space boundaries for match #%d", line); lbound = rbound = -1; } } else lbound = rbound = -1; break; case TargetField: excl_start = excl_end = corp->targets[line]; if (excl_start >= 0) { if (calculate_ranges(corp, corp->targets[line], context, &lbound, &rbound) == False) { Rprintf( "Can't compute search space boundaries for match #%d", line); lbound = rbound = -1; } } else lbound = rbound = -1; break; case KeywordField: excl_start = excl_end = corp->keywords[line]; if (excl_start >= 0) { if (calculate_ranges(corp, corp->keywords[line], context, &lbound, &rbound) == False) { Rprintf( "Can't compute search space boundaries for match #%d", line); lbound = rbound = -1; } } else lbound = rbound = -1; break; default: assert(0 && "Can't be"); return 0; } if ((lbound >= 0) && (rbound >= 0)) { int dist, maxdist; if (direction == left) { rbound = excl_start; if (strategy == SearchNearest) strategy = SearchRightmost; else if (strategy == SearchFarthest) strategy = SearchLeftmost; } else if (direction == right) { lbound = excl_start; if (strategy == SearchNearest) strategy = SearchLeftmost; else if (strategy == SearchFarthest) strategy = SearchRightmost; } switch (strategy) { case SearchFarthest: maxdist = MAX(excl_start - lbound, rbound - excl_start); assert(maxdist >= 0); for (dist = maxdist; dist >= 0; dist--) { i = excl_start - dist; if (i >= lbound && (inclusive || (i < excl_start))) if (eval_bool(constr, NULL, i)) { table[line] = i; break; } i = excl_start + dist; if (i <= rbound && (inclusive || (i > excl_end))) if (eval_bool(constr, NULL, i)) { table[line] = i; break; } nr_evals++; if (nr_evals == 1000) { CheckForInterrupts(); nr_evals = 0; } } break; case SearchNearest: maxdist = MAX(excl_start - lbound, rbound - excl_start); assert(maxdist >= 0); for (dist = 0; dist <= maxdist; dist++) { i = excl_start - dist; if (i >= lbound && (inclusive || (i < excl_start))) if (eval_bool(constr, NULL, i)) { table[line] = i; break; } i = excl_start + dist; if (i <= rbound && (inclusive || (i > excl_end))) if (eval_bool(constr, NULL, i)) { table[line] = i; break; } nr_evals++; if (nr_evals == 1000) { CheckForInterrupts(); nr_evals = 0; } } break; case SearchLeftmost: for (i = lbound; i <= rbound; i++) if (inclusive || (i < excl_start) || (i > excl_end)) { if (eval_bool(constr, NULL, i)) { table[line] = i; break; } nr_evals++; if (nr_evals == 1000) { CheckForInterrupts(); nr_evals = 0; } } break; case SearchRightmost: for (i = rbound; i >= lbound; i--) if (inclusive || (i < excl_start) || (i > excl_end)) { if (eval_bool(constr, NULL, i)) { table[line] = i; break; } nr_evals++; if (nr_evals == 1000) { CheckForInterrupts(); nr_evals = 0; } } break; default: break; } } } if (progress_bar) progress_bar_message(1, 1, " cleaning up"); switch (t_id) { case MatchField: for (i = 0; i < corp->size; i++) { if (table[i] >= 0) corp->range[i].start = table[i]; if (corp->range[i].start > corp->range[i].end) corp->range[i].start = corp->range[i].end; } cl_free(table); break; case MatchEndField: for (i = 0; i < corp->size; i++) { if (table[i] >= 0) corp->range[i].end = table[i]; if (corp->range[i].end < corp->range[i].start) corp->range[i].end = corp->range[i].start; } cl_free(table); break; case TargetField: cl_free(corp->targets); corp->targets = table; break; case KeywordField: cl_free(corp->keywords); corp->keywords = table; break; default: assert(0 && "Can't be"); break; } if (progress_bar) progress_bar_clear_line(); if ((t_id == MatchField) || (t_id == MatchEndField)) RangeSort(corp, 0); /* re-sort corpus if match regions were modified */ touch_corpus(corp); if (!EvaluationIsRunning) { cqpmessage(Warning, "Evaluation interruted: results may be incomplete."); if (which_app == cqp) install_signal_handler(); } EvaluationIsRunning = 0; return 1; }