// see if two-level suffix is present in the word
struct hentry * SfxEntry::check_twosfx(const char * word, int len, int optflags,
    PfxEntry* ppfx, const FLAG needflag)
{
    int                 tmpl;            // length of tmpword
    struct hentry *     he;              // hash entry pointer
    unsigned char *     cp;
    char                tmpword[MAXWORDUTF8LEN + 4];
    PfxEntry* ep = ppfx;


    // if this suffix is being cross checked with a prefix
    // but it does not support cross products skip it

    if ((optflags & aeXPRODUCT) != 0 &&  (opts & aeXPRODUCT) == 0)
        return NULL;

    // upon entry suffix is 0 length or already matches the end of the word.
    // So if the remaining root word has positive length
    // and if there are enough chars in root word and added back strip chars
    // to meet the number of characters conditions, then test it

    tmpl = len - appndl;

    if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
       (tmpl + stripl >= numconds)) {

            // generate new root word by removing suffix and adding
            // back any characters that would have been stripped or
            // or null terminating the shorter string

            strcpy (tmpword, word);
            cp = (unsigned char *)(tmpword + tmpl);
            if (stripl) {
                strcpy ((char *)cp, strip);
                tmpl += stripl;
                cp = (unsigned char *)(tmpword + tmpl);
            } else *cp = '\0';

            // now make sure all of the conditions on characters
            // are met.  Please see the appendix at the end of
            // this file for more info on exactly what is being
            // tested

            // if all conditions are met then recall suffix_check

            if (test_condition((char *) cp, (char *) tmpword)) {
                if (ppfx) {
                    // handle conditional suffix
                    if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen))
                        he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag);
                    else
                        he = pmyMgr->suffix_check(tmpword, tmpl, optflags, ppfx, NULL, 0, NULL, (FLAG) aflag, needflag);
                } else {
                    he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag);
                }
                if (he) return he;
            }
    }
    return NULL;
}
Example #2
0
        void synchronize(std::size_t generation_value, Lock& l,
            char const* function_name = "base_and_gate<>::synchronize",
            error_code& ec= throws)
        {
            HPX_ASSERT_OWNS_LOCK(l);

            if (generation_value < generation_)
            {
                HPX_THROWS_IF(ec, hpx::invalid_status, function_name,
                    "sequencing error, generational counter too small");
                return;
            }

           // make sure this set operation has not arrived ahead of time
            if (!test_condition(generation_value))
            {
                conditional_trigger c;
                manage_condition cond(*this, c);

                future<void> f = cond.get_future(util::bind(
                        &base_trigger::test_condition, this, generation_value));

                {
                    hpx::util::unlock_guard<Lock> ul(l);
                    f.get();
                }   // make sure lock gets re-acquired
            }

            if (&ec != &throws)
                ec = make_success_code();
        }
Example #3
0
File: user.c Project: dborca/mc
/* Calculates the truth value of one lineful of conditions. Returns
   the point just before the end of line. */
static char *test_line (WEdit *edit_widget, char *p, int *result)
{
    int condition;
    char operator;
    char *debug_start, *debug_end;

    /* Repeat till end of line */
    while (*p && *p != '\n') {
        /* support quote space .mnu */
	while ((*p == ' ' && *(p-1) != '\\' ) || *p == '\t')
	    p++;
	if (!*p || *p == '\n')
	    break;
	operator = *p++;
	if (*p == '?'){
	    debug_flag = 1;
	    p++;
	}
        /* support quote space .mnu */
	while ((*p == ' ' && *(p-1) != '\\' ) || *p == '\t')
	    p++;
	if (!*p || *p == '\n')
	    break;
	condition = 1;	/* True by default */

	debug_start = p;
	p = test_condition (edit_widget, p, &condition);
	debug_end = p;
	/* Add one debug statement */
	debug_out (debug_start, debug_end, condition);

	switch (operator){
	case '+':
	case '=':
	    /* Assignment */
	    *result = condition;
	    break;
	case '&':	/* Logical and */
	    *result &= condition;
	    break;
	case '|':	/* Logical or */
	    *result |= condition;
	    break;
	default:
	    debug_error = 1;
	    break;
	} /* switch */
	/* Add one debug statement */
	debug_out (&operator, NULL, *result);
	
    } /* while (*p != '\n') */
    /* Report debug message */
    debug_out (NULL, NULL, 1);

    if (!*p || *p == '\n')
	p --;
    return p;
}
// check if this prefix entry matches
struct hentry * PfxEntry::checkword(const char * word, int len, char in_compound, const FLAG needflag)
{
    int                 tmpl;   // length of tmpword
    struct hentry *     he;     // hash entry of root word or NULL
    char                tmpword[MAXWORDUTF8LEN + 4];

