Add support for cleanup functions
[bcusdk.git] / eibd / bcu / bcuread.cpp
blob958ded289a02e0993c258e51483c05c137e7a0ef
1 /*
2 EIBD eib bus access and management daemon
3 Copyright (C) 2005-2009 Martin Koegler <mkoegler@auto.tuwien.ac.at>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <argp.h>
24 #include "addrtab.h"
25 #include "lowlevelconf.h"
27 /** aborts program with a printf like message */
28 void
29 die (const char *msg, ...)
31 va_list ap;
32 va_start (ap, msg);
33 vprintf (msg, ap);
34 printf ("\n");
35 va_end (ap);
37 exit (1);
40 /** structure to store low level backends */
41 struct urldef
43 /** URL-prefix */
44 const char *prefix;
45 /** factory function */
46 LowLevel_Create_Func Create;
47 /** cleanup function */
48 void (*Cleanup) ();
51 /** list of URLs */
52 struct urldef URLs[] = {
53 #undef L2_NAME
54 #define L2_NAME(a) { a##_PREFIX, a##_CREATE, a##_CLEANUP },
55 #include "lowlevelcreate.h"
56 {0, 0, 0}
59 void (*Cleanup) ();
61 /** determines the right backend for the url and creates it */
62 LowLevelDriverInterface *
63 Create (const char *url, Trace * t)
65 unsigned int p = 0;
66 struct urldef *u = URLs;
67 while (url[p] && url[p] != ':')
68 p++;
69 if (url[p] != ':')
70 die ("not a valid url");
71 while (u->prefix)
73 if (strlen (u->prefix) == p && !memcmp (u->prefix, url, p))
75 Cleanup = u->Cleanup;
76 return u->Create (url + p + 1, t);
78 u++;
80 die ("url not supported");
81 return 0;
84 /** version */
85 const char *argp_program_version = "bcuread " VERSION;
86 /** documentation */
87 static char doc[] =
88 "bcuread -- read BCU memory\n"
89 "(C) 2005-2009 Martin Koegler <mkoegler@auto.tuwien.ac.at>\n"
90 "supported URLs are:\n"
91 #undef L2_NAME
92 #define L2_NAME(a) a##_URL
93 #include "lowlevelcreate.h"
94 "\n"
95 #undef L2_NAME
96 #define L2_NAME(a) a##_DOC
97 #include "lowlevelcreate.h"
98 "\n";
100 /** structure to store the arguments */
101 struct arguments
103 /** trace level */
104 int tracelevel;
106 /** storage for the arguments*/
107 struct arguments arg;
109 unsigned
110 readHex (const char *addr)
112 int i;
113 sscanf (addr, "%x", &i);
114 return i;
117 /** documentation for arguments*/
118 static char args_doc[] = "URL addr len";
120 /** option list */
121 static struct argp_option options[] = {
123 {"trace", 't', "LEVEL", 0, "set trace level"},
128 /** parses and stores an option */
129 static error_t
130 parse_opt (int key, char *arg, struct argp_state *state)
132 struct arguments *arguments = (struct arguments *) state->input;
133 switch (key)
135 case 't':
136 arguments->tracelevel = (arg ? atoi (arg) : 0);
137 break;
138 default:
139 return ARGP_ERR_UNKNOWN;
141 return 0;
144 /** information for the argument parser*/
145 static struct argp argp = { options, parse_opt, args_doc, doc };
149 main (int ac, char *ag[])
151 int addr;
152 int len;
153 int index;
154 CArray result;
155 LowLevelDriverInterface *iface = 0;
156 memset (&arg, 0, sizeof (arg));
158 argp_parse (&argp, ac, ag, 0, &index, &arg);
159 if (index > ac - 3)
160 die ("more parameter expected");
161 if (index < ac - 3)
162 die ("unexpected parameter");
164 signal (SIGPIPE, SIG_IGN);
165 pth_init ();
167 Trace t;
168 t.SetTraceLevel (arg.tracelevel);
170 iface = Create (ag[index], &t);
171 if (!iface->init ())
172 die ("initialisation failed");
174 addr = readHex (ag[index + 1]);
175 len = atoi (ag[index + 2]);
177 int res = readEMIMem (iface, addr, len, result);
178 if (!res)
180 printf ("Read failed");
182 else
184 for (int i = 0; i < result (); i++)
185 printf ("%02x ", result[i]);
186 printf ("\n");
189 delete iface;
190 if (Cleanup)
191 Cleanup ();
193 pth_exit (0);
194 return 0;