1 /* Copyright (C) 2021-2023 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;
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
;