extern void* DynLoad_executeFunction(threadData_t* threadData, int _inFuncHandle, void* _inValLst, int _inPrintDebug) { modelica_ptr_t func = NULL; int retval = -1; void *retarg = NULL; func = lookup_ptr(_inFuncHandle); if (func == NULL) MMC_THROW(); retval = execute_function(threadData, _inValLst, &retarg, func->data.func.handle, _inPrintDebug); if (retval) MMC_THROW(); return retarg; }
void execute(Chunk *chunk) { Closure *closure = make_closure(chunk); Frame *frame = make_frame(NULL, closure); VM *vm = make_vm(frame, 0); execute_function(vm); gc(vm); free(vm); // TODO - free last closure [?] // Other closrues should be already taken care of // by the last gc sweep, but this one existed outside // of the heap. }
static void test_long_file_name(char *name, int (*callback) (const char *), int expected) { char *ptr, *ptr_end, *buffer; size_t name_length; buffer = get_long_name_buffer(&name_length, 1); strcpy(buffer, tmp_path); ptr = buffer + strlen(buffer); ptr_end = ptr + name_length + 1; *(ptr++) = '/'; while (ptr <= ptr_end) *(ptr++) = 'E'; *ptr = '\000'; execute_function(name, callback, buffer, expected); free(buffer); }
static void test_long_component_name(char *name, int (*callback) (const char *), int expected) { char *ptr, *ptr_end, *buffer; size_t name_length; buffer = get_long_name_buffer(&name_length, 3); strcpy(buffer, tmp_path); ptr = buffer + strlen(buffer); ptr_end = ptr + name_length + 2; *(ptr++) = '/'; for (; ptr < ptr_end; ptr++) *ptr = 'E'; *(ptr++) = '/'; *(ptr++) = 'F'; *ptr = '\000'; execute_function(name, callback, buffer, expected); free(buffer); }
void test_ENAMETOOLONG_path(char *name, int (*callback) (const char *), int expected) { size_t pcPathMax; char *path, *tmpPtr; int pathLength, tempPathLength; temp = stderr; if ((pcPathMax = pathconf(tmp_path, _PC_PATH_MAX)) == -1) { tst_resm(TFAIL, "pathconf(_PC_PATH_MAX) failed: %s", strerror(errno)); cleanup_function(); fail_exit(); } #ifdef DEBUG fprintf(temp, "INFO: pathconf(_PC_PATH_MAX) for %s is %lu\n", tmp_path, pcPathMax); #endif if ((path = malloc(pcPathMax + 2)) == NULL) { tst_resm(TFAIL, "malloc(%zu) for path failed: %s", pcPathMax + 2, strerror(errno)); cleanup_function(); fail_exit(); } path = strcpy(path, tmp_path); pathLength = (int)strlen(path); tempPathLength = pathLength + 1; /* leave some chars for element that pushes path over PC_PATH_MAX */ pcPathMax = pcPathMax - tempPathLength - 5; tmpPtr = path + strlen(path); while (pathLength < pcPathMax) { tmpPtr += sprintf(tmpPtr, "/%s", tmp_path); pathLength += tempPathLength; } /* reinstate pcPathMax correct value */ pcPathMax = pcPathMax + tempPathLength + 5; tmpPtr = path + pathLength; *tmpPtr++ = '/'; pathLength++; while (pathLength <= pcPathMax) { *tmpPtr++ = 'z'; pathLength++; } *tmpPtr = '\0'; pathLength = (int)strlen(path); if (pathLength != pcPathMax + 1) { tst_resm(TFAIL, "test logic failure, path length is %d, should be %lu", pathLength, (long unsigned int)pcPathMax + 1); free(path); cleanup_function(); fail_exit(); } execute_function(name, callback, path, expected); free(path); }
/* * Change by PRB ([email protected]), 31/10/93. Prepend a hot key * specifier to each item in the list. This means allocating the * memory for each item (& freeing it) rather than just using the window * title directly. */ void CMD_WindowList(F_CMD_ARGS) { struct MenuRoot *mr; struct MenuParameters mp; char* ret_action = NULL; FvwmWindow *t; FvwmWindow **windowList; FvwmWindow **iconifiedList = NULL; int numWindows; int ii; char tname[128]; char loc[64]; char *name=NULL; Bool free_name = False; int dwidth; int dheight; char *tlabel; int last_desk_done = INT_MIN; int last_desk_displayed = INT_MIN; int next_desk = 0; char *t_hot=NULL; /* Menu label with hotkey added */ char scut = '0'; /* Current short cut key */ char *opts=NULL; char *tok=NULL; int desk = Scr.CurrentDesk; unsigned long flags = SHOW_DEFAULT; char *func = NULL; char *ffunc = NULL; char *tfunc = NULL; char *default_action = NULL; MenuReturn mret; MenuOptions mops; int low_layer = 0; /* show all layers by default */ int high_layer = INT_MAX; int max_label_width = 0; int skiplist_mode = 0; /* do not show skiplist by default */ Bool use_hotkey = True; KeyCode old_sor_keycode; char sor_default_keyname[8] = { 'M', 'e', 't', 'a', '_', 'L' }; char *sor_keyname = sor_default_keyname; /* Condition vars. */ Bool use_condition = False; Bool current_at_end = False; Bool iconified_at_end = False; int ic = 0; int ij; WindowConditionMask mask; char *cond_flags; Bool first_desk = True; Bool empty_menu = True; Bool was_get_menu_opts_called = False; FvwmWindow * const fw = exc->w.fw; const Window w = exc->w.w; const exec_context_t *exc2; memset(&mops, 0, sizeof(mops)); memset(&mret, 0, sizeof(MenuReturn)); /* parse postitioning args - must call this even if no action is given * because it sets the xinerama screen origin */ if (action && *action) { /* Look for condition - CreateFlagString returns NULL if no '(' * or '[' */ cond_flags = CreateFlagString(action, &action); if (cond_flags) { /* Create window mask */ use_condition = True; DefaultConditionMask(&mask); /* override for Current [] */ mask.my_flags.use_circulate_hit = 1; mask.my_flags.use_circulate_hit_icon = 1; CreateConditionMask(cond_flags, &mask); free(cond_flags); } opts = get_menu_options( action, w, fw, NULL, NULL, NULL, &mops); was_get_menu_opts_called = True; /* parse options */ while (opts && *opts) { opts = GetNextSimpleOption(opts, &tok); if (!tok) { break; } if (StrEquals(tok,"NoHotkeys")) { use_hotkey = False; } else if (StrEquals(tok,"Function")) { opts = GetNextSimpleOption(opts, &func); } else if (StrEquals(tok,"Desk")) { free(tok); opts = GetNextSimpleOption(opts, &tok); if (tok) { desk = atoi(tok); flags &= ~SHOW_ALLDESKS; } } else if (StrEquals(tok,"CurrentDesk")) { desk = Scr.CurrentDesk; flags &= ~SHOW_ALLDESKS; } else if (StrEquals(tok,"NotAlphabetic")) { flags &= ~SHOW_ALPHABETIC; } else if (StrEquals(tok,"Alphabetic")) { flags |= SHOW_ALPHABETIC; } else if (StrEquals(tok,"SortByClass")) { flags |= SORT_BYCLASS; } else if (StrEquals(tok,"SortByResource")) { flags |= SORT_BYRESOURCE; } else if (StrEquals(tok,"ReverseOrder")) { flags |= SORT_REVERSE; } else if (StrEquals(tok,"CurrentAtEnd")) { current_at_end = True; } else if (StrEquals(tok,"IconifiedAtEnd")) { iconified_at_end = True; } else if (StrEquals(tok,"NoDeskSort")) { flags |= NO_DESK_SORT; } else if (StrEquals(tok,"ShowPage")) { flags |= SHOW_PAGE_X | SHOW_PAGE_Y; } else if (StrEquals(tok,"ShowPageX")) { flags |= SHOW_PAGE_X; } else if (StrEquals(tok,"ShowPageY")) { flags |= SHOW_PAGE_Y; } else if (StrEquals(tok,"ShowScreen")) { flags |= SHOW_SCREEN; } else if (StrEquals(tok,"UseIconName")) { flags |= SHOW_ICONNAME; } else if (StrEquals(tok,"NoGeometry")) { flags &= ~SHOW_GEOMETRY; flags &= ~SHOW_INFONOTGEO; } else if (StrEquals(tok,"NoGeometryWithInfo")) { flags &= ~SHOW_GEOMETRY; flags |= SHOW_INFONOTGEO; } else if (StrEquals(tok,"Geometry")) { flags |= SHOW_GEOMETRY; flags &= ~SHOW_INFONOTGEO; } else if (StrEquals(tok,"NoIcons")) { flags &= ~SHOW_ICONIC; } else if (StrEquals(tok,"Icons")) { flags |= SHOW_ICONIC; } else if (StrEquals(tok,"OnlyIcons")) { flags = SHOW_ICONIC; } else if (StrEquals(tok,"NoNormal")) { flags &= ~SHOW_NORMAL; } else if (StrEquals(tok,"Normal")) { flags |= SHOW_NORMAL; } else if (StrEquals(tok,"OnlyNormal")) { flags = SHOW_NORMAL; } else if (StrEquals(tok,"NoSticky")) { flags &= ~(SHOW_STICKY_ACROSS_PAGES); flags &= ~(SHOW_STICKY_ACROSS_DESKS); } else if (StrEquals(tok,"NoStickyPage")) { flags &= ~(SHOW_STICKY_ACROSS_PAGES); } else if (StrEquals(tok,"NoStickyDesk")) { flags &= ~(SHOW_STICKY_ACROSS_DESKS); } else if (StrEquals(tok,"Sticky")) { flags |= SHOW_STICKY_ACROSS_PAGES; flags |= SHOW_STICKY_ACROSS_DESKS; } else if (StrEquals(tok,"StickyPage")) { flags |= SHOW_STICKY_ACROSS_PAGES; } else if (StrEquals(tok,"StickyDesk")) { flags |= SHOW_STICKY_ACROSS_DESKS; } else if (StrEquals(tok,"OnlySticky")) { flags = SHOW_STICKY_ACROSS_PAGES; flags = SHOW_STICKY_ACROSS_DESKS; } else if (StrEquals(tok,"OnlyStickyPage")) { flags = SHOW_STICKY_ACROSS_PAGES; } else if (StrEquals(tok,"OnlyStickyDesk")) { flags = SHOW_STICKY_ACROSS_DESKS; } else if (StrEquals(tok,"UseListSkip")) { /* deprecated as of 02-May-2007 (SS) */ fprintf(stderr, "UseListSkip is deprecated. Please use \"UseSkipList\".\n"); skiplist_mode = 1; } else if (StrEquals(tok,"UseSkipList")) { skiplist_mode = 1; } else if (StrEquals(tok,"OnlyListSkip")) { /* deprecated as of 02-May-2007 (SS) */ fprintf(stderr, "OnlyListSkip is deprecated. Please use \"OnlySkipList\".\n"); skiplist_mode = 2; } else if (StrEquals(tok,"OnlySkipList")) { skiplist_mode = 2; } else if (StrEquals(tok,"NoDeskNum")) { flags |= NO_DESK_NUM; } else if (StrEquals(tok,"NoLayer")) { flags |= NO_LAYER; } else if (StrEquals(tok,"NoCurrentDeskTitle")) { flags |= NO_CURRENT_DESK_TITLE; } else if (StrEquals(tok,"TitleForAllDesks")) { flags |= TITLE_FOR_ALL_DESKS; } else if (StrEquals(tok,"NoNumInDeskTitle")) { flags |= NO_NUM_IN_DESK_TITLE; } /* these are a bit dubious, but we should keep the * OnTop options for compatibility */ else if (StrEquals(tok, "NoOnTop")) { if (high_layer >= Scr.TopLayer) { high_layer = Scr.TopLayer - 1; } } else if (StrEquals(tok, "OnTop")) { if (high_layer < Scr.TopLayer) { high_layer = Scr.TopLayer; } } else if (StrEquals(tok, "OnlyOnTop")) { high_layer = low_layer = Scr.TopLayer; } else if (StrEquals(tok, "NoOnBottom")) { if (low_layer <= Scr.BottomLayer) { low_layer = Scr.BottomLayer - 1; } } else if (StrEquals(tok, "OnBottom")) { if (low_layer > Scr.BottomLayer) { low_layer = Scr.BottomLayer; } } else if (StrEquals(tok, "OnlyOnBottom")) { high_layer = low_layer = Scr.BottomLayer; } else if (StrEquals(tok, "Layer")) { free(tok); opts = GetNextSimpleOption(opts, &tok); if (tok) { low_layer = high_layer = atoi(tok); free(tok); opts = GetNextSimpleOption(opts, &tok); if (tok) { high_layer = atoi(tok); } } } else if (StrEquals(tok, "SelectOnRelease")) { if (sor_keyname != sor_default_keyname) { free(sor_keyname); } sor_keyname = NULL; opts = GetNextSimpleOption(opts, &sor_keyname); } else if (StrEquals(tok, "MaxLabelWidth")) { char *wid; opts = GetNextSimpleOption(opts, &wid); if (wid) { max_label_width = atoi(wid); if (max_label_width < 1) { max_label_width = 1; } free(wid); } } else if (!opts || !*opts) { default_action = safestrdup(tok); } else { fvwm_msg( ERR, "WindowList","Unknown option '%s'", tok); } if (tok) { free(tok); } } } if (was_get_menu_opts_called == False) { opts = get_menu_options( action, w, fw, NULL, NULL, NULL, &mops); } tlabel = get_desk_title(desk, flags, True); mr = NewMenuRoot(tlabel); if (!(flags & NO_CURRENT_DESK_TITLE)) { AddToMenu(mr, tlabel, "TITLE", False, False, False); empty_menu = False; } free(tlabel); numWindows = 0; for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { numWindows++; } windowList = malloc(numWindows*sizeof(t)); if (windowList == NULL) { return; } if (iconified_at_end) { iconifiedList = malloc(numWindows*sizeof(t)); if (iconifiedList == NULL) { free(windowList); return; } } /* get the windowlist starting from the current window (if any)*/ t = get_focus_window(); if (t == NULL) { t = Scr.FvwmRoot.next; } else if (current_at_end) { if (t->next) { t = t->next; } else { t = Scr.FvwmRoot.next; } } for (ii = 0; ii < numWindows; ii++) { if (flags & SORT_REVERSE) { windowList[numWindows - ii - 1] = t; } else if (iconified_at_end && IS_ICONIFIED(t)) { iconifiedList[ic++] = t; } else { windowList[ii - ic] = t; } if (t->next) { t = t->next; } else { t = Scr.FvwmRoot.next; } } if (iconified_at_end && ic > 0) { if (current_at_end && ii > ic) { windowList[numWindows - 1] = windowList[--ii - ic]; } for (ij = 0; ij < ic; ij++) { windowList[ij + (ii - ic)] = iconifiedList[ij]; } } /* Do alphabetic sort */ if (flags & (SHOW_ALPHABETIC | SORT_BYCLASS | SORT_BYRESOURCE)) { /* This will be compare or compareReverse if a reverse order * is selected. */ int (*sort)(const FvwmWindow **a, const FvwmWindow **b); switch (flags & (SHOW_ALPHABETIC | SHOW_ICONNAME | \ SORT_BYCLASS | SORT_BYRESOURCE)) { case SHOW_ALPHABETIC: compare = visibleCompare; break; case SHOW_ALPHABETIC | SHOW_ICONNAME: compare = iconCompare; break; /* Sorting based on class name produces an alphabetic * order so the keyword alphabetic is redundant. */ case SORT_BYCLASS: case SORT_BYCLASS | SHOW_ALPHABETIC: compare = classCompare; break; case SORT_BYCLASS | SHOW_ICONNAME: case SORT_BYCLASS | SHOW_ICONNAME | SHOW_ALPHABETIC: compare = classIconCompare; break; case SORT_BYRESOURCE: case SORT_BYRESOURCE | SORT_BYCLASS: case SORT_BYRESOURCE | SORT_BYCLASS | SHOW_ALPHABETIC: compare = resourceCompare; break; case SORT_BYRESOURCE | SHOW_ICONNAME: case SORT_BYRESOURCE | SHOW_ICONNAME | SORT_BYCLASS: case SORT_BYRESOURCE | SHOW_ICONNAME | SORT_BYCLASS | \ SHOW_ALPHABETIC: compare = resourceIconCompare; break; /* All current cases are covered, but if something * changes in the future we leave compare valid even if * it isn't what is expected. */ default: compare = visibleCompare; break; } if ( flags & SORT_REVERSE ) { sort = compareReverse; } else { sort = compare; } qsort(windowList, numWindows, sizeof(t), (int(*)(const void*, const void*))sort); } while(next_desk != INT_MAX) { /* Sort window list by desktop number */ if ((flags & SHOW_ALLDESKS) && !(flags & NO_DESK_SORT)) { /* run through the windowlist finding the first desk * not already processed */ next_desk = INT_MAX; for (ii = 0; ii < numWindows; ii++) { t = windowList[ii]; if (t->Desk >last_desk_done && t->Desk < next_desk) { next_desk = t->Desk; } } } if (!(flags & SHOW_ALLDESKS)) { /* if only doing one desk and it hasn't been done */ if (last_desk_done == INT_MIN) next_desk = desk; /* select the desk */ else next_desk = INT_MAX; /* flag completion */ } if (flags & NO_DESK_SORT) next_desk = INT_MAX; /* only go through loop once */ last_desk_done = next_desk; for (ii = 0; ii < numWindows; ii++) { t = windowList[ii]; if (t->Desk != next_desk && !(flags & NO_DESK_SORT)) { continue; } if (skiplist_mode == 0 && DO_SKIP_WINDOW_LIST(t)) { /* don't want skiplist windows - skip */ continue; } if (skiplist_mode == 2 && !DO_SKIP_WINDOW_LIST(t)) { /* don't want no skiplist one - skip */ continue; } if (use_condition && !MatchesConditionMask(t, &mask)) { /* doesn't match specified condition */ continue; } if (!(flags & SHOW_ICONIC) && (IS_ICONIFIED(t))) { /* don't want icons - skip */ continue; } if (!(flags & SHOW_STICKY_ACROSS_PAGES) && (IS_STICKY_ACROSS_PAGES(t))) { /* don't want sticky ones - skip */ continue; } if (!(flags & SHOW_STICKY_ACROSS_DESKS) && (IS_STICKY_ACROSS_DESKS(t))) { /* don't want sticky ones - skip */ continue; } if (!(flags & SHOW_NORMAL) && !(IS_ICONIFIED(t) || IS_STICKY_ACROSS_PAGES(t) || IS_STICKY_ACROSS_DESKS(t))) { /* don't want "normal" ones - skip */ continue; } if (get_layer(t) < low_layer || get_layer(t) > high_layer) { /* don't want this layer */ continue; } empty_menu = False; /* add separator between desks when geometry * shown but not at the top*/ if (t->Desk != last_desk_displayed) { if (last_desk_displayed != INT_MIN) { if (((flags & SHOW_GEOMETRY) || (flags & SHOW_INFONOTGEO)) && !(flags & TITLE_FOR_ALL_DESKS)) { AddToMenu( mr, NULL, NULL, False, False, False); } if (flags & TITLE_FOR_ALL_DESKS) { tlabel = get_desk_title( t->Desk, flags, False); AddToMenu( mr, tlabel, "TITLE", False, False, False); free(tlabel); } } last_desk_displayed = t->Desk; } if (first_desk && flags & TITLE_FOR_ALL_DESKS) { tlabel = get_desk_title(t->Desk, flags, False); AddToMenu( mr, tlabel, "TITLE", False, False, False); free(tlabel); } first_desk = False; if (flags & SHOW_ICONNAME) { name = t->visible_icon_name; } else { name = t->visible_name; } free_name = False; if (!name) { name = "NULL_NAME"; } else if (max_label_width > 0 && strlen(name) > max_label_width) { name = strdup(name); name[max_label_width] = '\0'; free_name = True; } t_hot = safemalloc(strlen(name) + 80); if (use_hotkey) { /* Generate label */ sprintf(t_hot, "&%c. ", scut); } else { *t_hot = 0; } if (!(flags & SHOW_INFONOTGEO)) { strcat(t_hot, name); } if (*t_hot == 0) { strcpy(t_hot, " "); } /* Next shortcut key */ if (scut == '9') { scut = 'A'; } else if (scut == 'Z') { scut = '0'; } else { scut++; } if (flags & SHOW_INFONOTGEO) { tname[0]=0; if (!IS_ICONIFIED(t) && !(flags & NO_DESK_NUM)) { sprintf(loc,"%d:", t->Desk); strcat(tname,loc); } if (IS_ICONIFIED(t)) { strcat(tname, "("); } strcat(t_hot,"\t"); strcat(t_hot,tname); strcat(t_hot, name); if (IS_ICONIFIED(t)) { strcat(t_hot, ")"); } } else if (flags & SHOW_GEOMETRY) { size_borders b; tname[0]=0; if (IS_ICONIFIED(t)) { strcpy(tname, "("); } if (!(flags & NO_DESK_NUM)) { sprintf(loc, "%d", t->Desk); strcat(tname, loc); } if (flags & SHOW_SCREEN) { fscreen_scr_arg fscr; int scr; fscr.xypos.x = Scr.Vx + t->g.frame.x + t->g.frame.width / 2; fscr.xypos.y = Scr.Vy + t->g.frame.y + t->g.frame.height / 2; scr = FScreenGetScrId( &fscr, FSCREEN_XYPOS); sprintf(loc, "@%d", scr); strcat(tname, loc); } if (flags & SHOW_PAGE_X) { sprintf(loc, "+%d", (Scr.Vx + t->g.frame.x + t->g.frame.width / 2) / Scr.MyDisplayWidth); strcat(tname, loc); } if (flags & SHOW_PAGE_Y) { sprintf(loc, "+%d", (Scr.Vy + t->g.frame.y + t->g.frame.height/2) / Scr.MyDisplayHeight); strcat(tname, loc); } if (!(flags & NO_LAYER)) { sprintf(loc, "(%d)", (get_layer(t))); strcat(tname, loc); } strcat(tname, ":"); get_window_borders(t, &b); dheight = t->g.frame.height - b.total_size.height; dwidth = t->g.frame.width - b.total_size.width; dwidth = (dwidth - t->hints.base_width) /t->orig_hints.width_inc; dheight = (dheight - t->hints.base_height) /t->orig_hints.height_inc; sprintf(loc,"%d",dwidth); strcat(tname, loc); sprintf(loc,"x%d",dheight); strcat(tname, loc); if (t->g.frame.x >=0) { sprintf(loc,"+%d",t->g.frame.x); } else { sprintf(loc,"%d",t->g.frame.x); } strcat(tname, loc); if (t->g.frame.y >=0) { sprintf(loc,"+%d",t->g.frame.y); } else { sprintf(loc,"%d",t->g.frame.y); } strcat(tname, loc); if (IS_STICKY_ACROSS_PAGES(t) || IS_STICKY_ACROSS_DESKS(t)) { strcat(tname, " S"); } if (IS_ICONIFIED(t)) { strcat(tname, ")"); } strcat(t_hot,"\t"); strcat(t_hot,tname); } ffunc = func ? func : "WindowListFunc"; tfunc = safemalloc(strlen(ffunc) + 36); /* support two ways for now: window context * (new) and window id param (old) */ sprintf(tfunc, "WindowId %lu %s %lu", FW_W(t), ffunc, FW_W(t)); AddToMenu( mr, t_hot, tfunc, False, False, False); free(tfunc); /* Add the title pixmap */ if (FMiniIconsSupported && t->mini_icon) { MI_MINI_ICON(MR_LAST_ITEM(mr))[0] = t->mini_icon; /* increase the cache count. Otherwise the * pixmap will be eventually removed from the * cache by DestroyMenu */ t->mini_icon->count++; } if (t_hot) { free(t_hot); } if (free_name) { free(name); } } } if (empty_menu) { /* force current desk title */ tlabel = get_desk_title(desk, flags, True); AddToMenu(mr, tlabel, "TITLE", False, False, False); free(tlabel); } if (func) { free(func); } free(windowList); if (iconified_at_end) { free(iconifiedList); } /* Use the WindowList menu style if there is one */ change_mr_menu_style(mr, "WindowList"); /* Activate select_on_release style */ old_sor_keycode = MST_SELECT_ON_RELEASE_KEY(mr); if (sor_keyname && (!MST_SELECT_ON_RELEASE_KEY(mr) || sor_keyname != sor_default_keyname)) { MST_SELECT_ON_RELEASE_KEY(mr) = XKeysymToKeycode( dpy, FvwmStringToKeysym(dpy, sor_keyname)); } memset(&mp, 0, sizeof(mp)); mp.menu = mr; exc2 = exc_clone_context(exc, NULL, 0); mp.pexc = &exc2; mp.flags.has_default_action = (default_action && *default_action != 0); mp.flags.is_sticky = 1; mp.flags.is_submenu = 0; mp.flags.is_already_mapped = 0; mp.flags.is_triggered_by_keypress = (!default_action && exc->x.etrigger->type == KeyPress); mp.pops = &mops; mp.ret_paction = &ret_action; do_menu(&mp, &mret); /* Restore old menu style */ MST_SELECT_ON_RELEASE_KEY(mr) = old_sor_keycode; if (ret_action) { free(ret_action); } DestroyMenu(mr, False, False); if (mret.rc == MENU_DOUBLE_CLICKED && default_action && *default_action) { execute_function(cond_rc, exc2, default_action, 0); } if (default_action != NULL) { free(default_action); } if (use_condition) { FreeConditionMask(&mask); } if (sor_keyname && sor_keyname != sor_default_keyname) { free(sor_keyname); } exc_destroy_context(exc2); return; }
dsc* EVAL_value(qli_nod* node) { /************************************** * * E V A L _ v a l u e * ************************************** * * Functional description * Evaluate a value node. * **************************************/ DSC *values[4]; // Start by evaluating sub-expressions (where appropriate) dsc* desc = &node->nod_desc; fb_assert(node->nod_count < 5); qli_nod** ptr = node->nod_arg; const qli_nod* const* const end_ptr = ptr + node->nod_count; for (dsc** value = values; ptr < end_ptr; ptr++, value++) { *value = EVAL_value(*ptr); if (node->nod_flags & nod_partial) break; } switch (node->nod_type) { case nod_edit_blob: return execute_edit(node); case nod_rpt_max: case nod_rpt_min: case nod_rpt_total: case nod_rpt_average: if (!(IPTR) node->nod_arg[e_stt_default]) desc->dsc_missing = DSC_missing; case nod_rpt_count: case nod_constant: return desc; case nod_variable: { qli_fld* field = (qli_fld*) node->nod_arg[e_fld_field]; desc->dsc_missing = (field->fld_flags & FLD_missing) ? DSC_missing : 0; } return desc; case nod_field: return EVAL_value(node->nod_arg[e_fld_reference]); case nod_reference: return EVAL_parameter(node->nod_import); case nod_null: return desc; case nod_add: if ((values[0]->dsc_missing & DSC_missing) || (values[1]->dsc_missing & DSC_missing)) { desc->dsc_missing = DSC_missing; return desc; } desc->dsc_missing = FALSE; if (node->nod_flags & nod_date) { double d1 = MOVQ_date_to_double(values[0]) + MOVQ_get_double(values[1]); MOVQ_double_to_date(d1, (SLONG*) desc->dsc_address); } else if (desc->dsc_dtype == dtype_long) { *((SLONG*) desc->dsc_address) = MOVQ_get_long(values[0], desc->dsc_scale) + MOVQ_get_long(values[1], desc->dsc_scale); } else *((double*) desc->dsc_address) = MOVQ_get_double(values[0]) + MOVQ_get_double(values[1]); return desc; case nod_subtract: if ((values[0]->dsc_missing & DSC_missing) || (values[1]->dsc_missing & DSC_missing)) { desc->dsc_missing = DSC_missing; return desc; } desc->dsc_missing = FALSE; if (node->nod_flags & nod_date) { *((double*) desc->dsc_address) = MOVQ_date_to_double(values[0]) - MOVQ_date_to_double(values[1]); } else if (desc->dsc_dtype == dtype_long) { *((SLONG*) desc->dsc_address) = MOVQ_get_long(values[0], desc->dsc_scale) - MOVQ_get_long(values[1], desc->dsc_scale); } else *((double*) desc->dsc_address) = MOVQ_get_double(values[0]) - MOVQ_get_double(values[1]); return desc; case nod_divide: if ((values[0]->dsc_missing & DSC_missing) || (values[1]->dsc_missing & DSC_missing)) { desc->dsc_missing = DSC_missing; return desc; } desc->dsc_missing = FALSE; *((double*) desc->dsc_address) = MOVQ_get_double(values[0]) / MOVQ_get_double(values[1]); return desc; case nod_multiply: if ((values[0]->dsc_missing & DSC_missing) || (values[1]->dsc_missing & DSC_missing)) { desc->dsc_missing = DSC_missing; return desc; } desc->dsc_missing = FALSE; if (desc->dsc_dtype == dtype_long) { *((SLONG*) desc->dsc_address) = MOVQ_get_long(values[0], values[0]->dsc_scale) * MOVQ_get_long(values[1], values[1]->dsc_scale); } else *((double*) desc->dsc_address) = MOVQ_get_double(values[0]) * MOVQ_get_double(values[1]); return desc; case nod_negate: if (values[0]->dsc_missing & DSC_missing) { desc->dsc_missing = DSC_missing; return desc; } desc->dsc_missing = FALSE; switch (desc->dsc_dtype) { case dtype_short: *((SSHORT*) desc->dsc_address) = -MOVQ_get_long(values[0], desc->dsc_scale); break; case dtype_long: *((SLONG*) desc->dsc_address) = -MOVQ_get_long(values[0], desc->dsc_scale); break; // lets throw arithmetic not supported until fixed //case dtype_int64: // *((SINT64*) desc->dsc_address) = -MOVQ_get_long(values[0], desc->dsc_scale); // break; case dtype_real: *((float*) desc->dsc_address) = -MOVQ_get_double(values[0]); break; case dtype_double: *((double*) desc->dsc_address) = -MOVQ_get_double(values[0]); break; default: IBERROR(30); // Msg30 data type not supported for arithmetic } return desc; case nod_prompt: if (!prompt[0][0]) { ERRQ_msg_get(499, prompt[0], sizeof(prompt[0])); // Msg499 Re-enter ERRQ_msg_get(500, prompt[1], sizeof(prompt[1])); // Msg500 Enter } return execute_prompt(node); case nod_concatenate: return execute_concatenate(node, values[0], values[1]); case nod_function: return execute_function(node); case nod_max: case nod_min: case nod_count: case nod_average: case nod_total: case nod_from: return execute_statistical(node); case nod_running_count: *(SLONG*) (desc->dsc_address) += 1; return desc; case nod_running_total: { dsc* desc2 = EVAL_value(node->nod_arg[e_stt_value]); if (desc2) { if (desc2->dsc_missing & DSC_missing) return desc; if (desc->dsc_dtype == dtype_long) *(SLONG*) desc->dsc_address += MOVQ_get_long(desc2, desc->dsc_scale); else *(double*) desc->dsc_address += MOVQ_get_double(desc2); } } return desc; case nod_format: { UCHAR* p = desc->dsc_address; PIC_edit(values[0], (pics*) node->nod_arg[e_fmt_picture], (TEXT**) &p, desc->dsc_length); desc->dsc_length = p - desc->dsc_address; } return desc; case nod_user_name: IBERROR(31); // Msg31 user name is supported only in RSEs temporarily case nod_parameter: case nod_position: case nod_substr: case nod_via: default: ERRQ_bugcheck(29); // Msg29 EVAL_value: not finished return NULL; } }
static void menu_func(F_CMD_ARGS, Bool fStaysUp) { struct MenuRoot *menu; char *ret_action = NULL; struct MenuOptions mops; char *menu_name = NULL; struct MenuParameters mp; struct MenuReturn mret; FvwmWindow * const fw = exc->w.fw; const Window w = exc->w.w; const exec_context_t *exc2; memset(&mops, 0, sizeof(mops)); memset(&mret, 0, sizeof(MenuReturn)); action = GetNextToken(action,&menu_name); action = get_menu_options( action, w, fw, NULL, NULL, NULL, &mops); while (action && *action && isspace((unsigned char)*action)) { action++; } if (action && *action == 0) { action = NULL; } menu = menus_find_menu(menu_name); if (menu == NULL) { if (menu_name) { fvwm_msg(ERR,"menu_func","No such menu %s",menu_name); free(menu_name); } return; } if (menu_name && set_repeat_data( menu_name, (fStaysUp) ? REPEAT_MENU : REPEAT_POPUP,NULL)) { free(menu_name); } memset(&mp, 0, sizeof(mp)); mp.menu = menu; exc2 = exc_clone_context(exc, NULL, 0); mp.pexc = &exc2; MR_IS_TEAR_OFF_MENU(menu) = 0; mp.flags.has_default_action = (action != NULL); mp.flags.is_sticky = fStaysUp; mp.flags.is_submenu = False; mp.flags.is_already_mapped = False; mp.flags.is_triggered_by_keypress = (exc->x.etrigger->type == KeyPress); mp.pops = &mops; mp.ret_paction = &ret_action; do_menu(&mp, &mret); if (mret.rc == MENU_DOUBLE_CLICKED && action) { execute_function(cond_rc, exc2, action, 0); } if (ret_action != NULL) { free(ret_action); } exc_destroy_context(exc2); return; }