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 rc_path
= dbe_sprintf (NTXT ("%s/../etc/gprofng.rc"), app
->get_run_dir ());
411 if (access (rc_path
, R_OK
| F_OK
) != 0)
414 sb
.sprintf (GTXT ("Warning: Default gprofng.rc file (%s) missing; configuration error "), rc_path
);
415 Emsg
*m
= new Emsg (CMSG_COMMENT
, sb
);
416 app
->get_comments_queue ()->append (m
);
419 set_rc (rc_path
, false, app
->get_comments_queue (), override
);
421 is_loexpand_default
= true;
422 if (str_printmode
== NULL
)
424 // only if there's none set
425 print_mode
= PM_TEXT
;
426 str_printmode
= dbe_strdup (NTXT ("text"));
431 // Handle various settings from reading the name .rc file
432 // This function is called for each .rc file read, and, for
433 // some settings, it accumulates the strings from the files.
434 // For others, it accepts the first appearance for a setting in a
435 // .rc file, and ignores subsequent appearances from other files.
436 // Error messages are appended to the Emsgqueue specified by the caller
441 Settings::set_rc (const char *path
, bool msg
, Emsgqueue
*commentq
,
442 bool override
, bool ipc_or_rdt_mode
)
445 int arg_count
, cparam
;
446 char *cmd
, *end_cmd
, *strbuf
;
447 char *arglist
[MAXARGS
];
450 FILE *fptr
= fopen (path
, NTXT ("r"));
456 sb
.sprintf (GTXT ("Processed %s for default settings"), path
);
457 Emsg
*m
= new Emsg (CMSG_COMMENT
, sb
);
458 commentq
->append (m
);
464 char *script
= read_line (fptr
);
468 strtok (script
, NTXT ("\n"));
470 // extract the command
471 cmd
= strtok (script
, NTXT (" \t"));
472 if (cmd
== NULL
|| *cmd
== '#' || *cmd
== '\n')
477 char *remainder
= strtok (NULL
, NTXT ("\n"));
478 // now extract the arguments
482 if (nargs
>= MAXARGS
)
486 msg
= true; // suppress repeats of header
487 Emsg
*m
= new Emsg (CMSG_COMMENT
, GTXT ("Processed system gprofng.rc file for default settings"));
488 commentq
->append (m
);
490 sb
.sprintf (GTXT ("Warning: more than %d arguments to %s command, line %d\n"),
491 MAXARGS
, cmd
, line_no
);
492 Emsg
*m
= new Emsg (CMSG_COMMENT
, sb
);
493 commentq
->append (m
);
497 char *nextarg
= strtok (remainder
, NTXT ("\n"));
498 if (nextarg
== NULL
|| *nextarg
== '#')
500 arglist
[nargs
++] = parse_qstring (nextarg
, &end_cmd
);
502 if (remainder
== NULL
)
504 // skip any blanks or tabs to get to next argument
505 while (*remainder
== ' ' || *remainder
== '\t')
508 cmd_type
= Command::get_command (cmd
, arg_count
, cparam
);
509 // check for extra arguments
510 if ((cmd_type
!= UNKNOWN_CMD
&& cmd_type
!= INDXOBJDEF
) && (nargs
> arg_count
))
514 msg
= true; // suppress repeats of header
515 Emsg
*m
= new Emsg (CMSG_COMMENT
, GTXT ("Processed system gprofng.rc file for default settings"));
516 commentq
->append (m
);
518 sb
.sprintf (GTXT ("Warning: extra arguments to %s command, line %d\n"), cmd
, line_no
);
519 Emsg
*m
= new Emsg (CMSG_COMMENT
, sb
);
520 commentq
->append (m
);
522 if (nargs
< arg_count
)
526 msg
= true; // suppress repeats of header
527 Emsg
*m
= new Emsg (CMSG_COMMENT
, GTXT ("Processed system gprofng.rc file for default settings"));
528 commentq
->append (m
);
530 sb
.sprintf (GTXT ("Error: missing arguments to %s command, line %d\n"),
532 Emsg
*m
= new Emsg (CMSG_COMMENT
, sb
);
533 commentq
->append (m
);
535 // ignore this command
539 if (ipc_or_rdt_mode
&& (cmd_type
!= ADDPATH
) && (cmd_type
!= PATHMAP
))
547 if (!str_scompcom
|| override
)
549 str_scompcom
= dbe_strdup (arglist
[0]);
550 proc_compcom (arglist
[0], true, true);
554 if (!str_sthresh
|| override
)
556 str_sthresh
= dbe_strdup (arglist
[0]);
557 proc_thresh (arglist
[0], true, true);
562 if (!str_dcompcom
|| override
)
564 str_dcompcom
= dbe_strdup (arglist
[0]);
565 proc_compcom (arglist
[0], false, true);
569 // process as if it were for both source and disassembly
570 // note that if it is set, subsequent SCOMPCOM and DCOMPCOM
572 if (!str_scompcom
|| override
)
574 str_scompcom
= dbe_strdup (arglist
[0]);
575 proc_compcom (arglist
[0], true, true);
577 if (!str_dcompcom
|| override
)
579 str_dcompcom
= dbe_strdup (arglist
[0]);
580 proc_compcom (arglist
[0], false, true);
584 if (!str_dthresh
|| override
)
586 str_dthresh
= dbe_strdup (arglist
[0]);
587 proc_thresh (arglist
[0], false, true);
591 // append new settings to old, if necessary
594 char *name
= strstr (str_dmetrics
, ":name");
596 strbuf
= dbe_sprintf ("%s:%s", str_dmetrics
, arglist
[0]);
599 char * next
= strstr (name
+ 1, ":");
603 strbuf
= dbe_sprintf ("%s:%s:name", str_dmetrics
, arglist
[0]);
606 strbuf
= dbe_sprintf ("%s:%s", str_dmetrics
, arglist
[0]);
609 str_dmetrics
= strbuf
;
612 str_dmetrics
= dbe_strdup (arglist
[0]);
615 // append new settings to old, if necessary
618 strbuf
= dbe_sprintf (NTXT ("%s:%s"), str_dsort
, arglist
[0]);
623 str_dsort
= dbe_strdup (arglist
[0]);
626 if (!str_tlmode
|| override
)
628 str_tlmode
= dbe_strdup (arglist
[0]);
629 proc_tlmode (arglist
[0], true);
633 if (!str_tldata
|| override
)
635 str_tldata
= dbe_strdup (arglist
[0]);
636 proc_tldata (arglist
[0], true);
640 if (!str_tabs
|| override
)
641 // the string is processed later, after all .rc files are read
642 str_tabs
= dbe_strdup (arglist
[0]);
645 if (!str_rtabs
|| override
)
646 // the string is processed later, after all .rc files are read
647 str_rtabs
= dbe_strdup (arglist
[0]);
652 strbuf
= dbe_sprintf (NTXT ("%s:%s"), str_search_path
, arglist
[0]);
653 free (str_search_path
);
654 str_search_path
= strbuf
;
657 str_search_path
= dbe_strdup (arglist
[0]);
661 char *err
= add_pathmap (pathmaps
, arglist
[0], arglist
[1]);
662 free (err
); // XXX error is not reported
666 if (preload_libdirs
== NULL
)
667 preload_libdirs
= dbe_strdup (arglist
[0]);
670 if (name_format
== Histable::NA
)
671 set_name_format (arglist
[0]);
674 if (!str_vmode
|| override
)
676 str_vmode
= dbe_strdup (arglist
[0]);
677 set_view_mode (arglist
[0], true);
681 if (!str_en_desc
|| override
)
683 str_en_desc
= dbe_strdup (arglist
[0]);
684 set_en_desc (arglist
[0], true);
688 if (!str_limit
|| override
)
690 str_limit
= dbe_strdup (arglist
[0]);
691 set_limit (arglist
[0], true);
695 if (!str_printmode
|| override
)
696 set_printmode (arglist
[0]);
699 if (!str_compare
|| override
)
701 char *s
= arglist
[0];
703 str_compare
= dbe_strdup (s
);
706 if (strcasecmp (s
, NTXT ("OFF")) == 0
707 || strcmp (s
, NTXT ("0")) == 0)
708 set_compare_mode (CMP_DISABLE
);
709 else if (strcasecmp (s
, NTXT ("ON")) == 0
710 || strcmp (s
, NTXT ("1")) == 0)
711 set_compare_mode (CMP_ENABLE
);
712 else if (strcasecmp (s
, NTXT ("DELTA")) == 0)
713 set_compare_mode (CMP_DELTA
);
714 else if (strcasecmp (s
, NTXT ("RATIO")) == 0)
715 set_compare_mode (CMP_RATIO
);
718 sb
.sprintf (GTXT (" .er.rc:%d The argument of 'compare' should be 'on', 'off', 'delta', or 'ratio'"),
720 Emsg
*m
= new Emsg (CMSG_COMMENT
, sb
);
721 commentq
->append (m
);
728 char *ret
= dbeSession
->indxobj_define (arglist
[0], NULL
, arglist
[1], (nargs
>= 3) ? PTXT (arglist
[2]) : NULL
, (nargs
>= 4) ? PTXT (arglist
[3]) : NULL
);
731 sb
.sprintf (GTXT (" %s: line %d `%s %s %s'\n"),
732 ret
, line_no
, cmd
, arglist
[0], arglist
[1]);
733 Emsg
*m
= new Emsg (CMSG_COMMENT
, sb
);
734 commentq
->append (m
);
739 //XXX: should be conditional on the experiment ARCH, not dbe ARCH
740 case IGNORE_NO_XHWCPROF
:
741 // ignore absence of -xhwcprof info for dataspace profiling
742 set_ignore_no_xhwcprof (true);
746 // ignore file system warning in experiments
747 set_ignore_fs_warn (true);
750 // Add the named libraries to the lib_expands array
751 set_libexpand (arglist
[0], LIBEX_SHOW
, true);
754 // Add the named libraries to the lib_expands array
755 set_libexpand (arglist
[0], LIBEX_HIDE
, true);
758 // Add the named libraries to the lib_expands array
759 set_libexpand (arglist
[0], LIBEX_API
, true);
766 // unexpected command in an rc file
769 // if quiet, can remain so no longer
771 Emsg
*m
= new Emsg (CMSG_COMMENT
, GTXT ("Processed system gprofng.rc file for default settings"));
772 commentq
->append (m
);
774 sb
.sprintf (GTXT (" Unrecognized .gprofng.rc command on line %d: `%.64s'"),
776 Emsg
*m
= new Emsg (CMSG_COMMENT
, sb
);
777 commentq
->append (m
);
787 Settings::set_view_mode (char *arg
, bool rc
)
789 if (!strcasecmp (arg
, NTXT ("user")))
790 view_mode
= VMODE_USER
;
791 else if (!strcasecmp (arg
, NTXT ("expert")))
792 view_mode
= VMODE_EXPERT
;
793 else if (!strcasecmp (arg
, NTXT ("machine")))
794 view_mode
= VMODE_MACHINE
;
801 Settings::set_en_desc (char *arg
, bool rc
)
803 regex_t
*regex_desc
= NULL
;
805 // cases below should be similar to Coll_Ctrl::set_follow_mode() cases
806 if (!strcasecmp (arg
, NTXT ("on")))
808 else if (!strcasecmp (arg
, NTXT ("off")))
810 else if (arg
[0] == '=' && arg
[1] != 0)
812 // user has specified a string matching specification
814 { // compile regex_desc
815 char * str
= dbe_sprintf (NTXT ("^%s$"), arg
+ 1);
816 regex_desc
= new regex_t
;
817 memset (regex_desc
, 0, sizeof (regex_t
));
818 ercode
= regcomp (regex_desc
, str
, REG_EXTENDED
| REG_NOSUB
| REG_NEWLINE
);
823 // syntax error in parsing string
838 en_desc_usr
= dbe_strdup (arg
);
841 regfree (en_desc_cmp
);
844 en_desc_cmp
= regex_desc
;
848 // See if a descendant matches either the lineage or the executable name
850 Settings::check_en_desc (const char *lineage
, const char *targname
)
853 if (en_desc_cmp
== NULL
)
854 return en_desc
; // no specification was set, use the binary on/off value
855 if (lineage
== NULL
) // user doesn't care about specification
856 return en_desc
; // use the binary on/off specification
857 if (!regexec (en_desc_cmp
, lineage
, 0, NULL
, 0))
858 rc
= true; // this one matches user specification
859 else if (targname
== NULL
)
860 rc
= false; //a NULL name does not match any expression
861 else if (!regexec (en_desc_cmp
, targname
, 0, NULL
, 0))
862 rc
= true; // this one matches the executable name
869 Settings::set_limit (char *arg
, bool)
871 limit
= (int) strtol (arg
, (char **) NULL
, 10);
876 Settings::set_printmode (char *arg
)
879 return dbe_sprintf (GTXT ("The argument to '%s' must be '%s' or '%s' or a single-character"),
880 NTXT ("printmode"), NTXT ("text"), NTXT ("html"));
881 if (strlen (arg
) == 1)
883 print_mode
= PM_DELIM_SEP_LIST
;
884 print_delim
= arg
[0];
886 else if (!strcasecmp (arg
, NTXT ("text")))
887 print_mode
= PM_TEXT
;
888 else if (!strcasecmp (arg
, NTXT ("html")))
889 print_mode
= PM_HTML
;
891 return dbe_sprintf (GTXT ("The argument to '%s' must be '%s' or '%s' or a single-character"),
892 NTXT ("printmode"), NTXT ("text"), NTXT ("html"));
893 free (str_printmode
);
894 str_printmode
= dbe_strdup (arg
);
899 Settings::proc_compcom (const char *cmd
, bool isSrc
, bool rc
)
901 int ck_compcom_bits
, ck_threshold
;
902 bool ck_hex_visible
= false;
903 bool ck_src_visible
= false;
904 bool ck_srcmetric_visible
= false;
905 bool got_compcom_bits
, got_threshold
, got_src_visible
, got_srcmetric_visible
;
906 bool got_hex_visible
, got
;
911 char buf
[BUFSIZ
], *list
;
917 got_compcom_bits
= got_threshold
= got_src_visible
= false;
918 got_srcmetric_visible
= got_hex_visible
= false;
919 snprintf (buf
, sizeof (buf
), NTXT ("%s"), cmd
);
921 while ((mcmd
= strtok (list
, NTXT (":"))) != NULL
)
924 // if "all" or "none"
925 if (!strcasecmp (mcmd
, Command::ALL_CMD
))
927 got_compcom_bits
= true;
928 ck_compcom_bits
= CCMV_ALL
;
931 else if (!strcasecmp (mcmd
, Command::NONE_CMD
))
933 got_compcom_bits
= true;
938 // Find parameter after '='
939 param
= strchr (mcmd
, '=');
948 len
= (int) strlen (mcmd
);
949 for (i
= 0; status
== CMD_OK
&& i
< comp_size
; i
++)
950 if (!strncasecmp (mcmd
, comp_cmd
[i
], len
))
952 if (got
) // Ambiguous comp_com command
953 status
= CMD_AMBIGUOUS
;
959 if (flag
== COMP_THRESHOLD
)
962 status
= CMD_BAD_ARG
;
965 value
= (int) strtol (param
, ¶m
, 10);
966 if (value
< 0 || value
> 100)
967 status
= CMD_OUTRANGE
;
970 else if (param
!= NULL
)
971 status
= CMD_BAD_ARG
;
975 // Not valid comp_com command
977 status
= CMD_INVALID
;
978 if (status
!= CMD_OK
)
989 cmpline_visible
= true;
992 funcline_visible
= true;
995 got_threshold
= true;
996 ck_threshold
= value
;
999 got_src_visible
= true;
1000 ck_src_visible
= true;
1002 case COMP_SRC_METRIC
:
1003 got_srcmetric_visible
= true;
1004 ck_srcmetric_visible
= true;
1005 got_src_visible
= true;
1006 ck_src_visible
= true;
1009 got_src_visible
= true;
1010 ck_src_visible
= false;
1013 got_hex_visible
= true;
1014 ck_hex_visible
= true;
1017 got_hex_visible
= true;
1018 ck_hex_visible
= false;
1021 got_compcom_bits
= true;
1022 ck_compcom_bits
= CCMV_BASIC
;
1025 got_compcom_bits
= true;
1026 ck_compcom_bits
|= flag
;
1031 if (got_compcom_bits
)
1034 src_compcom
= ck_compcom_bits
;
1036 dis_compcom
= ck_compcom_bits
;
1041 threshold_src
= ck_threshold
;
1043 threshold_dis
= ck_threshold
;
1045 if (got_src_visible
)
1046 src_visible
= ck_src_visible
;
1047 if (got_srcmetric_visible
)
1048 srcmetric_visible
= ck_srcmetric_visible
;
1049 if (got_hex_visible
)
1050 hex_visible
= ck_hex_visible
;
1054 // Process a threshold setting
1056 Settings::proc_thresh (char *cmd
, bool isSrc
, bool rc
)
1060 value
= DEFAULT_SRC_DIS_THRESHOLD
; // the default
1062 value
= (int) strtol (cmd
, &cmd
, 10);
1063 if (value
< 0 || value
> 100)
1066 return CMD_OUTRANGE
;
1067 value
= DEFAULT_SRC_DIS_THRESHOLD
;
1070 threshold_src
= value
;
1072 threshold_dis
= value
;
1076 // return any error string from processing visibility settings
1078 Settings::get_compcom_errstr (Cmd_status status
, const char *cmd
)
1085 sb
.append (GTXT ("No commentary classes has been specified."));
1088 sb
.append (GTXT ("Ambiguous commentary classes: "));
1091 sb
.append (GTXT ("Invalid argument for commentary classes: "));
1094 sb
.append (GTXT ("Out of range commentary classes argument: "));
1097 sb
.append (GTXT ("Invalid commentary classes: "));
1104 sb
.append (GTXT ("\nAvailable commentary classes: "));
1105 for (i
= 0; i
< comp_size
; i
++)
1107 sb
.append (comp_cmd
[i
]);
1108 if (i
== comp_size
- 1)
1109 sb
.append (NTXT ("=#\n"));
1111 sb
.append (NTXT (":"));
1113 return sb
.toString ();
1116 // Process a timeline-mode setting
1118 Settings::proc_tlmode (char *cmd
, bool rc
)
1120 bool got_tlmode
, got_stack_align
, got_stack_depth
, got
;
1121 int ck_tlmode
= 0, ck_stack_align
= 0, ck_stack_depth
= 0;
1124 int cmd_id
, value
= 0;
1125 TLModeSubcommand cmd_type
;
1127 char buf
[BUFSIZ
], *list
;
1130 got_tlmode
= got_stack_align
= got_stack_depth
= false;
1131 snprintf (buf
, sizeof (buf
), NTXT ("%s"), cmd
);
1133 while ((mcmd
= strtok (list
, NTXT (":"))) != NULL
)
1137 // Find parameter after '='
1138 param
= strchr (mcmd
, '=');
1147 cmd_type
= TLCMD_INVALID
;
1148 len
= (int) strlen (mcmd
);
1149 for (i
= 0; status
== CMD_OK
&& i
< tlmode_size
; i
++)
1151 if (!strncasecmp (mcmd
, tlmode_cmd
[i
].cmdText
, len
))
1153 if (got
) // Ambiguous timeline mode
1154 status
= CMD_AMBIGUOUS
;
1158 cmd_type
= tlmode_cmd
[i
].cmdType
;
1159 cmd_id
= tlmode_cmd
[i
].cmdId
;
1162 if (cmd_type
== TLCMD_DEPTH
)
1165 status
= CMD_BAD_ARG
;
1168 value
= (int) strtol (param
, ¶m
, 10);
1169 if (value
<= 0 || value
> 256)
1170 status
= CMD_OUTRANGE
;
1173 else if (param
!= NULL
)
1174 status
= CMD_BAD_ARG
;
1179 // Not valid timeline mode
1181 status
= CMD_INVALID
;
1182 if (status
!= CMD_OK
)
1192 case TLCMD_ENTITY_MODE
:
1197 got_stack_align
= true;
1198 ck_stack_align
= cmd_id
;
1201 got_stack_depth
= true;
1202 ck_stack_depth
= value
;
1212 if (got_stack_align
)
1213 stack_align
= ck_stack_align
;
1214 if (got_stack_depth
)
1215 stack_depth
= ck_stack_depth
;
1219 // Process timeline data specification
1221 Settings::proc_tldata (const char *cmd
, bool /* if true, ignore any error */)
1224 tldata
= dbe_strdup (cmd
); // let GUI parse it
1229 Settings::set_tldata (const char* _tldata_str
)
1232 tldata
= dbe_strdup (_tldata_str
);
1236 Settings::get_tldata ()
1238 return dbe_strdup (tldata
);
1242 Settings::set_name_format (char *arg
)
1244 char *colon
= strchr (arg
, ':');
1245 size_t arg_len
= (colon
) ? (colon
- arg
) : strlen (arg
);
1246 Histable::NameFormat fname_fmt
= Histable::NA
;
1247 if (!strncasecmp (arg
, NTXT ("long"), arg_len
))
1248 fname_fmt
= Histable::LONG
;
1249 else if (!strncasecmp (arg
, NTXT ("short"), arg_len
))
1250 fname_fmt
= Histable::SHORT
;
1251 else if (!strncasecmp (arg
, NTXT ("mangled"), arg_len
))
1252 fname_fmt
= Histable::MANGLED
;
1256 bool soname_fmt
= false;
1257 if (colon
&& (colon
+ 1))
1260 if (!strcasecmp (colon
, NTXT ("soname")))
1262 else if (!strcasecmp (colon
, NTXT ("nosoname")))
1267 name_format
= Histable::make_fmt (fname_fmt
, soname_fmt
);
1272 Settings::buildMasterTabList ()
1274 tab_list
= new Vector
<DispTab
*>;
1277 // Add tabs for all the known reports
1278 tab_list
->append (new DispTab (DSP_DEADLOCKS
, i
, false, DEADLOCK_EVNTS
));
1279 tab_list
->append (new DispTab (DSP_FUNCTION
, i
, false, FUNCS
));
1280 tab_list
->append (new DispTab (DSP_TIMELINE
, i
, false, TIMELINE
));
1281 tab_list
->append (new DispTab (DSP_CALLTREE
, i
, false, CALLTREE
));
1282 tab_list
->append (new DispTab (DSP_CALLFLAME
, i
, false, CALLFLAME
));
1283 tab_list
->append (new DispTab (DSP_DUALSOURCE
, i
, false, DUALSOURCE
));
1284 tab_list
->append (new DispTab (DSP_SOURCE_DISASM
, i
, false, SOURCEDISAM
));
1285 tab_list
->append (new DispTab (DSP_SOURCE
, i
, false, SOURCE
));
1286 tab_list
->append (new DispTab (DSP_LINE
, i
, false, HOTLINES
));
1287 tab_list
->append (new DispTab (DSP_DISASM
, i
, false, DISASM
));
1288 tab_list
->append (new DispTab (DSP_PC
, i
, false, HOTPCS
));
1289 tab_list
->append (new DispTab (DSP_LEAKLIST
, i
, false, LEAKS
));
1290 tab_list
->append (new DispTab (DSP_IOACTIVITY
, i
, false, IOACTIVITY
));
1291 tab_list
->append (new DispTab (DSP_HEAPCALLSTACK
, i
, false, HEAP
));
1292 tab_list
->append (new DispTab (DSP_IFREQ
, i
, false, IFREQ
));
1293 tab_list
->append (new DispTab (DSP_CALLER
, i
, false, GPROF
));
1294 tab_list
->append (new DispTab (DSP_STATIS
, i
, false, STATISTICS
));
1295 tab_list
->append (new DispTab (DSP_EXP
, i
, false, HEADER
));
1298 // Update tablist based on data availability
1300 Settings::updateTabAvailability ()
1305 Vec_loop (DispTab
*, tab_list
, index
, dsptab
)
1307 if (dsptab
->type
== DSP_DATAOBJ
)
1308 dsptab
->setAvailability (dbeSession
->is_datamode_available ());
1309 else if (dsptab
->type
== DSP_DLAYOUT
)
1310 dsptab
->setAvailability (dbeSession
->is_datamode_available ());
1311 else if (dsptab
->type
== DSP_LEAKLIST
)
1312 dsptab
->setAvailability (false);
1313 else if (dsptab
->type
== DSP_IOACTIVITY
)
1314 dsptab
->setAvailability (dbeSession
->is_iodata_available ());
1315 else if (dsptab
->type
== DSP_HEAPCALLSTACK
)
1316 dsptab
->setAvailability (dbeSession
->is_heapdata_available ());
1317 else if (dsptab
->type
== DSP_TIMELINE
)
1318 dsptab
->setAvailability (dbeSession
->is_timeline_available ());
1319 else if (dsptab
->type
== DSP_IFREQ
)
1320 dsptab
->setAvailability (dbeSession
->is_ifreq_available ());
1321 else if (dsptab
->type
== DSP_RACES
)
1322 dsptab
->setAvailability (dbeSession
->is_racelist_available ());
1323 else if (dsptab
->type
== DSP_DEADLOCKS
)
1324 dsptab
->setAvailability (dbeSession
->is_deadlocklist_available ());
1325 else if (dsptab
->type
== DSP_DUALSOURCE
)
1326 dsptab
->setAvailability (dbeSession
->is_racelist_available ()
1327 || dbeSession
->is_deadlocklist_available ());
1331 // Process a tab setting
1333 Settings::proc_tabs (bool _rdtMode
)
1335 int arg_cnt
, cparam
;
1340 if (tabs_processed
== true)
1342 tabs_processed
= true;
1343 if (_rdtMode
== true)
1345 if (str_rtabs
== NULL
)
1346 str_rtabs
= strdup ("header");
1351 if (str_tabs
== NULL
)
1352 str_tabs
= strdup ("header");
1355 if (strcmp (cmd
, NTXT ("none")) == 0)
1357 Vector
<char *> *tokens
= split_str (cmd
, ':');
1358 for (long j
= 0, sz
= VecSize (tokens
); j
< sz
; j
++)
1360 char *tabname
= tokens
->get (j
);
1361 // search for this tab command token
1362 CmdType c
= Command::get_command (tabname
, arg_cnt
, cparam
);
1365 // set the bit for this subtype
1366 indx_tab_state
->store (cparam
, true);
1367 indx_tab_order
->store (cparam
, count
++);
1371 // search for this tab type in the regular tabs
1372 Vec_loop (DispTab
*, tab_list
, index
, dsptab
)
1374 if (dsptab
->cmdtoken
== c
)
1376 dsptab
->visible
= true;
1377 dsptab
->order
= count
++;
1389 Settings::set_MemTabState (Vector
<bool>*selected
)
1391 if (selected
->size () == 0)
1393 for (int j
= 0; j
< mem_tab_state
->size (); j
++)
1394 mem_tab_state
->store (j
, selected
->fetch (j
));
1397 // define a new memory object type
1400 Settings::mobj_define (MemObjType_t */
* mobj */
, bool state
)
1402 if (mem_tab_state
->size () == 0)
1404 mem_tab_state
->append (state
);
1405 mem_tab_order
->append (-1);
1409 Settings::set_IndxTabState (Vector
<bool>*selected
)
1411 for (int j
= 0; j
< selected
->size (); j
++)
1412 indx_tab_state
->store (j
, selected
->fetch (j
));
1415 // define a new index object type
1417 Settings::indxobj_define (int type
, bool state
)
1419 indx_tab_state
->store (type
, state
);
1420 indx_tab_order
->store (type
, -1);
1424 Settings::set_pathmaps (Vector
<pathmap_t
*> *newPathMap
)
1428 pathmaps
->destroy ();
1431 pathmaps
= newPathMap
;
1435 get_canonical_name (const char *fname
)
1437 char *nm
= dbe_strdup (fname
);
1438 for (size_t len
= strlen (nm
); (len
> 0) && (nm
[len
- 1] == '/'); len
--)
1444 Settings::add_pathmap (Vector
<pathmap_t
*> *v
, const char *from
, const char *to
)
1447 if (from
== NULL
|| to
== NULL
)
1448 return dbe_strdup (GTXT ("Pathmap can have neither from nor to as NULL\n"));
1449 if (strcmp (from
, to
) == 0)
1450 return dbe_strdup (GTXT ("Pathmap from must differ from to\n"));
1451 char *old_prefix
= get_canonical_name (from
);
1452 char *new_prefix
= get_canonical_name (to
);
1454 // Check the pathmap list
1455 for (int i
= 0, sz
= v
->size (); i
< sz
; i
++)
1457 pathmap_t
*pmp
= v
->get (i
);
1458 if ((strcmp (pmp
->old_prefix
, old_prefix
) == 0) &&(strcmp (pmp
->new_prefix
, new_prefix
) == 0))
1460 char *s
= dbe_sprintf (GTXT ("Pathmap from `%s' to `%s' already exists\n"), old_prefix
, new_prefix
);
1466 // construct a map for this pair
1467 pathmap_t
*thismap
= new pathmap_t
;
1468 thismap
->old_prefix
= old_prefix
;
1469 thismap
->new_prefix
= new_prefix
;
1470 v
->append (thismap
);
1474 // Set all shared object expands back to .rc file defaults,
1475 // as stored in the DbeSession Settings
1477 Settings::set_libdefaults ()
1479 // See if this is unchanged
1480 if (is_loexpand_default
== true)
1481 return false; // no change
1483 // replicate the DbeSession's lo_expand vector and default settings
1484 lo_expand_t
*this_lo_ex
;
1485 lo_expand_t
*new_lo_ex
;
1487 lo_expand_default
= dbeSession
->get_settings ()->lo_expand_default
;
1488 lo_expands
= new Vector
<lo_expand_t
*>;
1489 Vec_loop (lo_expand_t
*, dbeSession
->get_settings ()->lo_expands
, index
, this_lo_ex
)
1491 new_lo_ex
= new lo_expand_t
;
1492 new_lo_ex
->libname
= dbe_strdup (this_lo_ex
->libname
);
1493 new_lo_ex
->expand
= this_lo_ex
->expand
;
1494 lo_expands
->append (new_lo_ex
);
1496 is_loexpand_default
= true;
1501 Settings::set_libexpand (char *cov
, enum LibExpand expand
, bool rc
)
1505 bool change
= false;
1506 if (cov
== NULL
|| !strcasecmp (cov
, Command::ALL_CMD
))
1507 { // set all libraries
1509 if (lo_expand_default
!= expand
)
1511 lo_expand_default
= expand
;
1513 is_loexpand_default
= false;
1516 // and force any explicit settings to match, too
1517 Vec_loop (lo_expand_t
*, lo_expands
, index
, loe
)
1519 if (loe
->expand
!= expand
)
1521 loe
->expand
= expand
;
1523 is_loexpand_default
= false;
1529 { // parsing coverage
1530 Vector
<char *> *tokens
= split_str (cov
, ',');
1531 for (long j
= 0, sz
= VecSize (tokens
); j
< sz
; j
++)
1533 char *lo_name
= tokens
->get (j
);
1534 char *newname
= get_basename (lo_name
);
1536 Vec_loop (lo_expand_t
*, lo_expands
, index
, loe
)
1538 if (strcmp (loe
->libname
, newname
) == 0)
1540 if (loe
->expand
!= expand
)
1544 loe
->expand
= expand
;
1546 is_loexpand_default
= false;
1556 // construct a map for this pair
1557 lo_expand_t
*thisloe
;
1558 thisloe
= new lo_expand_t
;
1559 thisloe
->libname
= dbe_strdup (newname
);
1560 thisloe
->expand
= expand
;
1562 is_loexpand_default
= false;
1564 // add it to the vector
1565 lo_expands
->append (thisloe
);
1575 Settings::get_lo_setting (char *name
)
1579 char *lo_name
= get_basename (name
);
1580 Vec_loop (lo_expand_t
*, lo_expands
, index
, loe
)
1582 if (strcmp (loe
->libname
, lo_name
) == 0)
1585 return lo_expand_default
;