Use thermal zone x86_pkg_temp by default
[khatus.git] / x5 / khatus.c
CommitLineData
9b5ebc12
SK
1#include <assert.h>
2#include <ctype.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#define MAX_TOT_WIDTH 1024
8
9#define debug( args...) {fprintf(stderr, "[debug] " args);}
10#define error( args...) {fprintf(stderr, "[error] " args); errors++;}
11#define fatal(n, args...) {fprintf(stderr, "[fatal] " args); exit(n);}
12#define usage( args...) {print_usage(); fatal(1, "[usage] " args);}
13
14
15typedef struct file * File;
16
17struct file {
18 char * name;
19 int width;
20 int ttl;
21 File next;
22};
23
24struct options {
25 char * argv0;
26 int interval;
27 File files;
28} options = {
29 .argv0 = NULL,
30 .interval = 1,
31 .files = NULL
32};
33
34typedef struct options * Options;
35
36Options opts = &options;
37int errors = 0;
38
39
40int
41is_pos_num(char *s)
42{
43 while (*s != '\0')
44 if (!isdigit(*(s++)))
45 return 0;
46 return 1;
47}
48
49void
50print_usage()
51{
52 assert(opts->argv0);
53 fprintf(
54 stderr,
55 "\n"
56 "Usage: %s [OPTIONS ...] SPEC [SPEC ...]\n"
57 "\n"
58 "\tSPEC = FILE_PATH DATA_WIDTH DATA_TTL\n"
59 "\tFILE_PATH = string\n"
60 "\tDATA_WIDTH = int (* (positive) number of characters *)\n"
61 "\tDATA_TTL = int (* (positive) number of seconds *)\n"
62 "\tOPTION = -i INTERVAL\n"
63 "\tINTERVAL = int (* (positive) number of seconds *)\n"
64 "\n",
65 opts->argv0
66 );
67 fprintf(
68 stderr,
69 "Example: %s -i 1 /dev/shm/khatus/khatus_sensor_x 4 10\n"
70 "\n",
71 opts->argv0
72 );
73}
74
75void parse_opts(int, char *[], int); /* For mutually-recursive calls. */
76
77void
78parse_opts_opt_i(int argc, char *argv[], int i)
79{
80 if (i < argc) {
81 char *param = argv[i++];
82
83 if (is_pos_num(param)) {
84 opts->interval = atoi(param);
85 parse_opts(argc, argv, i);
86 } else {
87 usage("Option -i parameter is invalid: \"%s\"\n", param);
88 }
89 } else {
90 usage("Option -i parameter is missing.\n");
91 }
92}
93
94void
95parse_opts_opt(int argc, char *argv[], int i)
96{
97 switch (argv[i][1]) {
98 case 'i': parse_opts_opt_i(argc, argv, ++i); break; /* TODO: Generic set_int */
99 default : usage("Option \"%s\" is invalid\n", argv[i]);
100 }
101}
102
103void
104parse_opts_spec(int argc, char *argv[], int i)
105{
106 if ((i + 3) > argc)
107 usage("[spec] Parameter(s) missing for file \"%s\".\n", argv[i]);
108
109 char *n = argv[i++];
110 char *w = argv[i++];
111 char *t = argv[i++];
112
113 if (!is_pos_num(w))
114 usage("[spec] Invalid width: \"%s\", for file \"%s\"\n", w, n);
115 if (!is_pos_num(t))
116 usage("[spec] Invalid TTL: \"%s\", for file \"%s\"\n", t, n);
117 File f = malloc(sizeof(struct file));
118 if (f) {
119 f->name = n;
120 f->width = atoi(w);
121 f->ttl = atoi(t);
122 f->next = opts->files;
123 opts->files = f;
124 } else {
125 fatal(2, "[memory] Allocation failure.");
126 }
127 parse_opts(argc, argv, i);
128}
129
130void
131parse_opts(int argc, char *argv[], int i)
132{
133 if (i < argc) {
134 switch (argv[i][0]) {
135 case '-': parse_opts_opt(argc, argv, i); break;
136 default : parse_opts_spec(argc, argv, i);
137 }
138 }
139}
140
141int
142main(int argc, char **argv)
143{
144 opts->argv0 = argv[0];
145 parse_opts(argc, argv, 1);
146 assert(!errors);
147 debug("[options] argv0 = %s\n", opts->argv0);
148 debug("[options] interval = %d\n", opts->interval);
149 if (opts->files == NULL)
150 usage("No file specs were given!\n");
151 for (File f = opts->files; f; f = f->next) {
152 debug(
153 "[options] file = { name = %s, width = %d, ttl = %d }\n",
154 f->name,
155 f->width,
156 f->ttl
157 );
158 }
159}
This page took 0.044943 seconds and 4 git commands to generate.