librnr  1.14.5
RoadNarrows Robotics Common Library 1
example_log.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Common Library 1
4 //
5 // File: example_log.c
6 //
7 /*! \file
8  *
9  * $LastChangedDate: 2012-10-31 09:53:31 -0600 (Wed, 31 Oct 2012) $
10  * $Rev: 2497 $
11  *
12  * \brief Example of librnr support for logging and command-line options
13  * processing.
14  *
15  * \author Robin Knight (robin.knight@roadnarrows.com)
16  *
17  * \pkgcopyright{2007-2018,RoadNarrows LLC.,http://www.roadnarrows.com}
18  */
19 // Permission is hereby granted, without written agreement and without
20 // license or royalty fees, to use, copy, modify, and distribute this
21 // software and its documentation for any purpose, provided that
22 // (1) The above copyright notice and the following two paragraphs
23 // appear in all copies of the source code and (2) redistributions
24 // including binaries reproduces these notices in the supporting
25 // documentation. Substantial modifications to this software may be
26 // copyrighted by their authors and need not follow the licensing terms
27 // described here, provided that the new terms are clearly indicated in
28 // all files where they apply.
29 //
30 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
31 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
32 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
33 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
34 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
35 // THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
38 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
39 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
40 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
41 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
42 //
43 ////////////////////////////////////////////////////////////////////////////////
44 
45 #include <stdio.h>
46 #include <string.h>
47 #include <libgen.h>
48 
49 #include "rnr/rnrconfig.h"
50 #include "rnr/log.h"
51 #include "rnr/opts.h"
52 
53 #include "version.h"
54 
55 //
56 // The command with option and argument values.
57 //
58 static char *Argv0; ///< the command
59 static int OptsTest = 1; ///< test option value
60 
61 /*!
62  * \brief Program information.
63  */
65 {
66  .synopsis = "Example of librnr logging and options processing facilities.",
67 
68  .long_desc =
69  "The %P command demonstrates various macros and functions of the "
70  "librnr logging facilities, plus command-line options processing."
71 };
72 
73 /*!
74  * \brief Command line options information.
75  */
77 {
78  // -t, --test <test>
79  {
80  .long_opt = "test",
81  .short_opt = 't',
82  .has_arg = required_argument,
83  .has_default= true,
84  .opt_addr = &OptsTest,
85  .fn_cvt = OptsCvtArgInt,
86  .fn_fmt = OptsFmtInt,
87  .arg_name = "<test>",
88  .opt_desc =
89  "Set the logging test(s) to conduct.\n"
90  "%A is one of:\n"
91  " 0 - No tests.\n"
92  " 1 - Test #1.\n"
93  " 2 - Test #2.\n"
94  " 3 - All tests."
95  },
96 
97  {NULL, }
98 };
99 
100 /*!
101  * \brief Log test number 1.
102  *
103  * \param p Void pointer.
104  * \param sFruit Character pointer.
105  * \param n Integer.
106  * \param half Short.
107  * \param f Double.
108  * \param hex Integer in hex.
109  * \param bAreRipe Boolean.
110  */
111 static void logtest_num1(void *p, const char *sFruit, int n, int half,
112  double f, int hex, bool_t bAreRipe)
113 {
114  // test log function call diagnostics 1
115  LOGDIAG1CALL(_TPTR(p), _TSTR(sFruit), _TINT(n), _TSHORT(half), _TFLOAT(f),
116  _THEX(hex), _TBOOL(bAreRipe));
117 
118  // test diagnostic 2 test
119  if( bAreRipe )
120  {
121  LOGDIAG2("There are %d juicy %s in %s", n, sFruit, "Tuscany");
122  }
123  else
124  {
125  LOGDIAG2("There are %d green %s in %s", n, sFruit, "Utah");
126  }
127 }
128 
129 /*!
130  * \brief Log test number 2.
131  *
132  * \param count Count.
133  */
134 static void logtest_num2(int count)
135 {
136  FILE *fp;
137  const char *sFileName = "PackingShedOnStrike.newsflash";
138 
139  // test log function call diagnostics 2
140  LOGDIAG2CALL(_TINT(count));
141 
142  LOGWARN("Ebola is your friend, Mr. %s.", "Sicko");
143 
144  // test error logging
145  while( count-- > 0 )
146  {
147  LOGERROR("Salmonella scare %d...", count);
148  }
149 
150  // test system error logging
151  if( (fp = fopen(sFileName, "r")) == NULL )
152  {
153  LOGSYSERROR("%s", sFileName);
154  }
155  else
156  {
157  LOGDIAG4("%s: what a pleasant surprise", sFileName);
158  fclose(fp);
159  }
160 }
161 
162 /*!
163  * \brief Run log test(s).
164  *
165  * \returns 1 on success, \h_gt 0 on failure.
166  */
167 static int runlogtests()
168 {
169  short h = 10;
170  int i = 12;
171 
172  switch( OptsTest )
173  {
174  case 0:
175  break;
176  case 1:
177  logtest_num1(&i, "apples", 53, h, 123.5, 0xdead, false);
178  break;
179  case 2:
180  logtest_num2(3);
181  break;
182  case 3:
183  logtest_num1(&h, "pears", 12, h, -1.5E-2, 0xf1, true);
184  logtest_num2(3);
185  break;
186  default:
187  LOGERROR("bug: %d: unexpected test", OptsTest);
188  return 0;
189  }
190  return 1;
191 }
192 
193 /*!
194  * \brief Main initialization.
195  *
196  * \param argc Command-line argument count.
197  * \param argv Command-line argument list.
198  *
199  * \return Returns 1 on success, exits on failure.
200  */
201 static int init(int argc, char *argv[])
202 {
203  FILE *fp;
204  int i;
205 
206  // name of this process
207  Argv0 = basename(argv[0]);
208 
209  // parse input options
210  argv = OptsGet(Argv0, &PkgInfo, &LogExamplePgmInfo, LogExampleOptsInfo, true,
211  &argc, argv);
212 
213  // test log helper macro
214  CHKEXPR_INT(OptsTest, ((OptsTest >= 0) || (OptsTest <= 3)), 0);
215 
216  // test complicated logging
217  if( LOGABLE(LOG_LEVEL_DIAG1) )
218  {
219  LOGDIAG1("Post options processed non-option arguments:");
220  fp = LOG_GET_LOGFP();
221  for(i=0; i<argc; ++i)
222  {
223  fprintf(fp, " argv[%d]=\"%s\"\n", i, argv[i]);
224  }
225  }
226 
227  return 1;
228 }
229 
230 /*!
231  * \brief Example main.
232  *
233  * \param argc Command-line argument count.
234  * \param argv Command-line argument list.
235  *
236  * \par Exit Status:
237  * Program exits with 0 success, \h_gt 0 on failure.
238  */
239 int main(int argc, char *argv[])
240 {
241  printf("arch : %s\n", ARCH);
242 
243  if( !init(argc, argv) )
244  {
245  return 3;
246  }
247 
248  return runlogtests()? 0: 4;
249 }
#define _THEX(var)
int (hex)
Definition: log.h:581
#define CHKEXPR_INT(val, expr,...)
check integer
Definition: log.h:688
#define _TINT(var)
int (decimal)
Definition: log.h:582
FILE * LOG_GET_LOGFP()
Get current logging output stream file pointer.
Definition: log.c:301
static OptsInfo_T LogExampleOptsInfo[]
Command line options information.
Definition: example_log.c:76
Standard command-line options options and parsing.
Program Description Strings Info Structure.
Definition: opts.h:226
int main(int argc, char *argv[])
Example main.
Definition: example_log.c:239
static void logtest_num2(int count)
Log test number 2.
Definition: example_log.c:134
char * OptsFmtInt(char *buf, size_t buflen, void *pOptVal)
Integer option value string formatter.
Definition: opts.c:1215
#define NULL
null pointer
Definition: rnrconfig.h:199
#define _TSHORT(var)
short int (decimal)
Definition: log.h:584
#define LOGDIAG1(fmt,...)
Standard Diagnostic Level 1 logging.
Definition: log.h:407
static int OptsTest
test option value
Definition: example_log.c:59
static void logtest_num1(void *p, const char *sFruit, int n, int half, double f, int hex, bool_t bAreRipe)
Log test number 1.
Definition: example_log.c:111
#define LOGSYSERROR(fmt,...)
Standard System Error logging.
Definition: log.h:509
const char * synopsis
Simple program synopsis string.
Definition: opts.h:240
#define LOGDIAG2(fmt,...)
Standard Diagnostic Level 2 logging.
Definition: log.h:400
#define LOGERROR(fmt,...)
Standard Error logging.
Definition: log.h:488
#define LOGABLE(level)
Test if given level is logable at current threshold.
Definition: log.h:195
int OptsCvtArgInt(const char *argv0, const char *sOptName, char *optarg, void *pOptVal)
Convert options integer argument to integer.
Definition: opts.c:1065
#define LOGWARN(fmt,...)
Standard Warning logging.
Definition: log.h:467
#define LOGDIAG4(fmt,...)
Standard Diagnostic Level 4 logging.
Definition: log.h:386
static int runlogtests()
Run log test(s).
Definition: example_log.c:167
static const PkgInfo_T PkgInfo
Definition: version.h:45
int bool_t
"boolean" T/F
Definition: rnrconfig.h:187
RoadNarrows Robotics common configuration file.
char ** OptsGet(const char *argv0, const PkgInfo_T *pPkgInfo, OptsPgmInfo_T *pPgmInfo, OptsInfo_T *pOptsInfo, bool_t bHasLogging, int *pargc, char *argv[])
Gets, validates, and sets all command line options.
Definition: opts.c:861
#define _TBOOL(var)
boolean
Definition: log.h:588
Package version information.
#define _TSTR(var)
string variable
Definition: log.h:578
#define LOG_LEVEL_DIAG1
diagnostic level 1
Definition: log.h:181
static OptsPgmInfo_T LogExamplePgmInfo
Program information.
Definition: example_log.c:64
#define _TPTR(var)
pointer
Definition: log.h:587
#define _TFLOAT(var)
float
Definition: log.h:586
static char * Argv0
the command
Definition: example_log.c:58
Logger declarations.
const char * long_opt
Long option string name.
Definition: opts.h:137
#define LOGDIAG2CALL(...)
Standard Diagnostic Level 2 function call tracing.
Definition: log.h:454
Short and Long Options Info.
Definition: opts.h:134
#define LOGDIAG1CALL(...)
Standard Diagnostic Level 1 function call tracing.
Definition: log.h:460
static int init(int argc, char *argv[])
Main initialization.
Definition: example_log.c:201