1/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
2   Contributed by Oracle.
3
4   This file is part of GNU Binutils.
5
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.
10
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.
15
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.  */
20
21#include "config.h"
22#include <time.h>
23
24#include "DbeSession.h"
25#include "Expression.h"
26#include "StringBuilder.h"
27#include "util.h"
28#include "UserLabel.h"
29#include "debug.h"
30
31int UserLabel::last_id = 0;
32
33UserLabel::UserLabel (char *_name)
34{
35  name = dbe_strdup (_name);
36  comment = str_expr = all_times = hostname = NULL;
37  start_f = stop_f = false;
38  expr = NULL;
39  start_tv.tv_sec = 0;
40  start_tv.tv_usec = 0;
41  atime = timeStart = timeStop = start_sec = start_hrtime = 0;
42  relative = REL_TIME;
43  id = ++last_id;
44}
45
46UserLabel::~UserLabel ()
47{
48  free (name);
49  free (comment);
50  free (all_times);
51  free (hostname);
52  free (str_expr);
53  delete expr;
54}
55
56void
57UserLabel::gen_expr ()
58{
59  if (!start_f && !stop_f)
60    return;
61  StringBuilder sb;
62  sb.append ('(');
63  if (str_expr)
64    {
65      sb.append (str_expr);
66      sb.append (NTXT (" || ("));
67    }
68  if (start_f)
69    {
70      sb.append (NTXT ("TSTAMP"));
71      sb.append (NTXT (">="));
72      sb.append (timeStart);
73      if (stop_f)
74	{
75	  sb.append (NTXT (" && "));
76	}
77    }
78  if (stop_f)
79    {
80      sb.append (NTXT ("TSTAMP"));
81      sb.append ('<');
82      sb.append (timeStop);
83    }
84  sb.append (')');
85  if (str_expr)
86    {
87      sb.append (')');
88      delete str_expr;
89    }
90  str_expr = sb.toString ();
91  start_f = stop_f = false;
92}
93
94void
95UserLabel::register_user_label (int groupId)
96{
97  gen_expr ();
98  if (str_expr)
99    {
100      char *old_str = str_expr;
101      str_expr = dbe_sprintf (NTXT ("(EXPGRID==%d && %s)"), groupId, old_str);
102      delete old_str;
103      UserLabel *ulbl = dbeSession->findUserLabel (name);
104      if (ulbl)
105	{
106	  old_str = ulbl->str_expr;
107	  ulbl->str_expr = dbe_sprintf (NTXT ("(%s || %s)"), old_str, str_expr);
108	  delete old_str;
109	  if (comment)
110	    {
111	      if (ulbl->comment)
112		{
113		  old_str = ulbl->comment;
114		  ulbl->comment = dbe_sprintf (NTXT ("%s; %s"), old_str, comment);
115		  delete old_str;
116		}
117	      else
118		ulbl->comment = dbe_strdup (comment);
119	    }
120	  delete ulbl->expr;
121	  ulbl->expr = dbeSession->ql_parse (ulbl->str_expr);
122	}
123      else
124	{
125	  expr = dbeSession->ql_parse (str_expr);
126	  dbeSession->append (this);
127	}
128    }
129}
130
131char *
132UserLabel::dump ()
133{
134  StringBuilder sb;
135  sb.append (name);
136  if (str_expr)
137    {
138      sb.append (NTXT ("  str_expr='"));
139      sb.append (str_expr);
140      sb.append ('\'');
141    }
142  if (all_times)
143    {
144      sb.append (NTXT (" atime="));
145      sb.append ((unsigned int) (atime / NANOSEC));
146      sb.append ('.');
147      char buf[128];
148      snprintf (buf, sizeof (buf), NTXT ("%09llu"), (unsigned long long) (atime % NANOSEC));
149      sb.append (buf);
150      sb.append (NTXT ("  all_times='"));
151      sb.append (all_times);
152      sb.append ('\'');
153    }
154  if (comment)
155    {
156      sb.append (NTXT ("  comment='"));
157      sb.append (comment);
158      sb.append ('\'');
159    }
160  return sb.toString ();
161}
162
163void
164UserLabel::dump (const char *msg, Vector<UserLabel*> *labels)
165{
166  if (!DUMP_USER_LABELS)
167    return;
168  if (msg)
169    fprintf (stderr, NTXT ("%s\n"), msg);
170  for (int i = 0, sz = labels ? labels->size () : 0; i < sz; i++)
171    {
172      UserLabel *lbl = labels->fetch (i);
173      char *s = lbl->dump ();
174      fprintf (stderr, NTXT ("%2d %s\n"), i, s);
175      delete s;
176    }
177}
178