1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
25 #include <sys/param.h>
29 #include "DbeSession.h"
31 #include "Application.h"
32 #include "MemorySpace.h"
33 #include "StringBuilder.h"
39 // Commands for compiler commentary
40 static const char *comp_cmd[] = {
61 static const int comp_vis[] = {
82 const int comp_size = sizeof (comp_cmd) / sizeof (char *);
84 // Commands for timeline
96 TLModeSubcommand cmdType;
99 static const TLModeCmd tlmode_cmd[] = {
101 {NTXT ("lwp"), TLCMD_ENTITY_MODE, PROP_LWPID},
102 {NTXT ("thread"), TLCMD_ENTITY_MODE, PROP_THRID},
103 {NTXT ("cpu"), TLCMD_ENTITY_MODE, PROP_CPUID},
104 {NTXT ("experiment"), TLCMD_ENTITY_MODE, PROP_EXPID},
106 {NTXT ("root"), TLCMD_ALIGN, TLSTACK_ALIGN_ROOT},
107 {NTXT ("leaf"), TLCMD_ALIGN, TLSTACK_ALIGN_LEAF},
109 {NTXT ("depth"), TLCMD_DEPTH, 0 /* don't care */}
112 static const int tlmode_size = sizeof (tlmode_cmd) / sizeof (TLModeCmd);
116 Settings::Settings (Application *_app)
118 // Remember the application
121 // Clear all default strings
135 str_search_path = NULL;
136 str_name_format = NULL;
138 str_printmode = NULL;
140 preload_libdirs = NULL;
141 pathmaps = new Vector<pathmap_t*>;
142 lo_expands = new Vector<lo_expand_t*>;
143 lo_expand_default = LIBEX_SHOW;
144 is_loexpand_default = true;
145 tabs_processed = false;
147 // set default-default values
148 name_format = Histable::NA;
149 view_mode = VMODE_USER;
153 src_compcom = 2147483647;
154 dis_compcom = 2147483647;
155 #define DEFAULT_SRC_DIS_THRESHOLD 75
156 threshold_src = DEFAULT_SRC_DIS_THRESHOLD;
157 threshold_dis = DEFAULT_SRC_DIS_THRESHOLD;
159 srcmetric_visible = false;
161 cmpline_visible = true;
162 funcline_visible = true;
168 // print mode is initialized after the .rc files are read
170 compare_mode = CMP_DISABLE;
172 ignore_no_xhwcprof = false;
173 ignore_fs_warn = false;
175 // construct the master list of tabs
176 buildMasterTabList ();
178 indx_tab_state = new Vector<bool>;
179 indx_tab_order = new Vector<int>;
180 mem_tab_state = new Vector<bool>;
181 mem_tab_order = new Vector<int>;
183 // note that the .rc files are not read here, but later
186 // Constructor for duplicating an existing Settings class
188 Settings::Settings (Settings * _settings)
191 app = _settings->app;
193 // Copy all default strings
194 str_vmode = dbe_strdup (_settings->str_vmode);
195 str_en_desc = dbe_strdup (_settings->str_en_desc);
196 str_datamode = dbe_strdup (_settings->str_datamode);
197 str_scompcom = dbe_strdup (_settings->str_scompcom);
198 str_sthresh = dbe_strdup (_settings->str_sthresh);
199 str_dcompcom = dbe_strdup (_settings->str_dcompcom);
200 str_dthresh = dbe_strdup (_settings->str_dthresh);
201 str_dmetrics = dbe_strdup (_settings->str_dmetrics);
202 str_dsort = dbe_strdup (_settings->str_dsort);
203 str_tlmode = dbe_strdup (_settings->str_tlmode);
204 str_tldata = dbe_strdup (_settings->str_tldata);
205 str_tabs = dbe_strdup (_settings->str_tabs);
206 str_rtabs = dbe_strdup (_settings->str_rtabs);
207 str_search_path = dbe_strdup (_settings->str_search_path);
208 str_name_format = dbe_strdup (_settings->str_name_format);
209 str_limit = dbe_strdup (_settings->str_limit);
210 str_printmode = dbe_strdup (_settings->str_printmode);
211 str_compare = dbe_strdup (_settings->str_compare);
212 preload_libdirs = dbe_strdup (_settings->preload_libdirs);
214 // replicate the pathmap vector
217 pathmaps = new Vector<pathmap_t*>;
219 Vec_loop (pathmap_t*, _settings->pathmaps, index, thismap)
221 newmap = new pathmap_t;
222 newmap->old_prefix = dbe_strdup (thismap->old_prefix);
223 newmap->new_prefix = dbe_strdup (thismap->new_prefix);
224 pathmaps->append (newmap);
227 // replicate the lo_expand vector and default
228 lo_expand_t *this_lo_ex;
229 lo_expand_t *new_lo_ex;
230 lo_expand_default = _settings->lo_expand_default;
231 is_loexpand_default = _settings->is_loexpand_default;
232 lo_expands = new Vector<lo_expand_t*>;
234 Vec_loop (lo_expand_t*, _settings->lo_expands, index, this_lo_ex)
236 new_lo_ex = new lo_expand_t;
237 new_lo_ex->libname = dbe_strdup (this_lo_ex->libname);
238 new_lo_ex->expand = this_lo_ex->expand;
239 lo_expands->append (new_lo_ex);
241 tabs_processed = _settings->tabs_processed;
243 // Copy the various values from the _settings instance
244 name_format = _settings->name_format;
245 view_mode = _settings->view_mode;
249 if (_settings->en_desc_usr)
250 set_en_desc (_settings->en_desc_usr, true);
251 src_compcom = _settings->src_compcom;
252 dis_compcom = _settings->dis_compcom;
253 threshold_src = _settings->threshold_src;
254 threshold_dis = _settings->threshold_dis;
255 src_visible = _settings->src_visible;
256 srcmetric_visible = _settings->srcmetric_visible;
257 hex_visible = _settings->hex_visible;
258 cmpline_visible = _settings->cmpline_visible;
259 funcline_visible = _settings->funcline_visible;
260 tldata = dbe_strdup (_settings->tldata);
261 tlmode = _settings->tlmode;
262 stack_align = _settings->stack_align;
263 stack_depth = _settings->stack_depth;
264 limit = _settings->limit;
265 print_mode = _settings->print_mode;
266 print_delim = _settings->print_delim;
267 compare_mode = _settings->compare_mode;
268 machinemodel = dbe_strdup (_settings->machinemodel);
269 ignore_no_xhwcprof = _settings->ignore_no_xhwcprof;
270 ignore_fs_warn = _settings->ignore_fs_warn;
272 // copy the tab list, too
273 tab_list = new Vector<DispTab*>;
276 Vec_loop (DispTab*, _settings->tab_list, index, dsptab)
279 ntab = new DispTab (dsptab->type, dsptab->order, dsptab->visible, dsptab->cmdtoken);
280 ntab->setAvailability (dsptab->available);
281 tab_list->append (ntab);
284 // construct the master list of memory tabs & copy order
285 index = _settings->mem_tab_state->size ();
286 mem_tab_state = new Vector<bool>(index);
287 mem_tab_order = new Vector<int>(index);
288 for (int i = 0; i < index; i++)
290 mem_tab_state->append (false);
291 mem_tab_order->append (_settings->mem_tab_order->fetch (i));
294 // construct the master list of index tabs & copy order
295 index = _settings->indx_tab_state->size ();
296 indx_tab_state = new Vector<bool>(index);
297 indx_tab_order = new Vector<int>(index);
298 for (int i = 0; i < index; i++)
299 indx_tab_order->append (_settings->indx_tab_order->fetch (i));
300 set_IndxTabState (_settings->indx_tab_state);
303 Settings::~Settings ()
305 for (int i = 0; i < pathmaps->size (); ++i)
307 pathmap_t *pmap = pathmaps->fetch (i);
308 free (pmap->old_prefix);
309 free (pmap->new_prefix);
314 for (int i = 0; i < lo_expands->size (); ++i)
316 lo_expand_t *lo_ex = lo_expands->fetch (i);
317 free (lo_ex->libname);
322 tab_list->destroy ();
324 delete indx_tab_state;
325 delete indx_tab_order;
326 delete mem_tab_state;
327 delete mem_tab_order;
342 free (str_search_path);
343 free (str_name_format);
346 free (str_printmode);
347 free (preload_libdirs);
352 regfree (en_desc_cmp);
358 * Read .er.rc file from the specified location
363 Settings::read_rc (char *path)
366 Emsgqueue *commentq = new Emsgqueue (NTXT ("setting_commentq"));
370 return dbe_strdup (GTXT ("Error: empty file name"));
371 bool override = true;
372 set_rc (path, true, commentq, override);
373 Emsg *msg = commentq->fetch ();
376 char *str = msg->get_msg ();
380 return sb.toString ();
384 Settings::read_rc (bool ipc_or_rdt_mode)
386 bool override = false;
388 // Read file from the current working directory
389 char *rc_path = realpath (NTXT ("./.gprofng.rc"), NULL);
391 set_rc (rc_path, true, app->get_comments_queue (), override, ipc_or_rdt_mode);
393 // Read file from the user's home directory
394 char *home = getenv (NTXT ("HOME"));
397 char *strbuf = dbe_sprintf (NTXT ("%s/.gprofng.rc"), home);
398 char *home_rc_path = realpath (strbuf, NULL);
401 if (rc_path == NULL || strcmp (rc_path, home_rc_path) != 0)
402 set_rc (home_rc_path, true, app->get_comments_queue (), override, ipc_or_rdt_mode);
409 // Read system-wide file
410 const char *sysconfdir = getenv("GPROFNG_SYSCONFDIR");
411 if (sysconfdir == NULL)
412 sysconfdir = SYSCONFDIR;
413 rc_path = dbe_sprintf (NTXT ("%s/gprofng.rc"), sysconfdir);
414 if (access (rc_path, R_OK | F_OK) != 0)
417 sb.sprintf (GTXT ("Warning: Default gprofng.rc file (%s) missing; configuration error "), rc_path);
418 Emsg *m = new Emsg (CMSG_COMMENT, sb);
419 app->get_comments_queue ()->append (m);
422 set_rc (rc_path, false, app->get_comments_queue (), override);
424 is_loexpand_default = true;
425 if (str_printmode == NULL)
427 // only if there's none set
428 print_mode = PM_TEXT;
429 str_printmode = dbe_strdup (NTXT ("text"));
434 // Handle various settings from reading the name .rc file
435 // This function is called for each .rc file read, and, for
436 // some settings, it accumulates the strings from the files.
437 // For others, it accepts the first appearance for a setting in a
438 // .rc file, and ignores subsequent appearances from other files.
439 // Error messages are appended to the Emsgqueue specified by the caller
444 Settings::set_rc (const char *path, bool msg, Emsgqueue *commentq,
445 bool override, bool ipc_or_rdt_mode)
448 int arg_count, cparam;
449 char *cmd, *end_cmd, *strbuf;
450 char *arglist[MAXARGS];
453 FILE *fptr = fopen (path, NTXT ("r"));
459 sb.sprintf (GTXT ("Processed %s for default settings"), path);
460 Emsg *m = new Emsg (CMSG_COMMENT, sb);
461 commentq->append (m);
467 char *script = read_line (fptr);
471 strtok (script, NTXT ("\n"));
473 // extract the command
474 cmd = strtok (script, NTXT (" \t"));
475 if (cmd == NULL || *cmd == '#' || *cmd == '\n')
480 char *remainder = strtok (NULL, NTXT ("\n"));
481 // now extract the arguments
485 if (nargs >= MAXARGS)
489 msg = true; // suppress repeats of header
490 Emsg *m = new Emsg (CMSG_COMMENT, GTXT ("Processed system gprofng.rc file for default settings"));
491 commentq->append (m);
493 sb.sprintf (GTXT ("Warning: more than %d arguments to %s command, line %d\n"),
494 MAXARGS, cmd, line_no);
495 Emsg *m = new Emsg (CMSG_COMMENT, sb);
496 commentq->append (m);
500 char *nextarg = strtok (remainder, NTXT ("\n"));
501 if (nextarg == NULL || *nextarg == '#')
503 arglist[nargs++] = parse_qstring (nextarg, &end_cmd);
505 if (remainder == NULL)
507 // skip any blanks or tabs to get to next argument
508 while (*remainder == ' ' || *remainder == '\t')
511 cmd_type = Command::get_command (cmd, arg_count, cparam);
512 // check for extra arguments
513 if ((cmd_type != UNKNOWN_CMD && cmd_type != INDXOBJDEF) && (nargs > arg_count))
517 msg = true; // suppress repeats of header
518 Emsg *m = new Emsg (CMSG_COMMENT, GTXT ("Processed system gprofng.rc file for default settings"));
519 commentq->append (m);
521 sb.sprintf (GTXT ("Warning: extra arguments to %s command, line %d\n"), cmd, line_no);
522 Emsg *m = new Emsg (CMSG_COMMENT, sb);
523 commentq->append (m);
525 if (nargs < arg_count)
529 msg = true; // suppress repeats of header
530 Emsg *m = new Emsg (CMSG_COMMENT, GTXT ("Processed system gprofng.rc file for default settings"));
531 commentq->append (m);
533 sb.sprintf (GTXT ("Error: missing arguments to %s command, line %d\n"),
535 Emsg *m = new Emsg (CMSG_COMMENT, sb);
536 commentq->append (m);
538 // ignore this command
542 if (ipc_or_rdt_mode && (cmd_type != ADDPATH) && (cmd_type != PATHMAP))
550 if (!str_scompcom || override)
552 str_scompcom = dbe_strdup (arglist[0]);
553 proc_compcom (arglist[0], true, true);
557 if (!str_sthresh || override)
559 str_sthresh = dbe_strdup (arglist[0]);
560 proc_thresh (arglist[0], true, true);
565 if (!str_dcompcom || override)
567 str_dcompcom = dbe_strdup (arglist[0]);
568 proc_compcom (arglist[0], false, true);
572 // process as if it were for both source and disassembly
573 // note that if it is set, subsequent SCOMPCOM and DCOMPCOM
575 if (!str_scompcom || override)
577 str_scompcom = dbe_strdup (arglist[0]);
578 proc_compcom (arglist[0], true, true);
580 if (!str_dcompcom || override)
582 str_dcompcom = dbe_strdup (arglist[0]);
583 proc_compcom (arglist[0], false, true);
587 if (!str_dthresh || override)
589 str_dthresh = dbe_strdup (arglist[0]);
590 proc_thresh (arglist[0], false, true);
594 // append new settings to old, if necessary
597 char *name = strstr (str_dmetrics, ":name");
599 strbuf = dbe_sprintf ("%s:%s", str_dmetrics, arglist[0]);
602 char * next = strstr (name + 1, ":");
606 strbuf = dbe_sprintf ("%s:%s:name", str_dmetrics, arglist[0]);
609 strbuf = dbe_sprintf ("%s:%s", str_dmetrics, arglist[0]);
612 str_dmetrics = strbuf;
615 str_dmetrics = dbe_strdup (arglist[0]);
618 // append new settings to old, if necessary
621 strbuf = dbe_sprintf (NTXT ("%s:%s"), str_dsort, arglist[0]);
626 str_dsort = dbe_strdup (arglist[0]);
629 if (!str_tlmode || override)
631 str_tlmode = dbe_strdup (arglist[0]);
632 proc_tlmode (arglist[0], true);
636 if (!str_tldata || override)
638 str_tldata = dbe_strdup (arglist[0]);
639 proc_tldata (arglist[0], true);
643 if (!str_tabs || override)
644 // the string is processed later, after all .rc files are read
645 str_tabs = dbe_strdup (arglist[0]);
648 if (!str_rtabs || override)
649 // the string is processed later, after all .rc files are read
650 str_rtabs = dbe_strdup (arglist[0]);
655 strbuf = dbe_sprintf (NTXT ("%s:%s"), str_search_path, arglist[0]);
656 free (str_search_path);
657 str_search_path = strbuf;
660 str_search_path = dbe_strdup (arglist[0]);
664 char *err = add_pathmap (pathmaps, arglist[0], arglist[1]);
665 free (err); // XXX error is not reported
669 if (preload_libdirs == NULL)
670 preload_libdirs = dbe_strdup (arglist[0]);
673 if (name_format == Histable::NA)
674 set_name_format (arglist[0]);
677 if (!str_vmode || override)
679 str_vmode = dbe_strdup (arglist[0]);
680 set_view_mode (arglist[0], true);
684 if (!str_en_desc || override)
686 str_en_desc = dbe_strdup (arglist[0]);
687 set_en_desc (arglist[0], true);
691 if (!str_limit || override)
693 str_limit = dbe_strdup (arglist[0]);
694 set_limit (arglist[0], true);
698 if (!str_printmode || override)
699 set_printmode (arglist[0]);
702 if (!str_compare || override)
704 char *s = arglist[0];
706 str_compare = dbe_strdup (s);
709 if (strcasecmp (s, NTXT ("OFF")) == 0
710 || strcmp (s, NTXT ("0")) == 0)
711 set_compare_mode (CMP_DISABLE);
712 else if (strcasecmp (s, NTXT ("ON")) == 0
713 || strcmp (s, NTXT ("1")) == 0)
714 set_compare_mode (CMP_ENABLE);
715 else if (strcasecmp (s, NTXT ("DELTA")) == 0)
716 set_compare_mode (CMP_DELTA);
717 else if (strcasecmp (s, NTXT ("RATIO")) == 0)
718 set_compare_mode (CMP_RATIO);
721 sb.sprintf (GTXT (" .er.rc:%d The argument of 'compare' should be 'on', 'off', 'delta', or 'ratio'"),
723 Emsg *m = new Emsg (CMSG_COMMENT, sb);
724 commentq->append (m);
731 char *ret = dbeSession->indxobj_define (arglist[0], NULL, arglist[1], (nargs >= 3) ? PTXT (arglist[2]) : NULL, (nargs >= 4) ? PTXT (arglist[3]) : NULL);
734 sb.sprintf (GTXT (" %s: line %d `%s %s %s'\n"),
735 ret, line_no, cmd, arglist[0], arglist[1]);
736 Emsg *m = new Emsg (CMSG_COMMENT, sb);
737 commentq->append (m);
742 //XXX: should be conditional on the experiment ARCH, not dbe ARCH
743 case IGNORE_NO_XHWCPROF:
744 // ignore absence of -xhwcprof info for dataspace profiling
745 set_ignore_no_xhwcprof (true);
749 // ignore file system warning in experiments
750 set_ignore_fs_warn (true);
753 // Add the named libraries to the lib_expands array
754 set_libexpand (arglist[0], LIBEX_SHOW, true);
757 // Add the named libraries to the lib_expands array
758 set_libexpand (arglist[0], LIBEX_HIDE, true);
761 // Add the named libraries to the lib_expands array
762 set_libexpand (arglist[0], LIBEX_API, true);
769 // unexpected command in an rc file
772 // if quiet, can remain so no longer
774 Emsg *m = new Emsg (CMSG_COMMENT, GTXT ("Processed system gprofng.rc file for default settings"));
775 commentq->append (m);
777 sb.sprintf (GTXT (" Unrecognized .gprofng.rc command on line %d: `%.64s'"),
779 Emsg *m = new Emsg (CMSG_COMMENT, sb);
780 commentq->append (m);
790 Settings::set_view_mode (char *arg, bool rc)
792 if (!strcasecmp (arg, NTXT ("user")))
793 view_mode = VMODE_USER;
794 else if (!strcasecmp (arg, NTXT ("expert")))
795 view_mode = VMODE_EXPERT;
796 else if (!strcasecmp (arg, NTXT ("machine")))
797 view_mode = VMODE_MACHINE;
804 Settings::set_en_desc (char *arg, bool rc)
806 regex_t *regex_desc = NULL;
808 // cases below should be similar to Coll_Ctrl::set_follow_mode() cases
809 if (!strcasecmp (arg, NTXT ("on")))
811 else if (!strcasecmp (arg, NTXT ("off")))
813 else if (arg[0] == '=' && arg[1] != 0)
815 // user has specified a string matching specification
817 { // compile regex_desc
818 char * str = dbe_sprintf (NTXT ("^%s$"), arg + 1);
819 regex_desc = new regex_t;
820 memset (regex_desc, 0, sizeof (regex_t));
821 ercode = regcomp (regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
826 // syntax error in parsing string
841 en_desc_usr = dbe_strdup (arg);
844 regfree (en_desc_cmp);
847 en_desc_cmp = regex_desc;
851 // See if a descendant matches either the lineage or the executable name
853 Settings::check_en_desc (const char *lineage, const char *targname)
856 if (en_desc_cmp == NULL)
857 return en_desc; // no specification was set, use the binary on/off value
858 if (lineage == NULL) // user doesn't care about specification
859 return en_desc; // use the binary on/off specification
860 if (!regexec (en_desc_cmp, lineage, 0, NULL, 0))
861 rc = true; // this one matches user specification
862 else if (targname == NULL)
863 rc = false; //a NULL name does not match any expression
864 else if (!regexec (en_desc_cmp, targname, 0, NULL, 0))
865 rc = true; // this one matches the executable name
872 Settings::set_limit (char *arg, bool)
874 limit = (int) strtol (arg, (char **) NULL, 10);
879 Settings::set_printmode (char *arg)
882 return dbe_sprintf (GTXT ("The argument to '%s' must be '%s' or '%s' or a single-character"),
883 NTXT ("printmode"), NTXT ("text"), NTXT ("html"));
884 if (strlen (arg) == 1)
886 print_mode = PM_DELIM_SEP_LIST;
887 print_delim = arg[0];
889 else if (!strcasecmp (arg, NTXT ("text")))
890 print_mode = PM_TEXT;
891 else if (!strcasecmp (arg, NTXT ("html")))
892 print_mode = PM_HTML;
894 return dbe_sprintf (GTXT ("The argument to '%s' must be '%s' or '%s' or a single-character"),
895 NTXT ("printmode"), NTXT ("text"), NTXT ("html"));
896 free (str_printmode);
897 str_printmode = dbe_strdup (arg);
902 Settings::proc_compcom (const char *cmd, bool isSrc, bool rc)
904 int ck_compcom_bits, ck_threshold;
905 bool ck_hex_visible = false;
906 bool ck_src_visible = false;
907 bool ck_srcmetric_visible = false;
908 bool got_compcom_bits, got_threshold, got_src_visible, got_srcmetric_visible;
909 bool got_hex_visible, got;
914 char buf[BUFSIZ], *list;
920 got_compcom_bits = got_threshold = got_src_visible = false;
921 got_srcmetric_visible = got_hex_visible = false;
922 snprintf (buf, sizeof (buf), NTXT ("%s"), cmd);
924 while ((mcmd = strtok (list, NTXT (":"))) != NULL)
927 // if "all" or "none"
928 if (!strcasecmp (mcmd, Command::ALL_CMD))
930 got_compcom_bits = true;
931 ck_compcom_bits = CCMV_ALL;
934 else if (!strcasecmp (mcmd, Command::NONE_CMD))
936 got_compcom_bits = true;
941 // Find parameter after '='
942 param = strchr (mcmd, '=');
951 len = (int) strlen (mcmd);
952 for (i = 0; status == CMD_OK && i < comp_size; i++)
953 if (!strncasecmp (mcmd, comp_cmd[i], len))
955 if (got) // Ambiguous comp_com command
956 status = CMD_AMBIGUOUS;
962 if (flag == COMP_THRESHOLD)
965 status = CMD_BAD_ARG;
968 value = (int) strtol (param, ¶m, 10);
969 if (value < 0 || value > 100)
970 status = CMD_OUTRANGE;
973 else if (param != NULL)
974 status = CMD_BAD_ARG;
978 // Not valid comp_com command
980 status = CMD_INVALID;
981 if (status != CMD_OK)
992 cmpline_visible = true;
995 funcline_visible = true;
998 got_threshold = true;
999 ck_threshold = value;
1002 got_src_visible = true;
1003 ck_src_visible = true;
1005 case COMP_SRC_METRIC:
1006 got_srcmetric_visible = true;
1007 ck_srcmetric_visible = true;
1008 got_src_visible = true;
1009 ck_src_visible = true;
1012 got_src_visible = true;
1013 ck_src_visible = false;
1016 got_hex_visible = true;
1017 ck_hex_visible = true;
1020 got_hex_visible = true;
1021 ck_hex_visible = false;
1024 got_compcom_bits = true;
1025 ck_compcom_bits = CCMV_BASIC;
1028 got_compcom_bits = true;
1029 ck_compcom_bits |= flag;
1034 if (got_compcom_bits)
1037 src_compcom = ck_compcom_bits;
1039 dis_compcom = ck_compcom_bits;
1044 threshold_src = ck_threshold;
1046 threshold_dis = ck_threshold;
1048 if (got_src_visible)
1049 src_visible = ck_src_visible;
1050 if (got_srcmetric_visible)
1051 srcmetric_visible = ck_srcmetric_visible;
1052 if (got_hex_visible)
1053 hex_visible = ck_hex_visible;
1057 // Process a threshold setting
1059 Settings::proc_thresh (char *cmd, bool isSrc, bool rc)
1063 value = DEFAULT_SRC_DIS_THRESHOLD; // the default
1065 value = (int) strtol (cmd, &cmd, 10);
1066 if (value < 0 || value > 100)
1069 return CMD_OUTRANGE;
1070 value = DEFAULT_SRC_DIS_THRESHOLD;
1073 threshold_src = value;
1075 threshold_dis = value;
1079 // return any error string from processing visibility settings
1081 Settings::get_compcom_errstr (Cmd_status status, const char *cmd)
1088 sb.append (GTXT ("No commentary classes has been specified."));
1091 sb.append (GTXT ("Ambiguous commentary classes: "));
1094 sb.append (GTXT ("Invalid argument for commentary classes: "));
1097 sb.append (GTXT ("Out of range commentary classes argument: "));
1100 sb.append (GTXT ("Invalid commentary classes: "));
1107 sb.append (GTXT ("\nAvailable commentary classes: "));
1108 for (i = 0; i < comp_size; i++)
1110 sb.append (comp_cmd[i]);
1111 if (i == comp_size - 1)
1112 sb.append (NTXT ("=#\n"));
1114 sb.append (NTXT (":"));
1116 return sb.toString ();
1119 // Process a timeline-mode setting
1121 Settings::proc_tlmode (char *cmd, bool rc)
1123 bool got_tlmode, got_stack_align, got_stack_depth, got;
1124 int ck_tlmode = 0, ck_stack_align = 0, ck_stack_depth = 0;
1127 int cmd_id, value = 0;
1128 TLModeSubcommand cmd_type;
1130 char buf[BUFSIZ], *list;
1133 got_tlmode = got_stack_align = got_stack_depth = false;
1134 snprintf (buf, sizeof (buf), NTXT ("%s"), cmd);
1136 while ((mcmd = strtok (list, NTXT (":"))) != NULL)
1140 // Find parameter after '='
1141 param = strchr (mcmd, '=');
1150 cmd_type = TLCMD_INVALID;
1151 len = (int) strlen (mcmd);
1152 for (i = 0; status == CMD_OK && i < tlmode_size; i++)
1154 if (!strncasecmp (mcmd, tlmode_cmd[i].cmdText, len))
1156 if (got) // Ambiguous timeline mode
1157 status = CMD_AMBIGUOUS;
1161 cmd_type = tlmode_cmd[i].cmdType;
1162 cmd_id = tlmode_cmd[i].cmdId;
1165 if (cmd_type == TLCMD_DEPTH)
1168 status = CMD_BAD_ARG;
1171 value = (int) strtol (param, ¶m, 10);
1172 if (value <= 0 || value > 256)
1173 status = CMD_OUTRANGE;
1176 else if (param != NULL)
1177 status = CMD_BAD_ARG;
1182 // Not valid timeline mode
1184 status = CMD_INVALID;
1185 if (status != CMD_OK)
1195 case TLCMD_ENTITY_MODE:
1200 got_stack_align = true;
1201 ck_stack_align = cmd_id;
1204 got_stack_depth = true;
1205 ck_stack_depth = value;
1215 if (got_stack_align)
1216 stack_align = ck_stack_align;
1217 if (got_stack_depth)
1218 stack_depth = ck_stack_depth;
1222 // Process timeline data specification
1224 Settings::proc_tldata (const char *cmd, bool /* if true, ignore any error */)
1227 tldata = dbe_strdup (cmd); // let GUI parse it
1232 Settings::set_tldata (const char* _tldata_str)
1235 tldata = dbe_strdup (_tldata_str);
1239 Settings::get_tldata ()
1241 return dbe_strdup (tldata);
1245 Settings::set_name_format (char *arg)
1247 char *colon = strchr (arg, ':');
1248 size_t arg_len = (colon) ? (colon - arg) : strlen (arg);
1249 Histable::NameFormat fname_fmt = Histable::NA;
1250 if (!strncasecmp (arg, NTXT ("long"), arg_len))
1251 fname_fmt = Histable::LONG;
1252 else if (!strncasecmp (arg, NTXT ("short"), arg_len))
1253 fname_fmt = Histable::SHORT;
1254 else if (!strncasecmp (arg, NTXT ("mangled"), arg_len))
1255 fname_fmt = Histable::MANGLED;
1259 bool soname_fmt = false;
1260 if (colon && (colon + 1))
1263 if (!strcasecmp (colon, NTXT ("soname")))
1265 else if (!strcasecmp (colon, NTXT ("nosoname")))
1270 name_format = Histable::make_fmt (fname_fmt, soname_fmt);
1275 Settings::buildMasterTabList ()
1277 tab_list = new Vector<DispTab*>;
1280 // Add tabs for all the known reports
1281 tab_list->append (new DispTab (DSP_DEADLOCKS, i, false, DEADLOCK_EVNTS));
1282 tab_list->append (new DispTab (DSP_FUNCTION, i, false, FUNCS));
1283 tab_list->append (new DispTab (DSP_TIMELINE, i, false, TIMELINE));
1284 tab_list->append (new DispTab (DSP_CALLTREE, i, false, CALLTREE));
1285 tab_list->append (new DispTab (DSP_CALLFLAME, i, false, CALLFLAME));
1286 tab_list->append (new DispTab (DSP_DUALSOURCE, i, false, DUALSOURCE));
1287 tab_list->append (new DispTab (DSP_SOURCE_DISASM, i, false, SOURCEDISAM));
1288 tab_list->append (new DispTab (DSP_SOURCE, i, false, SOURCE));
1289 tab_list->append (new DispTab (DSP_LINE, i, false, HOTLINES));
1290 tab_list->append (new DispTab (DSP_DISASM, i, false, DISASM));
1291 tab_list->append (new DispTab (DSP_PC, i, false, HOTPCS));
1292 tab_list->append (new DispTab (DSP_LEAKLIST, i, false, LEAKS));
1293 tab_list->append (new DispTab (DSP_IOACTIVITY, i, false, IOACTIVITY));
1294 tab_list->append (new DispTab (DSP_HEAPCALLSTACK, i, false, HEAP));
1295 tab_list->append (new DispTab (DSP_IFREQ, i, false, IFREQ));
1296 tab_list->append (new DispTab (DSP_CALLER, i, false, GPROF));
1297 tab_list->append (new DispTab (DSP_STATIS, i, false, STATISTICS));
1298 tab_list->append (new DispTab (DSP_EXP, i, false, HEADER));
1301 // Update tablist based on data availability
1303 Settings::updateTabAvailability ()
1308 Vec_loop (DispTab*, tab_list, index, dsptab)
1310 if (dsptab->type == DSP_DATAOBJ)
1311 dsptab->setAvailability (dbeSession->is_datamode_available ());
1312 else if (dsptab->type == DSP_DLAYOUT)
1313 dsptab->setAvailability (dbeSession->is_datamode_available ());
1314 else if (dsptab->type == DSP_LEAKLIST)
1315 dsptab->setAvailability (false);
1316 else if (dsptab->type == DSP_IOACTIVITY)
1317 dsptab->setAvailability (dbeSession->is_iodata_available ());
1318 else if (dsptab->type == DSP_HEAPCALLSTACK)
1319 dsptab->setAvailability (dbeSession->is_heapdata_available ());
1320 else if (dsptab->type == DSP_TIMELINE)
1321 dsptab->setAvailability (dbeSession->is_timeline_available ());
1322 else if (dsptab->type == DSP_IFREQ)
1323 dsptab->setAvailability (dbeSession->is_ifreq_available ());
1324 else if (dsptab->type == DSP_RACES)
1325 dsptab->setAvailability (dbeSession->is_racelist_available ());
1326 else if (dsptab->type == DSP_DEADLOCKS)
1327 dsptab->setAvailability (dbeSession->is_deadlocklist_available ());
1328 else if (dsptab->type == DSP_DUALSOURCE)
1329 dsptab->setAvailability (dbeSession->is_racelist_available ()
1330 || dbeSession->is_deadlocklist_available ());
1334 // Process a tab setting
1336 Settings::proc_tabs (bool _rdtMode)
1338 int arg_cnt, cparam;
1343 if (tabs_processed == true)
1345 tabs_processed = true;
1346 if (_rdtMode == true)
1348 if (str_rtabs == NULL)
1349 str_rtabs = strdup ("header");
1354 if (str_tabs == NULL)
1355 str_tabs = strdup ("header");
1358 if (strcmp (cmd, NTXT ("none")) == 0)
1360 Vector <char *> *tokens = split_str (cmd, ':');
1361 for (long j = 0, sz = VecSize (tokens); j < sz; j++)
1363 char *tabname = tokens->get (j);
1364 // search for this tab command token
1365 CmdType c = Command::get_command (tabname, arg_cnt, cparam);
1368 // set the bit for this subtype
1369 indx_tab_state->store (cparam, true);
1370 indx_tab_order->store (cparam, count++);
1374 // search for this tab type in the regular tabs
1375 Vec_loop (DispTab*, tab_list, index, dsptab)
1377 if (dsptab->cmdtoken == c)
1379 dsptab->visible = true;
1380 dsptab->order = count++;
1392 Settings::set_MemTabState (Vector<bool>*selected)
1394 if (selected->size () == 0)
1396 for (int j = 0; j < mem_tab_state->size (); j++)
1397 mem_tab_state->store (j, selected->fetch (j));
1400 // define a new memory object type
1403 Settings::mobj_define (MemObjType_t */* mobj */, bool state)
1405 if (mem_tab_state->size () == 0)
1407 mem_tab_state->append (state);
1408 mem_tab_order->append (-1);
1412 Settings::set_IndxTabState (Vector<bool>*selected)
1414 for (int j = 0; j < selected->size (); j++)
1415 indx_tab_state->store (j, selected->fetch (j));
1418 // define a new index object type
1420 Settings::indxobj_define (int type, bool state)
1422 indx_tab_state->store (type, state);
1423 indx_tab_order->store (type, -1);
1427 Settings::set_pathmaps (Vector<pathmap_t*> *newPathMap)
1431 pathmaps->destroy ();
1434 pathmaps = newPathMap;
1438 get_canonical_name (const char *fname)
1440 char *nm = dbe_strdup (fname);
1441 for (size_t len = strlen (nm); (len > 0) && (nm[len - 1] == '/'); len--)
1447 Settings::add_pathmap (Vector<pathmap_t*> *v, const char *from, const char *to)
1450 if (from == NULL || to == NULL)
1451 return dbe_strdup (GTXT ("Pathmap can have neither from nor to as NULL\n"));
1452 if (strcmp (from, to) == 0)
1453 return dbe_strdup (GTXT ("Pathmap from must differ from to\n"));
1454 char *old_prefix = get_canonical_name (from);
1455 char *new_prefix = get_canonical_name (to);
1457 // Check the pathmap list
1458 for (int i = 0, sz = v->size (); i < sz; i++)
1460 pathmap_t *pmp = v->get (i);
1461 if ((strcmp (pmp->old_prefix, old_prefix) == 0) &&(strcmp (pmp->new_prefix, new_prefix) == 0))
1463 char *s = dbe_sprintf (GTXT ("Pathmap from `%s' to `%s' already exists\n"), old_prefix, new_prefix);
1469 // construct a map for this pair
1470 pathmap_t *thismap = new pathmap_t;
1471 thismap->old_prefix = old_prefix;
1472 thismap->new_prefix = new_prefix;
1473 v->append (thismap);
1477 // Set all shared object expands back to .rc file defaults,
1478 // as stored in the DbeSession Settings
1480 Settings::set_libdefaults ()
1482 // See if this is unchanged
1483 if (is_loexpand_default == true)
1484 return false; // no change
1486 // replicate the DbeSession's lo_expand vector and default settings
1487 lo_expand_t *this_lo_ex;
1488 lo_expand_t *new_lo_ex;
1490 lo_expand_default = dbeSession->get_settings ()->lo_expand_default;
1491 lo_expands = new Vector<lo_expand_t*>;
1492 Vec_loop (lo_expand_t*, dbeSession->get_settings ()->lo_expands, index, this_lo_ex)
1494 new_lo_ex = new lo_expand_t;
1495 new_lo_ex->libname = dbe_strdup (this_lo_ex->libname);
1496 new_lo_ex->expand = this_lo_ex->expand;
1497 lo_expands->append (new_lo_ex);
1499 is_loexpand_default = true;
1504 Settings::set_libexpand (char *cov, enum LibExpand expand, bool rc)
1508 bool change = false;
1509 if (cov == NULL || !strcasecmp (cov, Command::ALL_CMD))
1510 { // set all libraries
1512 if (lo_expand_default != expand)
1514 lo_expand_default = expand;
1516 is_loexpand_default = false;
1519 // and force any explicit settings to match, too
1520 Vec_loop (lo_expand_t*, lo_expands, index, loe)
1522 if (loe->expand != expand)
1524 loe->expand = expand;
1526 is_loexpand_default = false;
1532 { // parsing coverage
1533 Vector <char *> *tokens = split_str (cov, ',');
1534 for (long j = 0, sz = VecSize (tokens); j < sz; j++)
1536 char *lo_name = tokens->get (j);
1537 char *newname = get_basename (lo_name);
1539 Vec_loop (lo_expand_t*, lo_expands, index, loe)
1541 if (strcmp (loe->libname, newname) == 0)
1543 if (loe->expand != expand)
1547 loe->expand = expand;
1549 is_loexpand_default = false;
1559 // construct a map for this pair
1560 lo_expand_t *thisloe;
1561 thisloe = new lo_expand_t;
1562 thisloe->libname = dbe_strdup (newname);
1563 thisloe->expand = expand;
1565 is_loexpand_default = false;
1567 // add it to the vector
1568 lo_expands->append (thisloe);
1578 Settings::get_lo_setting (char *name)
1582 char *lo_name = get_basename (name);
1583 Vec_loop (lo_expand_t*, lo_expands, index, loe)
1585 if (strcmp (loe->libname, lo_name) == 0)
1588 return lo_expand_default;