    // on entry prefix is 0 length or already matches the beginning of the word.
    // So if the remaining root word has positive length
    // and if there are enough chars in root word and added back strip chars
    // to meet the number of characters conditions, then test it

     tmpl = len - appndl;

     if (tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) {

            // generate new root word by removing prefix and adding
            // back any characters that would have been stripped

            if (stripl) strcpy (tmpword, strip);
            strcpy ((tmpword + stripl), (word + appndl));

            // now make sure all of the conditions on characters
            // are met.  Please see the appendix at the end of
            // this file for more info on exactly what is being
            // tested

            // if all conditions are met then check if resulting
            // root word in the dictionary

            if (test_condition(tmpword)) {
                tmpl += stripl;
                if ((he = pmyMgr->lookup(tmpword)) != NULL) {
                   do {
                      if (TESTAFF(he->astr, aflag, he->alen) &&
                        // forbid single prefixes with needaffix flag
                        ! TESTAFF(contclass, pmyMgr->get_needaffix(), contclasslen) &&
                        // needflag
                        ((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||
                         (contclass && TESTAFF(contclass, needflag, contclasslen))))
                            return he;
                      he = he->next_homonym; // check homonyms
                   } while (he);
                }

                // prefix matched but no root word was found
                // if aeXPRODUCT is allowed, try again but now
                // ross checked combined with a suffix

                //if ((opts & aeXPRODUCT) && in_compound) {
                if ((opts & aeXPRODUCT)) {
                   he = pmyMgr->suffix_check(tmpword, tmpl, aeXPRODUCT, this, NULL,
                        0, NULL, FLAG_NULL, needflag, in_compound);
                   if (he) return he;
                }
            }
     }
    return NULL;
}
// check if this prefix entry matches
struct hentry * PfxEntry::check_twosfx(const char * word, int len,
    char in_compound, const FLAG needflag)
{
    int                 tmpl;   // length of tmpword
    struct hentry *     he;     // hash entry of root word or NULL
    char                tmpword[MAXWORDUTF8LEN + 4];

    // on entry prefix is 0 length or already matches the beginning of the word.
    // So if the remaining root word has positive length
    // and if there are enough chars in root word and added back strip chars
    // to meet the number of characters conditions, then test it

     tmpl = len - appndl;

     if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
        (tmpl + stripl >= numconds)) {

            // generate new root word by removing prefix and adding
            // back any characters that would have been stripped

            if (stripl) strcpy (tmpword, strip);
            strcpy ((tmpword + stripl), (word + appndl));

            // now make sure all of the conditions on characters
            // are met.  Please see the appendix at the end of
            // this file for more info on exactly what is being
            // tested

            // if all conditions are met then check if resulting
            // root word in the dictionary

            if (test_condition(tmpword)) {
                tmpl += stripl;

                // prefix matched but no root word was found
                // if aeXPRODUCT is allowed, try again but now
                // cross checked combined with a suffix

                if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
                   he = pmyMgr->suffix_check_twosfx(tmpword, tmpl, aeXPRODUCT, this, needflag);
                   if (he) return he;
                }
            }
     }
    return NULL;
}
Example #6
0
/* Calculates the truth value of the next condition starting from
   p. Returns the point after condition. */
