Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
laelaps_utils.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Laelaps
4 //
5 // Program: laelaps_diag
6 //
7 // File: laelaps_utils.cxx
8 //
9 /*! \file
10  *
11  * \brief Diagnostic utilities.
12  *
13  * \author Robin Knight (robin.knight@roadnarrows.com)
14  *
15  * \par Copyright
16  * \h_copy 2015-2017. RoadNarrows LLC.\n
17  * http://www.roadnarrows.com\n
18  * All Rights Reserved
19  */
20 /*
21  * @EulaBegin@
22  *
23  * Unless otherwise stated explicitly, all materials contained are copyrighted
24  * and may not be used without RoadNarrows LLC's written consent,
25  * except as provided in these terms and conditions or in the copyright
26  * notice (documents and software) or other proprietary notice provided with
27  * the relevant materials.
28  *
29  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
30  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
31  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
32  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
33  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
34  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
37  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
38  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
39  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
40  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
41  *
42  * @EulaEnd@
43  */
44 ////////////////////////////////////////////////////////////////////////////////
45 
46 #include <sys/types.h>
47 #include <unistd.h>
48 #include <termios.h>
49 #include <limits.h>
50 #include <dirent.h>
51 #include <string.h>
52 #include <stdio.h>
53 #include <stdarg.h>
54 #include <stdlib.h>
55 
56 #include <string>
57 
58 #include "rnr/rnrconfig.h"
59 #include "rnr/color.h"
60 
61 #include "laelaps_diag.h"
62 
63 using namespace std;
64 
65 //------------------------------------------------------------------------------
66 // Private Interface
67 //------------------------------------------------------------------------------
68 
69 //
70 // Tag colors
71 //
72 #define COLOR_PASS ANSI_FG_GREEN
73 #define COLOR_WARN ANSI_FG_YELLOW
74 #define COLOR_FAIL ANSI_FG_RED
75 #define COLOR_YN ANSI_FG_BLUE
76 #define COLOR_FATAL ANSI_FG_BRIGHT_RED
77 #define COLOR_OFF ANSI_COLOR_RESET
78 
79 //
80 // Separators
81 //
82 static const char *DiagSep = \
83 "-----------------------------------------------------------------------------";
84 
85 static const char *SubHdrSep = \
86 ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .";
87 
88 static const char *SubSumTag = " ...";
89 static const char *TotSumTag = "...";
90 
91 static int getch()
92 {
93  static bool bSetup = false;
94  static struct termios orig, nb;
95 
96  char c = 0;
97 
98  if( !bSetup )
99  {
100  if( tcgetattr(0, &orig) < 0 )
101  {
102  return EOF;
103  }
104 
105  nb = orig;
106  nb.c_lflag &= ~ICANON;
107  nb.c_lflag &= ~ECHO;
108  nb.c_cc[VMIN] = 0;
109  nb.c_cc[VTIME] = 0;
110 
111  bSetup = true;
112  }
113 
114  if( tcsetattr(0, TCSANOW, &nb) < 0 )
115  {
116  c = EOF;
117  }
118 
119  else if( read(0, &c, 1) < 0 )
120  {
121  c = EOF;
122  }
123 
124  if( tcsetattr(0, TCSANOW, &orig) < 0 )
125  {
126  }
127 
128  return c;
129 }
130 
131 //------------------------------------------------------------------------------
132 // Public Interface
133 //------------------------------------------------------------------------------
134 
135 long findProc(const string &strName)
136 {
137  DIR *dir;
138  struct dirent *ent;
139  char *endptr;
140  char buf[PATH_MAX];
141 
142  if( !(dir = opendir("/proc")) )
143  {
144  return -1;
145  }
146 
147  while( (ent = readdir(dir)) != NULL )
148  {
149  // if endptr is not a null character, the directory is not
150  // entirely numeric, so ignore it
151  long lpid = strtol(ent->d_name, &endptr, 10);
152 
153  if( *endptr != '\0' )
154  {
155  continue;
156  }
157 
158  // try to open the cmdline file
159  snprintf(buf, sizeof(buf), "/proc/%ld/cmdline", lpid);
160 
161  FILE *fp = fopen(buf, "r");
162 
163  if( fp != NULL )
164  {
165  if( fgets(buf, sizeof(buf), fp) != NULL )
166  {
167  // check the first token in the file, the program name
168  string strCmd(strtok(buf, " "));
169 
170  if( strCmd.find(strName) != string::npos )
171  {
172  fclose(fp);
173  closedir(dir);
174  return lpid;
175  }
176  }
177  fclose(fp);
178  }
179  }
180 
181  closedir(dir);
182  return -1;
183 }
184 
185 int kbblock()
186 {
187  int c;
188 
189  while( (c = getch()) == 0 );
190 
191  return c;
192 }
193 
194 int kbhit()
195 {
196  return getch();
197 }
198 
199 //
200 // Diagnostic tags
201 //
202 const int MaxTagSize = 32;
203 
204 //
205 // Diagnostic Tags
206 //
207 char PassTag[MaxTagSize];
208 char WarnTag[MaxTagSize];
209 char FailTag[MaxTagSize];
210 char WaitTag[MaxTagSize];
211 char YNTag[MaxTagSize];
212 char FatalTag[MaxTagSize];
213 
214 void setTags(bool bColor)
215 {
216  if( bColor )
217  {
218  sprintf(PassTag, "[" COLOR_PASS "PASS" COLOR_OFF "] ");
219  sprintf(WarnTag, "[" COLOR_WARN "WARN" COLOR_OFF "] ");
220  sprintf(FailTag, "[" COLOR_FAIL "FAIL" COLOR_OFF "] ");
221  sprintf(WaitTag, " ");
222  sprintf(YNTag, "[" COLOR_YN "y/n" COLOR_OFF "] ");
223  sprintf(FatalTag, "[" COLOR_FATAL "FATAL" COLOR_OFF"] ");
224  }
225  else
226  {
227  sprintf(PassTag, "[PASS] ");
228  sprintf(WarnTag, "[WARN] ");
229  sprintf(FailTag, "[FAIL] ");
230  sprintf(WaitTag, " ");
231  sprintf(YNTag, "[y/n] ");
232  sprintf(FatalTag, "[FATAL]");
233  }
234 }
235 
236 void printHdr(string strDiag)
237 {
238  printf("%s\n", DiagSep);
239  printf("%s\n", strDiag.c_str());
240  printf("%s\n\n", DiagSep);
241 }
242 
243 void printSubHdr(string strName)
244 {
245  //printf("%s\n", SubHdrSep);
246  printf("+ + %s + +\n", strName.c_str());
247 }
248 
249 void printTestResult(const char *sTag, const char *sFmt, ...)
250 {
251  va_list ap;
252 
253  va_start(ap, sFmt);
254  printf("%s ", sTag);
255  vprintf(sFmt, ap);
256  printf("\n");
257  va_end(ap);
258  fflush(stdout);
259 }
260 
261 void printSubTotals(DiagStats &stats)
262 {
263  printf("%s %d/%d passed.\n\n", SubSumTag, stats.passCnt, stats.testCnt);
264 }
265 
266 void printTotals(DiagStats &stats)
267 {
268  printf("%s %d/%d diagnostics passed.\n\n",
269  TotSumTag, stats.passCnt, stats.testCnt);
270 }
271 
272 void printGrandTotals(DiagStats &stats)
273 {
274  printf("%s\n", DiagSep);
275  printf("%s\n", DiagSep);
276  printf("Gran Total: %d/%d diagnostics passed.\n",
277  stats.passCnt, stats.testCnt);
278  printf("%s\n", DiagSep);
279  printf("%s\n", DiagSep);
280 }
281 
282 /*!
283  * \}
284  */
Diagnotics header file.
Simple diagnostics statistics class.
Definition: laelaps_diag.h:106