// 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; }
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(); }
/* 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; }
/* 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; }
/*===========================================================================* * 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; }
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; }
/* 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; }
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; }
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; }