static char *test_condition (char *p, int *condition)
{
    WPanel *panel;
    char arg [256];

    /* Handle one condition */
    for (;*p != '\n' && *p != '&' && *p != '|'; p++){
    if (*p == ' ' || *p == '\t')
        continue;
    if (*p >= 'a')
        panel = cpanel;
    else {
        if (get_other_type () == view_listing)
        panel = other_panel;
        else
        panel = NULL;
    }
    *p |= 0x20;

    switch (*p++){
    case '!':
        p = test_condition (p, condition);
        *condition = ! *condition;
        p--;
        break;
    case 'f':
        p = extract_arg (p, arg);
        *condition = panel && regexp_match (arg, panel->dir.list [panel->selected].fname, match_file);
        break;
    case 'd':
        p = extract_arg (p, arg);
        *condition = panel && regexp_match (arg, panel->cwd, match_file);
        break;
    case 't':
        p = extract_arg (p, arg);
        *condition = panel && test_type (panel, arg);
        break;
    default:
        debug_error = 1;
        break;
    } /* switch */

    } /* while */
    return p;
}
// add prefix to this word assuming conditions hold
char * PfxEntry::add(const char * word, int len)
{
    char tword[MAXWORDUTF8LEN + 4];

    if ((len > stripl || (len == 0 && pmyMgr->get_fullstrip())) && 
       (len >= numconds) && test_condition(word) &&
       (!stripl || (strncmp(word, strip, stripl) == 0)) &&
       ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {
    /* we have a match so add prefix */
              char * pp = tword;
              if (appndl) {
                  strcpy(tword,appnd);
                  pp += appndl;
               }
               strcpy(pp, (word + stripl));
               return mystrdup(tword);
     }
     return NULL;
}
Example #8
0
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
int main(void)
{
  errct = 0;
  th_a = th_b = th_c = th_d = th_e = th_f = th_g = th_h = 0;
  mutex_a_step = mutex_b_step = mutex_c_step = 0;
  event_a_step = event_b_step = 0;
  rwlock_a_step = rwlock_b_step = 0;
  once = MTHREAD_ONCE_INIT;

  start(59);
  test_scheduling();
  test_mutex();
  test_event();
  test_rwlock();
  test_condition();
  test_attributes();
  test_keys();
  quit();
  return(0);	/* Not reachable */
}
// add suffix to this word assuming conditions hold
char * SfxEntry::add(const char * word, int len)
{
    char                tword[MAXWORDUTF8LEN + 4];

     /* make sure all conditions match */
     if ((len > stripl || (len == 0 && pmyMgr->get_fullstrip())) &&
        (len >= numconds) && test_condition(word + len, word) &&
        (!stripl || (strcmp(word + len - stripl, strip) == 0)) &&
        ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {
              /* we have a match so add suffix */
              strcpy(tword,word);
              if (appndl) {
                  strcpy(tword + len - stripl, appnd);
              } else {
                  *(tword + len - stripl) = '\0';
              }
              return mystrdup(tword);
     }
     return NULL;
}
Example #10
0
static GList *
process_conditional_items(BluefishTextView * btv, Tfound *found, gint contextnum, GList *items)
{
	BluefishTextView *master = BLUEFISH_TEXT_VIEW(btv->master);
	GList *retval=NULL, *tmplist=items;
	
	while (tmplist) {
		gboolean valid=TRUE;
		guint pattern_id;
		const gchar *string = tmplist->data;
		GHashTable *hasht = g_array_index(master->bflang->st->contexts, Tcontext,contextnum).patternhash;
		g_print("process_conditional_items, looking up %s in hashtable %p\n",string, hasht);
		pattern_id = GPOINTER_TO_INT(g_hash_table_lookup(hasht, string));
		DBG_AUTOCOMP("process_conditional_items, got pattern_id=%d\n", pattern_id);
		if (pattern_id && found) {
				/* found may be NULL, for examplein an empty document, in that case anything is valid */
			GSList *tmpslist = g_array_index(master->bflang->st->matches, Tpattern, pattern_id).autocomp_items;
			/* a pattern MAY have multiple autocomplete items. This code is not efficient if in the future some
			   patterns would have many autocomplete items. I don't expect this, so I leave this as it is right now  */
			while (tmpslist) {
				Tpattern_autocomplete *pac = tmpslist->data;
				if (g_strcmp0(string, pac->autocomplete_string) == 0 && pac->condition!=0) {
					Tpattern_condition *pcond = &g_array_index(master->bflang->st->conditions, Tpattern_condition, pac->condition);
					
					valid = test_condition(found->fcontext, found->fblock, pcond);
					if (!valid) {
						g_print("process_conditional_items, item %s is NOT VALID for autocompletion\n",string);
					}
				}
				tmpslist = g_slist_next(tmpslist);
			}
		}
		if (valid) {
			retval = g_list_prepend(retval, string);
		}
		
		tmplist = tmplist->next;
	}
	return retval;
}
Example #11
0
File: user.c Project: dborca/mc
/* Calculates the truth value of the next condition starting from
   p. Returns the point after condition. */
static char *test_condition (WEdit *edit_widget, char *p, int *condition)
{
    WPanel *panel;
    char arg [256];

    /* Handle one condition */
    for (;*p != '\n' && *p != '&' && *p != '|'; p++){
                /* support quote space .mnu */
	if ((*p == ' ' && *(p-1) != '\\') || *p == '\t')
	    continue;
	if (*p >= 'a')
	    panel = current_panel;
	else {
	    if (get_other_type () == view_listing)
		panel = other_panel;
	    else
		panel = NULL;
	}
	*p |= 0x20;

	switch (*p++){
	case '!':
	    p = test_condition (edit_widget, p, condition);
	    *condition = ! *condition;
	    p--;
	    break;
	case 'f': /* file name pattern */
	    p = extract_arg (p, arg, sizeof (arg));
	    *condition = panel && regexp_match (arg, panel->dir.list [panel->selected].fname, match_file, 0);
	    break;
	case 'y': /* syntax pattern */
            if (edit_widget && edit_widget->syntax_type) {
	        p = extract_arg (p, arg, sizeof (arg));
	        *condition = panel &&
                    regexp_match (arg, edit_widget->syntax_type, match_normal, 0);
	    }
            break;
	case 'd':
	    p = extract_arg (p, arg, sizeof (arg));
	    *condition = panel && regexp_match (arg, panel->cwd, match_file, 0);
	    break;
	case 't':
	    p = extract_arg (p, arg, sizeof (arg));
	    *condition = panel && test_type (panel, arg);
	    break;
	case 'x': /* executable */
	{
	    struct stat status;
	    
	    p = extract_arg (p, arg, sizeof (arg));
	    if (stat (arg, &status) == 0)
		*condition = is_exe (status.st_mode);
	    else
		*condition = 0; 
	    break;
	}
	default:
	    debug_error = 1;
	    break;
	} /* switch */

    } /* while */
    return p;
}
Example #12
0
static
int setup_rotation_trigger(const struct session *session,
		struct lttng_notification_channel *notification_channel)
{
	int ret;
	struct lttng_condition *rotation_ongoing_condition = NULL;
	struct lttng_condition *rotation_completed_condition = NULL;
	struct lttng_action *notify = NULL;
	struct lttng_trigger *rotation_ongoing_trigger = NULL;
	struct lttng_trigger *rotation_completed_trigger = NULL;
	enum lttng_condition_status condition_status;
	enum lttng_notification_channel_status notification_channel_status;

	notify = lttng_action_notify_create();
	if (!notify) {
		ret = -1;
		goto end;
	}

	/* Create rotation ongoing and completed conditions. */
	rotation_ongoing_condition =
			lttng_condition_session_rotation_ongoing_create();
	ok(rotation_ongoing_condition, "Create session rotation ongoing condition");
	if (!rotation_ongoing_condition) {
		ret = -1;
		goto end;
	}
	ret = test_condition(rotation_ongoing_condition, "rotation ongoing");
	if (ret) {
		goto end;
	}
	condition_status = lttng_condition_session_rotation_set_session_name(
			rotation_ongoing_condition, session->name);
	if (condition_status != LTTNG_CONDITION_STATUS_OK) {
		ret = -1;
		diag("Failed to set session name on session rotation ongoing condition");
		goto end;
	}

	rotation_completed_condition =
			lttng_condition_session_rotation_completed_create();
	ok(rotation_completed_condition, "Create session rotation completed condition");
	if (!rotation_completed_condition) {
		ret = -1;
		goto end;
	}
	ret = test_condition(rotation_completed_condition, "rotation completed");
	if (ret) {
		diag("Failed to set session name on session rotation completed condition");
		goto end;
	}
	condition_status = lttng_condition_session_rotation_set_session_name(
			rotation_completed_condition, session->name);
	if (condition_status != LTTNG_CONDITION_STATUS_OK) {
		ret = -1;
		goto end;
	}

	notification_channel_status = lttng_notification_channel_subscribe(
			notification_channel, rotation_ongoing_condition);
	ok(notification_channel_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
			"Subscribe to session rotation ongoing notifications");
	if (notification_channel_status !=
			LTTNG_NOTIFICATION_CHANNEL_STATUS_OK) {
		ret = -1;
		goto end;
	}
	notification_channel_status = lttng_notification_channel_subscribe(
			notification_channel, rotation_completed_condition);
	ok(notification_channel_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
			"Subscribe to session rotation completed notifications");
	if (notification_channel_status !=
			LTTNG_NOTIFICATION_CHANNEL_STATUS_OK) {
		ret = -1;
		goto end;
	}

	/* Create rotation ongoing and completed triggers. */
	rotation_ongoing_trigger = lttng_trigger_create(
			rotation_ongoing_condition, notify);
	ok(rotation_ongoing_trigger, "Create a rotation ongoing notification trigger");
	if (!rotation_ongoing_trigger) {
		ret = -1;
		goto end;
	}

	rotation_completed_trigger = lttng_trigger_create(
			rotation_completed_condition, notify);
	ok(rotation_completed_trigger, "Create a rotation completed notification trigger");
	if (!rotation_completed_trigger) {
		ret = -1;
		goto end;
	}

	/* Register rotation ongoing and completed triggers. */
	ret = lttng_register_trigger(rotation_ongoing_trigger);
	ok(ret == 0, "Registered session rotation ongoing trigger");
	if (ret) {
		goto end;
	}

	ret = lttng_register_trigger(rotation_completed_trigger);
	ok(ret == 0, "Registered session rotation completed trigger");
	if (ret) {
		goto end;
	}
end:
	lttng_trigger_destroy(rotation_ongoing_trigger);
	lttng_trigger_destroy(rotation_completed_trigger);
	lttng_condition_destroy(rotation_ongoing_condition);
	lttng_condition_destroy(rotation_completed_condition);
	lttng_action_destroy(notify);
	return ret;
}
Example #13
0
static char *
test_condition (WEdit * edit_widget, char *p, int *condition)
{
    char arg[256];
    const mc_search_type_t search_type = easy_patterns ? MC_SEARCH_T_GLOB : MC_SEARCH_T_REGEX;

    /* Handle one condition */
    for (; *p != '\n' && *p != '&' && *p != '|'; p++)
    {
        WPanel *panel = NULL;

        /* support quote space .mnu */
        if ((*p == ' ' && *(p - 1) != '\\') || *p == '\t')
            continue;
        if (*p >= 'a')
            panel = current_panel;
        else if (get_other_type () == view_listing)
            panel = other_panel;

        *p |= 0x20;

        switch (*p++)
        {
        case '!':
            p = test_condition (edit_widget, p, condition);
            *condition = !*condition;
            str_prev_char (&p);
            break;
        case 'f':              /* file name pattern */
            p = extract_arg (p, arg, sizeof (arg));
#ifdef USE_INTERNAL_EDIT
            if (edit_widget != NULL)
            {
                char *edit_filename;

                edit_filename = edit_get_file_name (edit_widget);
                *condition = mc_search (arg, DEFAULT_CHARSET, edit_filename, search_type) ? 1 : 0;
                g_free (edit_filename);
            }
            else
#endif
                *condition = panel != NULL &&
                    mc_search (arg, DEFAULT_CHARSET, panel->dir.list[panel->selected].fname,
                               search_type) ? 1 : 0;
            break;
        case 'y':              /* syntax pattern */
#ifdef USE_INTERNAL_EDIT
            if (edit_widget != NULL)
            {
                const char *syntax_type = edit_get_syntax_type (edit_widget);
                if (syntax_type != NULL)
                {
                    p = extract_arg (p, arg, sizeof (arg));
                    *condition =
                        mc_search (arg, DEFAULT_CHARSET, syntax_type, MC_SEARCH_T_NORMAL) ? 1 : 0;
                }
            }
#endif
            break;
        case 'd':
            p = extract_arg (p, arg, sizeof (arg));
            *condition = panel != NULL
                && mc_search (arg, DEFAULT_CHARSET, vfs_path_as_str (panel->cwd_vpath),
                              search_type) ? 1 : 0;
            break;
        case 't':
            p = extract_arg (p, arg, sizeof (arg));
            *condition = panel != NULL && test_type (panel, arg) ? 1 : 0;
            break;
        case 'x':              /* executable */
            {
                struct stat status;

                p = extract_arg (p, arg, sizeof (arg));
                if (stat (arg, &status) == 0)
                    *condition = is_exe (status.st_mode) ? 1 : 0;
                else
                    *condition = 0;
                break;
            }
        default:
            debug_error = 1;
            break;
        }                       /* switch */

    }                           /* while */
    return p;
}
// see if this suffix is present in the word
struct hentry * SfxEntry::checkword(const char * word, int len, int optflags,
    PfxEntry* ppfx, char ** wlst, int maxSug, int * ns, const FLAG cclass, const FLAG needflag,
    const FLAG badflag)
{
    int                 tmpl;            // length of tmpword
    struct hentry *     he;              // hash entry pointer
    unsigned char *     cp;
    char                tmpword[MAXWORDUTF8LEN + 4];
    PfxEntry* ep = ppfx;

    // if this suffix is being cross checked with a prefix
    // but it does not support cross products skip it

    if (((optflags & aeXPRODUCT) != 0) && ((opts & aeXPRODUCT) == 0))
        return NULL;

    // upon entry suffix is 0 length or already matches the end of the word.
    // So if the remaining root word has positive length
    // and if there are enough chars in root word and added back strip chars
    // to meet the number of characters conditions, then test it

    tmpl = len - appndl;
    // the second condition is not enough for UTF-8 strings
    // it checked in test_condition()

    if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
        (tmpl + stripl >= numconds)) {

            // generate new root word by removing suffix and adding
            // back any characters that would have been stripped or
            // or null terminating the shorter string

            strcpy (tmpword, word);
            cp = (unsigned char *)(tmpword + tmpl);
            if (stripl) {
                strcpy ((char *)cp, strip);
                tmpl += stripl;
                cp = (unsigned char *)(tmpword + tmpl);
            } else *cp = '\0';

            // now make sure all of the conditions on characters
            // are met.  Please see the appendix at the end of
            // this file for more info on exactly what is being
            // tested

            // if all conditions are met then check if resulting
            // root word in the dictionary

            if (test_condition((char *) cp, (char *) tmpword)) {

#ifdef SZOSZABLYA_POSSIBLE_ROOTS
                fprintf(stdout,"%s %s %c\n", word, tmpword, aflag);
#endif
                if ((he = pmyMgr->lookup(tmpword)) != NULL) {
                    do {
                        // check conditional suffix (enabled by prefix)
                        if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() &&
                                    TESTAFF(ep->getCont(), aflag, ep->getContLen()))) &&
                            (((optflags & aeXPRODUCT) == 0) ||
                            (ep && TESTAFF(he->astr, ep->getFlag(), he->alen)) ||
                             // enabled by prefix
                            ((contclass) && (ep && TESTAFF(contclass, ep->getFlag(), contclasslen)))
                            ) &&
                            // handle cont. class
                            ((!cclass) ||
                                ((contclass) && TESTAFF(contclass, cclass, contclasslen))
                            ) &&
                            // check only in compound homonyms (bad flags)
                            (!badflag || !TESTAFF(he->astr, badflag, he->alen)
                            ) &&
                            // handle required flag
                            ((!needflag) ||
                              (TESTAFF(he->astr, needflag, he->alen) ||
                              ((contclass) && TESTAFF(contclass, needflag, contclasslen)))
                            )
                        ) return he;
                        he = he->next_homonym; // check homonyms
                    } while (he);

                // obsolote stemming code (used only by the
                // experimental SuffixMgr:suggest_pos_stems)
                // store resulting root in wlst
                } else if (wlst && (*ns < maxSug)) {
                    int cwrd = 1;
                    for (int k=0; k < *ns; k++)
                        if (strcmp(tmpword, wlst[k]) == 0) cwrd = 0;
                    if (cwrd) {
                        wlst[*ns] = mystrdup(tmpword);
                        if (wlst[*ns] == NULL) {
                            for (int j=0; j<*ns; j++) free(wlst[j]);
                            *ns = -1;
                            return NULL;
                        }
                        (*ns)++;
                    }
                }
            }
    }
    return NULL;
}
// check if this prefix entry matches
char * PfxEntry::check_morph(const char * word, int len, char in_compound, const FLAG needflag)
{
    int                 tmpl;   // length of tmpword
    struct hentry *     he;     // hash entry of root word or NULL
    char                tmpword[MAXWORDUTF8LEN + 4];
    char                result[MAXLNLEN];
    char * st;

    *result = '\0';

    // on entry prefix is 0 length or already matches the beginning of the word.
    // So if the remaining root word has positive length
    // and if there are enough chars in root word and added back strip chars
    // to meet the number of characters conditions, then test it

     tmpl = len - appndl;

     if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
        (tmpl + stripl >= numconds)) {

            // generate new root word by removing prefix and adding
            // back any characters that would have been stripped

            if (stripl) strcpy (tmpword, strip);
            strcpy ((tmpword + stripl), (word + appndl));

            // now make sure all of the conditions on characters
            // are met.  Please see the appendix at the end of
            // this file for more info on exactly what is being
            // tested

            // if all conditions are met then check if resulting
            // root word in the dictionary

            if (test_condition(tmpword)) {
                tmpl += stripl;
                if ((he = pmyMgr->lookup(tmpword)) != NULL) {
                    do {
                      if (TESTAFF(he->astr, aflag, he->alen) &&
                        // forbid single prefixes with needaffix flag
                        ! TESTAFF(contclass, pmyMgr->get_needaffix(), contclasslen) &&
                        // needflag
                        ((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||
                         (contclass && TESTAFF(contclass, needflag, contclasslen)))) {
                            if (morphcode) {
                                mystrcat(result, " ", MAXLNLEN);
                                mystrcat(result, morphcode, MAXLNLEN);
                            } else mystrcat(result,getKey(), MAXLNLEN);
                            if (!HENTRY_FIND(he, MORPH_STEM)) {
                                mystrcat(result, " ", MAXLNLEN);
                                mystrcat(result, MORPH_STEM, MAXLNLEN);
                                mystrcat(result, HENTRY_WORD(he), MAXLNLEN);
                            }
                            // store the pointer of the hash entry
                            if (HENTRY_DATA(he)) {
                                mystrcat(result, " ", MAXLNLEN);
                                mystrcat(result, HENTRY_DATA2(he), MAXLNLEN);
                            } else {
                                // return with debug information
                                char * flag = pmyMgr->encode_flag(getFlag());
                                mystrcat(result, " ", MAXLNLEN);
                                mystrcat(result, MORPH_FLAG, MAXLNLEN);
                                mystrcat(result, flag, MAXLNLEN);
                                free(flag);
                            }
                            mystrcat(result, "\n", MAXLNLEN);
                      }
                      he = he->next_homonym;
                    } while (he);
                }

                // prefix matched but no root word was found
                // if aeXPRODUCT is allowed, try again but now
                // ross checked combined with a suffix

                if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
                   st = pmyMgr->suffix_check_morph(tmpword, tmpl, aeXPRODUCT, this,
                     FLAG_NULL, needflag);
                   if (st) {
                        mystrcat(result, st, MAXLNLEN);
                        free(st);
                   }
                }
            }
     }
    
    if (*result) return mystrdup(result);
    return NULL;
}