Automatic date update in version.in
[binutils-gdb.git] / gprofng / src / Settings.cc
blob965b9174da669e1b05512a1e6af9f039e2074582
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2 Contributed by Oracle.
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)
9 any later version.
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. */
21 #include "config.h"
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/param.h>
27 #include "enums.h"
28 #include "Settings.h"
29 #include "DbeSession.h"
30 #include "Command.h"
31 #include "Application.h"
32 #include "MemorySpace.h"
33 #include "StringBuilder.h"
34 #include "Table.h"
35 #include "Emsg.h"
36 #include "util.h"
37 #include "i18n.h"
39 // Commands for compiler commentary
40 static const char *comp_cmd[] = {
41 NTXT ("basic"),
42 NTXT ("version"),
43 NTXT ("warn"),
44 NTXT ("parallel"),
45 NTXT ("query"),
46 NTXT ("loop"),
47 NTXT ("pipe"),
48 NTXT ("inline"),
49 NTXT ("memops"),
50 NTXT ("fe"),
51 NTXT ("codegen"),
52 NTXT ("src"),
53 NTXT ("asrc"),
54 NTXT ("nosrc"),
55 NTXT ("hex"),
56 NTXT ("nohex"),
57 NTXT ("threshold"),
58 NTXT ("cf")
61 static const int comp_vis[] = {
62 CCMV_BASIC,
63 CCMV_VER,
64 CCMV_WARN,
65 CCMV_PAR,
66 CCMV_QUERY,
67 CCMV_LOOP,
68 CCMV_PIPE,
69 CCMV_INLINE,
70 CCMV_MEMOPS,
71 CCMV_FE,
72 CCMV_CG,
73 COMP_SRC,
74 COMP_SRC_METRIC,
75 COMP_NOSRC,
76 COMP_HEX,
77 COMP_NOHEX,
78 COMP_THRESHOLD,
79 COMP_CMPLINE
82 const int comp_size = sizeof (comp_cmd) / sizeof (char *);
84 // Commands for timeline
85 typedef enum
87 TLCMD_INVALID,
88 TLCMD_ENTITY_MODE,
89 TLCMD_ALIGN,
90 TLCMD_DEPTH
91 } TLModeSubcommand;
93 typedef struct
95 const char * cmdText;
96 TLModeSubcommand cmdType;
97 int cmdId;
98 } TLModeCmd;
99 static const TLModeCmd tlmode_cmd[] = {
100 // MODE commands
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},
105 // ALIGN commands
106 {NTXT ("root"), TLCMD_ALIGN, TLSTACK_ALIGN_ROOT},
107 {NTXT ("leaf"), TLCMD_ALIGN, TLSTACK_ALIGN_LEAF},
108 // DEPTH commands
109 {NTXT ("depth"), TLCMD_DEPTH, 0 /* don't care */}
112 static const int tlmode_size = sizeof (tlmode_cmd) / sizeof (TLModeCmd);
114 // Constructor
116 Settings::Settings (Application *_app)
118 // Remember the application
119 app = _app;
121 // Clear all default strings
122 str_vmode = NULL;
123 str_en_desc = NULL;
124 str_datamode = NULL;
125 str_scompcom = NULL;
126 str_sthresh = NULL;
127 str_dcompcom = NULL;
128 str_dthresh = NULL;
129 str_dmetrics = NULL;
130 str_dsort = NULL;
131 str_tlmode = NULL;
132 str_tldata = NULL;
133 str_tabs = NULL;
134 str_rtabs = NULL;
135 str_search_path = NULL;
136 str_name_format = NULL;
137 str_limit = NULL;
138 str_printmode = NULL;
139 str_compare = 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;
150 en_desc = false;
151 en_desc_cmp = NULL;
152 en_desc_usr = NULL;
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;
158 src_visible = true;
159 srcmetric_visible = false;
160 hex_visible = false;
161 cmpline_visible = true;
162 funcline_visible = true;
163 tldata = NULL;
164 tlmode = 0;
165 stack_align = 0;
166 stack_depth = 0;
167 limit = 0;
168 // print mode is initialized after the .rc files are read
169 print_delim = ',';
170 compare_mode = CMP_DISABLE;
171 machinemodel = NULL;
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)
190 int index;
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
215 pathmap_t *thismap;
216 pathmap_t *newmap;
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;
246 en_desc = false;
247 en_desc_cmp = NULL;
248 en_desc_usr = NULL;
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*>;
274 DispTab *dsptab;
276 Vec_loop (DispTab*, _settings->tab_list, index, dsptab)
278 DispTab *ntab;
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);
310 delete pmap;
312 delete pathmaps;
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);
318 delete lo_ex;
320 delete lo_expands;
322 tab_list->destroy ();
323 delete tab_list;
324 delete indx_tab_state;
325 delete indx_tab_order;
326 delete mem_tab_state;
327 delete mem_tab_order;
329 free (str_vmode);
330 free (str_en_desc);
331 free (str_datamode);
332 free (str_scompcom);
333 free (str_sthresh);
334 free (str_dcompcom);
335 free (str_dthresh);
336 free (str_dmetrics);
337 free (str_dsort);
338 free (str_tlmode);
339 free (str_tldata);
340 free (str_tabs);
341 free (str_rtabs);
342 free (str_search_path);
343 free (str_name_format);
344 free (str_limit);
345 free (str_compare);
346 free (str_printmode);
347 free (preload_libdirs);
348 free (tldata);
349 free (en_desc_usr);
350 if (en_desc_cmp)
352 regfree (en_desc_cmp);
353 delete en_desc_cmp;
358 * Read .er.rc file from the specified location
359 * @param path
360 * @return
362 char *
363 Settings::read_rc (char *path)
365 StringBuilder sb;
366 Emsgqueue *commentq = new Emsgqueue (NTXT ("setting_commentq"));
368 // Check file name
369 if (NULL == path)
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 ();
374 while (msg != NULL)
376 char *str = msg->get_msg ();
377 sb.append (str);
378 msg = msg->next;
380 return sb.toString ();
383 void
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);
390 if (rc_path)
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"));
395 if (home)
397 char *strbuf = dbe_sprintf (NTXT ("%s/.gprofng.rc"), home);
398 char *home_rc_path = realpath (strbuf, NULL);
399 if (home_rc_path)
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);
403 free (home_rc_path);
405 free (strbuf);
407 free (rc_path);
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)
413 StringBuilder sb;
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);
418 else
419 set_rc (rc_path, false, app->get_comments_queue (), override);
420 free (rc_path);
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
438 #define MAXARGS 20
440 void
441 Settings::set_rc (const char *path, bool msg, Emsgqueue *commentq,
442 bool override, bool ipc_or_rdt_mode)
444 CmdType cmd_type;
445 int arg_count, cparam;
446 char *cmd, *end_cmd, *strbuf;
447 char *arglist[MAXARGS];
448 StringBuilder sb;
450 FILE *fptr = fopen (path, NTXT ("r"));
451 if (fptr == NULL)
452 return;
454 if (msg)
456 sb.sprintf (GTXT ("Processed %s for default settings"), path);
457 Emsg *m = new Emsg (CMSG_COMMENT, sb);
458 commentq->append (m);
460 int line_no = 0;
461 end_cmd = NULL;
462 while (!feof (fptr))
464 char *script = read_line (fptr);
465 if (script == NULL)
466 continue;
467 line_no++;
468 strtok (script, NTXT ("\n"));
470 // extract the command
471 cmd = strtok (script, NTXT (" \t"));
472 if (cmd == NULL || *cmd == '#' || *cmd == '\n')
474 free (script);
475 continue;
477 char *remainder = strtok (NULL, NTXT ("\n"));
478 // now extract the arguments
479 int nargs = 0;
480 for (;;)
482 if (nargs >= MAXARGS)
484 if (!msg)
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);
494 break;
497 char *nextarg = strtok (remainder, NTXT ("\n"));
498 if (nextarg == NULL || *nextarg == '#')
499 break;
500 arglist[nargs++] = parse_qstring (nextarg, &end_cmd);
501 remainder = end_cmd;
502 if (remainder == NULL)
503 break;
504 // skip any blanks or tabs to get to next argument
505 while (*remainder == ' ' || *remainder == '\t')
506 remainder++;
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))
512 if (!msg)
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)
524 if (!msg)
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"),
531 cmd, line_no);
532 Emsg *m = new Emsg (CMSG_COMMENT, sb);
533 commentq->append (m);
535 // ignore this command
536 free (script);
537 continue;
539 if (ipc_or_rdt_mode && (cmd_type != ADDPATH) && (cmd_type != PATHMAP))
541 free (script);
542 continue;
544 switch (cmd_type)
546 case SCOMPCOM:
547 if (!str_scompcom || override)
549 str_scompcom = dbe_strdup (arglist[0]);
550 proc_compcom (arglist[0], true, true);
552 break;
553 case STHRESH:
554 if (!str_sthresh || override)
556 str_sthresh = dbe_strdup (arglist[0]);
557 proc_thresh (arglist[0], true, true);
558 break;
560 break;
561 case DCOMPCOM:
562 if (!str_dcompcom || override)
564 str_dcompcom = dbe_strdup (arglist[0]);
565 proc_compcom (arglist[0], false, true);
567 break;
568 case COMPCOM:
569 // process as if it were for both source and disassembly
570 // note that if it is set, subsequent SCOMPCOM and DCOMPCOM
571 // will be ignored
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);
582 break;
583 case DTHRESH:
584 if (!str_dthresh || override)
586 str_dthresh = dbe_strdup (arglist[0]);
587 proc_thresh (arglist[0], false, true);
589 break;
590 case DMETRICS:
591 // append new settings to old, if necessary
592 if (str_dmetrics)
594 char *name = strstr (str_dmetrics, ":name");
595 if (name == NULL)
596 strbuf = dbe_sprintf ("%s:%s", str_dmetrics, arglist[0]);
597 else
599 char * next = strstr (name + 1, ":");
600 if (next == NULL)
602 name[0] = '\0';
603 strbuf = dbe_sprintf ("%s:%s:name", str_dmetrics, arglist[0]);
605 else
606 strbuf = dbe_sprintf ("%s:%s", str_dmetrics, arglist[0]);
608 free (str_dmetrics);
609 str_dmetrics = strbuf;
611 else
612 str_dmetrics = dbe_strdup (arglist[0]);
613 break;
614 case DSORT:
615 // append new settings to old, if necessary
616 if (str_dsort)
618 strbuf = dbe_sprintf (NTXT ("%s:%s"), str_dsort, arglist[0]);
619 free (str_dsort);
620 str_dsort = strbuf;
622 else
623 str_dsort = dbe_strdup (arglist[0]);
624 break;
625 case TLMODE:
626 if (!str_tlmode || override)
628 str_tlmode = dbe_strdup (arglist[0]);
629 proc_tlmode (arglist[0], true);
631 break;
632 case TLDATA:
633 if (!str_tldata || override)
635 str_tldata = dbe_strdup (arglist[0]);
636 proc_tldata (arglist[0], true);
638 break;
639 case TABS:
640 if (!str_tabs || override)
641 // the string is processed later, after all .rc files are read
642 str_tabs = dbe_strdup (arglist[0]);
643 break;
644 case RTABS:
645 if (!str_rtabs || override)
646 // the string is processed later, after all .rc files are read
647 str_rtabs = dbe_strdup (arglist[0]);
648 break;
649 case ADDPATH:
650 if (str_search_path)
652 strbuf = dbe_sprintf (NTXT ("%s:%s"), str_search_path, arglist[0]);
653 free (str_search_path);
654 str_search_path = strbuf;
656 else
657 str_search_path = dbe_strdup (arglist[0]);
658 break;
659 case PATHMAP:
661 char *err = add_pathmap (pathmaps, arglist[0], arglist[1]);
662 free (err); // XXX error is not reported
663 break;
665 case LIBDIRS:
666 if (preload_libdirs == NULL)
667 preload_libdirs = dbe_strdup (arglist[0]);
668 break;
669 case NAMEFMT:
670 if (name_format == Histable::NA)
671 set_name_format (arglist[0]);
672 break;
673 case VIEWMODE:
674 if (!str_vmode || override)
676 str_vmode = dbe_strdup (arglist[0]);
677 set_view_mode (arglist[0], true);
679 break;
680 case EN_DESC:
681 if (!str_en_desc || override)
683 str_en_desc = dbe_strdup (arglist[0]);
684 set_en_desc (arglist[0], true);
686 break;
687 case LIMIT:
688 if (!str_limit || override)
690 str_limit = dbe_strdup (arglist[0]);
691 set_limit (arglist[0], true);
693 break;
694 case PRINTMODE:
695 if (!str_printmode || override)
696 set_printmode (arglist[0]);
697 break;
698 case COMPARE:
699 if (!str_compare || override)
701 char *s = arglist[0];
702 if (s)
703 str_compare = dbe_strdup (s);
704 else
705 s = NTXT ("");
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);
716 else
718 sb.sprintf (GTXT (" .er.rc:%d The argument of 'compare' should be 'on', 'off', 'delta', or 'ratio'"),
719 (int) line_no);
720 Emsg *m = new Emsg (CMSG_COMMENT, sb);
721 commentq->append (m);
724 break;
726 case INDXOBJDEF:
728 char *ret = dbeSession->indxobj_define (arglist[0], NULL, arglist[1], (nargs >= 3) ? PTXT (arglist[2]) : NULL, (nargs >= 4) ? PTXT (arglist[3]) : NULL);
729 if (ret != 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);
736 break;
738 #ifdef sparc
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);
743 break;
744 #endif // sparc
745 case IGNORE_FS_WARN:
746 // ignore file system warning in experiments
747 set_ignore_fs_warn (true);
748 break;
749 case OBJECT_SHOW:
750 // Add the named libraries to the lib_expands array
751 set_libexpand (arglist[0], LIBEX_SHOW, true);
752 break;
753 case OBJECT_HIDE:
754 // Add the named libraries to the lib_expands array
755 set_libexpand (arglist[0], LIBEX_HIDE, true);
756 break;
757 case OBJECT_API:
758 // Add the named libraries to the lib_expands array
759 set_libexpand (arglist[0], LIBEX_API, true);
760 break;
761 case COMMENT:
762 // ignore the line
763 break;
764 default:
766 // unexpected command in an rc file
767 if (!msg)
769 // if quiet, can remain so no longer
770 msg = true;
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'"),
775 line_no, cmd);
776 Emsg *m = new Emsg (CMSG_COMMENT, sb);
777 commentq->append (m);
778 break;
781 free (script);
783 fclose (fptr);
786 Cmd_status
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;
795 else if (!rc)
796 return CMD_BAD_ARG;
797 return CMD_OK;
800 Cmd_status
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")))
807 en_desc = true;
808 else if (!strcasecmp (arg, NTXT ("off")))
809 en_desc = false;
810 else if (arg[0] == '=' && arg[1] != 0)
812 // user has specified a string matching specification
813 int ercode;
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);
819 free (str);
821 if (ercode)
823 // syntax error in parsing string
824 delete regex_desc;
825 if (!rc)
826 return CMD_BAD_ARG;
827 return CMD_OK;
829 en_desc = true;
831 else
833 if (!rc)
834 return CMD_BAD_ARG;
835 return CMD_OK;
837 free (en_desc_usr);
838 en_desc_usr = dbe_strdup (arg);
839 if (en_desc_cmp)
841 regfree (en_desc_cmp);
842 delete en_desc_cmp;
844 en_desc_cmp = regex_desc;
845 return CMD_OK;
848 // See if a descendant matches either the lineage or the executable name
849 bool
850 Settings::check_en_desc (const char *lineage, const char *targname)
852 bool rc;
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
863 else
864 rc = false;
865 return rc;
868 char *
869 Settings::set_limit (char *arg, bool)
871 limit = (int) strtol (arg, (char **) NULL, 10);
872 return NULL;
875 char *
876 Settings::set_printmode (char *arg)
878 if (arg == NULL)
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;
890 else
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);
895 return NULL;
898 Cmd_status
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;
907 int len, i;
908 char *mcmd, *param;
909 int flag, value = 0;
910 Cmd_status status;
911 char buf[BUFSIZ], *list;
913 if (cmd == NULL)
914 return CMD_BAD;
915 ck_compcom_bits = 0;
916 ck_threshold = 0;
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);
920 list = buf;
921 while ((mcmd = strtok (list, NTXT (":"))) != NULL)
923 list = NULL;
924 // if "all" or "none"
925 if (!strcasecmp (mcmd, Command::ALL_CMD))
927 got_compcom_bits = true;
928 ck_compcom_bits = CCMV_ALL;
929 continue;
931 else if (!strcasecmp (mcmd, Command::NONE_CMD))
933 got_compcom_bits = true;
934 ck_compcom_bits = 0;
935 continue;
938 // Find parameter after '='
939 param = strchr (mcmd, '=');
940 if (param)
942 *param = '\0';
943 param++;
945 status = CMD_OK;
946 got = false;
947 flag = 0;
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;
954 else
956 got = true;
957 flag = comp_vis[i];
958 // Check argument
959 if (flag == COMP_THRESHOLD)
961 if (param == NULL)
962 status = CMD_BAD_ARG;
963 else
965 value = (int) strtol (param, &param, 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
976 if (!got)
977 status = CMD_INVALID;
978 if (status != CMD_OK)
980 if (!rc)
981 return status;
982 continue;
985 // Set bits
986 switch (flag)
988 case COMP_CMPLINE:
989 cmpline_visible = true;
990 break;
991 case COMP_FUNCLINE:
992 funcline_visible = true;
993 break;
994 case COMP_THRESHOLD:
995 got_threshold = true;
996 ck_threshold = value;
997 break;
998 case COMP_SRC:
999 got_src_visible = true;
1000 ck_src_visible = true;
1001 break;
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;
1007 break;
1008 case COMP_NOSRC:
1009 got_src_visible = true;
1010 ck_src_visible = false;
1011 break;
1012 case COMP_HEX:
1013 got_hex_visible = true;
1014 ck_hex_visible = true;
1015 break;
1016 case COMP_NOHEX:
1017 got_hex_visible = true;
1018 ck_hex_visible = false;
1019 break;
1020 case CCMV_BASIC:
1021 got_compcom_bits = true;
1022 ck_compcom_bits = CCMV_BASIC;
1023 break;
1024 default:
1025 got_compcom_bits = true;
1026 ck_compcom_bits |= flag;
1030 // No error, update
1031 if (got_compcom_bits)
1033 if (isSrc)
1034 src_compcom = ck_compcom_bits;
1035 else
1036 dis_compcom = ck_compcom_bits;
1038 if (got_threshold)
1040 if (isSrc)
1041 threshold_src = ck_threshold;
1042 else
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;
1051 return CMD_OK;
1054 // Process a threshold setting
1055 Cmd_status
1056 Settings::proc_thresh (char *cmd, bool isSrc, bool rc)
1058 int value;
1059 if (cmd == NULL)
1060 value = DEFAULT_SRC_DIS_THRESHOLD; // the default
1061 else
1062 value = (int) strtol (cmd, &cmd, 10);
1063 if (value < 0 || value > 100)
1065 if (!rc)
1066 return CMD_OUTRANGE;
1067 value = DEFAULT_SRC_DIS_THRESHOLD;
1069 if (isSrc)
1070 threshold_src = value;
1071 else
1072 threshold_dis = value;
1073 return CMD_OK;
1076 // return any error string from processing visibility settings
1077 char *
1078 Settings::get_compcom_errstr (Cmd_status status, const char *cmd)
1080 int i;
1081 StringBuilder sb;
1082 switch (status)
1084 case CMD_BAD:
1085 sb.append (GTXT ("No commentary classes has been specified."));
1086 break;
1087 case CMD_AMBIGUOUS:
1088 sb.append (GTXT ("Ambiguous commentary classes: "));
1089 break;
1090 case CMD_BAD_ARG:
1091 sb.append (GTXT ("Invalid argument for commentary classes: "));
1092 break;
1093 case CMD_OUTRANGE:
1094 sb.append (GTXT ("Out of range commentary classes argument: "));
1095 break;
1096 case CMD_INVALID:
1097 sb.append (GTXT ("Invalid commentary classes: "));
1098 break;
1099 case CMD_OK:
1100 break;
1102 if (cmd)
1103 sb.append (cmd);
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"));
1110 else
1111 sb.append (NTXT (":"));
1113 return sb.toString ();
1116 // Process a timeline-mode setting
1117 Cmd_status
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;
1122 int len, i;
1123 char *mcmd, *param;
1124 int cmd_id, value = 0;
1125 TLModeSubcommand cmd_type;
1126 Cmd_status status;
1127 char buf[BUFSIZ], *list;
1128 if (cmd == NULL)
1129 return CMD_BAD;
1130 got_tlmode = got_stack_align = got_stack_depth = false;
1131 snprintf (buf, sizeof (buf), NTXT ("%s"), cmd);
1132 list = buf;
1133 while ((mcmd = strtok (list, NTXT (":"))) != NULL)
1135 list = NULL;
1137 // Find parameter after '='
1138 param = strchr (mcmd, '=');
1139 if (param)
1141 *param = '\0';
1142 param++;
1144 status = CMD_OK;
1145 got = false;
1146 cmd_id = 0;
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;
1155 else
1157 got = true;
1158 cmd_type = tlmode_cmd[i].cmdType;
1159 cmd_id = tlmode_cmd[i].cmdId;
1161 // Check argument
1162 if (cmd_type == TLCMD_DEPTH)
1164 if (param == NULL)
1165 status = CMD_BAD_ARG;
1166 else
1168 value = (int) strtol (param, &param, 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
1180 if (!got)
1181 status = CMD_INVALID;
1182 if (status != CMD_OK)
1184 if (!rc)
1185 return status;
1186 continue;
1189 // Set bits
1190 switch (cmd_type)
1192 case TLCMD_ENTITY_MODE:
1193 got_tlmode = true;
1194 ck_tlmode = cmd_id;
1195 break;
1196 case TLCMD_ALIGN:
1197 got_stack_align = true;
1198 ck_stack_align = cmd_id;
1199 break;
1200 case TLCMD_DEPTH:
1201 got_stack_depth = true;
1202 ck_stack_depth = value;
1203 break;
1204 default:
1205 break;
1209 // No error, update
1210 if (got_tlmode)
1211 tlmode = ck_tlmode;
1212 if (got_stack_align)
1213 stack_align = ck_stack_align;
1214 if (got_stack_depth)
1215 stack_depth = ck_stack_depth;
1216 return CMD_OK;
1219 // Process timeline data specification
1220 Cmd_status
1221 Settings::proc_tldata (const char *cmd, bool /* if true, ignore any error */)
1223 free (tldata);
1224 tldata = dbe_strdup (cmd); // let GUI parse it
1225 return CMD_OK;
1228 void
1229 Settings::set_tldata (const char* _tldata_str)
1231 free (tldata);
1232 tldata = dbe_strdup (_tldata_str);
1235 char*
1236 Settings::get_tldata ()
1238 return dbe_strdup (tldata);
1241 Cmd_status
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;
1253 else
1254 return CMD_BAD_ARG;
1256 bool soname_fmt = false;
1257 if (colon && (colon + 1))
1259 colon++;
1260 if (!strcasecmp (colon, NTXT ("soname")))
1261 soname_fmt = true;
1262 else if (!strcasecmp (colon, NTXT ("nosoname")))
1263 soname_fmt = false;
1264 else
1265 return CMD_BAD_ARG;
1267 name_format = Histable::make_fmt (fname_fmt, soname_fmt);
1268 return CMD_OK;
1271 void
1272 Settings::buildMasterTabList ()
1274 tab_list = new Vector<DispTab*>;
1275 int i = -1;
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
1299 void
1300 Settings::updateTabAvailability ()
1302 int index;
1303 DispTab *dsptab;
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
1332 Cmd_status
1333 Settings::proc_tabs (bool _rdtMode)
1335 int arg_cnt, cparam;
1336 int count = 0;
1337 int index;
1338 DispTab *dsptab;
1339 char *cmd;
1340 if (tabs_processed == true)
1341 return CMD_OK;
1342 tabs_processed = true;
1343 if (_rdtMode == true)
1345 if (str_rtabs == NULL)
1346 str_rtabs = strdup ("header");
1347 cmd = str_rtabs;
1349 else
1351 if (str_tabs == NULL)
1352 str_tabs = strdup ("header");
1353 cmd = str_tabs;
1355 if (strcmp (cmd, NTXT ("none")) == 0)
1356 return CMD_OK;
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);
1363 if (c == INDXOBJ)
1365 // set the bit for this subtype
1366 indx_tab_state->store (cparam, true);
1367 indx_tab_order->store (cparam, count++);
1369 else
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++;
1378 break;
1382 free (tabname);
1384 delete tokens;
1385 return CMD_OK;
1388 void
1389 Settings::set_MemTabState (Vector<bool>*selected)
1391 if (selected->size () == 0)
1392 return;
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
1399 void
1400 Settings::mobj_define (MemObjType_t */* mobj */, bool state)
1402 if (mem_tab_state->size () == 0)
1403 state = true;
1404 mem_tab_state->append (state);
1405 mem_tab_order->append (-1);
1408 void
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
1416 void
1417 Settings::indxobj_define (int type, bool state)
1419 indx_tab_state->store (type, state);
1420 indx_tab_order->store (type, -1);
1423 void
1424 Settings::set_pathmaps (Vector<pathmap_t*> *newPathMap)
1426 if (pathmaps)
1428 pathmaps->destroy ();
1429 delete pathmaps;
1431 pathmaps = newPathMap;
1434 static char *
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--)
1439 nm[len - 1] = 0;
1440 return nm;
1443 char *
1444 Settings::add_pathmap (Vector<pathmap_t*> *v, const char *from, const char *to)
1446 // Check for errors
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);
1461 free (old_prefix);
1462 free (new_prefix);
1463 return s;
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);
1471 return NULL;
1474 // Set all shared object expands back to .rc file defaults,
1475 // as stored in the DbeSession Settings
1476 bool
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;
1486 int index;
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;
1497 return true;
1500 bool
1501 Settings::set_libexpand (char *cov, enum LibExpand expand, bool rc)
1503 int index;
1504 lo_expand_t *loe;
1505 bool change = false;
1506 if (cov == NULL || !strcasecmp (cov, Command::ALL_CMD))
1507 { // set all libraries
1508 // set the default
1509 if (lo_expand_default != expand)
1511 lo_expand_default = expand;
1512 change = true;
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;
1522 change = true;
1523 is_loexpand_default = false;
1528 else
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);
1535 bool found = false;
1536 Vec_loop (lo_expand_t*, lo_expands, index, loe)
1538 if (strcmp (loe->libname, newname) == 0)
1540 if (loe->expand != expand)
1542 if (rc == false)
1544 loe->expand = expand;
1545 change = true;
1546 is_loexpand_default = false;
1549 found = true;
1550 break;
1554 if (found == 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;
1561 change = true;
1562 is_loexpand_default = false;
1564 // add it to the vector
1565 lo_expands->append (thisloe);
1567 free (lo_name);
1569 delete tokens;
1571 return change;
1574 enum LibExpand
1575 Settings::get_lo_setting (char *name)
1577 int index;
1578 lo_expand_t *loe;
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)
1583 return loe->expand;
1585 return lo_expand_default;