labcomm2006_private.h 16 KB
Newer Older
1
/*
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
2
  labcomm2006_private.h -- semi private declarations for handling encoding and 
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
                       decoding of labcomm samples.

  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>

  This file is part of LabComm.

  LabComm is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  LabComm is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _LABCOMM_PRIVATE_H_
#define _LABCOMM_PRIVATE_H_

#ifdef LABCOMM_COMPAT
  #include LABCOMM_COMPAT
#else
  #include <endian.h>
  #include <stdio.h>
Tommy Olofsson's avatar
Tommy Olofsson committed
31
32
  #include <stdint.h>
  #include <unistd.h>
33
34
35
36
#endif

//#include <stdlib.h>
#include <string.h>
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
37
#include "labcomm2006.h"
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

/*
 * Predeclared aggregate type indices
 */
#define LABCOMM_TYPEDEF  0x01
#define LABCOMM_SAMPLE   0x02
#define LABCOMM_ARRAY    0x10
#define LABCOMM_STRUCT   0x11

/*
 * Predeclared primitive type indices
 */
#define LABCOMM_BOOLEAN  0x20 
#define LABCOMM_BYTE     0x21
#define LABCOMM_SHORT    0x22
#define LABCOMM_INT      0x23
#define LABCOMM_LONG     0x24
#define LABCOMM_FLOAT    0x25
#define LABCOMM_DOUBLE   0x26
#define LABCOMM_STRING   0x27

/*
 * Start index for user defined types
 */
#define LABCOMM_USER     0x80

/*
 * Macro to automagically call constructors in modules compiled 
 * with the labcomm compiler. If __attribute__((constructor)) is
 * not supported, these calls has to be done first in main program.
 */
#ifndef LABCOMM_CONSTRUCTOR
#define LABCOMM_CONSTRUCTOR __attribute__((constructor))
#endif

/*
 * Semi private dynamic memory declarations
 */

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
77
78
79
struct labcomm2006_memory {
  void *(*alloc)(struct labcomm2006_memory *m, int lifetime, size_t size);
  void *(*realloc)(struct labcomm2006_memory *m, int lifetime, 
80
		   void *ptr, size_t size);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
81
  void (*free)(struct labcomm2006_memory *m, int lifetime, void *ptr);
82
83
84
85
86
87
  void *context;
};

/*
 * Semi private decoder declarations
 */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
88
typedef void (*labcomm2006_handler_function)(void *value, void *context);
89

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
90
91
92
typedef void (*labcomm2006_decoder_function)(
  struct labcomm2006_reader *r,
  labcomm2006_handler_function handler,
93
94
  void *context);

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
95
struct labcomm2006_reader_action_context;
96

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
97
98
struct labcomm2006_reader_action {
  /* 'alloc' is called at the first invocation of 'labcomm2006_decoder_decode_one' 
99
     on the decoder containing the reader.
100
101
102
103
104

     Returned value:
       >  0    Number of bytes allocated for buffering
       <= 0    Error
  */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
105
  int (*alloc)(struct labcomm2006_reader *r, 
106
	       struct labcomm2006_reader_action_context *action_context);
107
108
109
110
111
112
113
  /* 'free' returns the resources claimed by 'alloc' and might have other
     reader specific side-effects as well.

     Returned value:
       == 0    Success
       != 0    Error
  */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
114
115
  int (*free)(struct labcomm2006_reader *r, 
	      struct labcomm2006_reader_action_context *action_context);
116
117
118
119
120
121
122
123
  /* 'start' is called at the following instances:
     1. When a sample is registered 
          (local_index != 0, remote_index == 0, value == NULL)
     2. When a sample definition is received 
          (local_index != 0, remote_index != 0, value == NULL)
     3. When a sample is received
          (local_index != 0, remote_index != 0, value != NULL)
   */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
124
125
  int (*start)(struct labcomm2006_reader *r, 
	       struct labcomm2006_reader_action_context *action_context,
126
	       int local_index, int remote_index,
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
127
	       struct labcomm2006_signature *signature,
128
	       void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
129
130
131
132
133
134
  int (*end)(struct labcomm2006_reader *r, 
	     struct labcomm2006_reader_action_context *action_context);
  int (*fill)(struct labcomm2006_reader *r, 
	      struct labcomm2006_reader_action_context *action_context);
  int (*ioctl)(struct labcomm2006_reader *r, 
	       struct labcomm2006_reader_action_context *action_context,
135
	       int local_index, int remote_index,
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
136
	       struct labcomm2006_signature *signature, 
137
138
139
	       uint32_t ioctl_action, va_list args);
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
140
141
142
struct labcomm2006_reader_action_context {
  struct labcomm2006_reader_action_context *next;
  const struct labcomm2006_reader_action *action;
143
144
145
  void *context;  
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
146
147
148
149
150
struct labcomm2006_reader {
  struct labcomm2006_reader_action_context *action_context;
  struct labcomm2006_memory *memory;
  /* The following fields are initialized by labcomm2006_decoder_new */
  struct labcomm2006_decoder *decoder;
151
152
153
154
155
156
157
  unsigned char *data;
  int data_size;
  int count;
  int pos;
  int error;
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
158
int labcomm2006_reader_alloc(struct labcomm2006_reader *r, 
159
			 struct labcomm2006_reader_action_context *action_context);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
160
161
162
163
int labcomm2006_reader_free(struct labcomm2006_reader *r, 
			struct labcomm2006_reader_action_context *action_context);
int labcomm2006_reader_start(struct labcomm2006_reader *r, 
			 struct labcomm2006_reader_action_context *action_context,
164
			 int local_index, int remote_index,
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
165
			 struct labcomm2006_signature *signature,
166
			 void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
167
168
169
170
171
172
int labcomm2006_reader_end(struct labcomm2006_reader *r, 
		       struct labcomm2006_reader_action_context *action_context);
int labcomm2006_reader_fill(struct labcomm2006_reader *r, 
			struct labcomm2006_reader_action_context *action_context);
int labcomm2006_reader_ioctl(struct labcomm2006_reader *r, 
			 struct labcomm2006_reader_action_context *action_context,
173
			 int local_index, int remote_index,
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
174
			 struct labcomm2006_signature *signature, 
175
176
177
178
			 uint32_t ioctl_action, va_list args);

/*
 * Non typesafe registration function to be called from
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
179
 * generated labcomm2006_decoder_register_* functions.
180
 */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
181
182
183
184
185
int labcomm2006_internal_decoder_register(
  struct labcomm2006_decoder *d, 
  struct labcomm2006_signature *s, 
  labcomm2006_decoder_function decoder,
  labcomm2006_handler_function handler,
186
187
  void *context);

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
188
189
int labcomm2006_internal_decoder_ioctl(struct labcomm2006_decoder *decoder, 
				   struct labcomm2006_signature *signature,
190
191
192
193
194
				   uint32_t ioctl_action, va_list args);

#if __BYTE_ORDER == __LITTLE_ENDIAN

#define LABCOMM_DECODE(name, type)					\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
195
  static inline type labcomm2006_read_##name(struct labcomm2006_reader *r) {	\
196
197
198
    type result; int i;							\
    for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
      if (r->pos >= r->count) {						\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
199
	labcomm2006_reader_fill(r, r->action_context);			\
200
201
202
203
204
205
206
207
208
209
210
211
212
	if (r->error < 0) {						\
	  return 0;							\
	}								\
      }									\
      ((unsigned char*)(&result))[i] = r->data[r->pos];			\
      r->pos++;								\
    }									\
    return result;							\
  }

#else

#define LABCOMM_DECODE(name, type)					\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
213
  static inline type labcomm2006_read_##name(struct labcomm2006_reader *r) {	\
214
215
216
    type result; int i;							\
    for (i = 0 ; i < sizeof(type) ; i++) {				\
      if (r->pos >= r->count) {						\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
217
	labcomm2006_reader_fille(r, r->action_context);			\
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
	if (r->error < 0) {						\
	  return 0;							\
	}								\
      }									\
      ((unsigned char*)(&result))[i] = r->data[r->pos];			\
      r->pos++;								\
    }									\
    return result;							\
  }

#endif

LABCOMM_DECODE(boolean, unsigned char)
LABCOMM_DECODE(byte, unsigned char)
LABCOMM_DECODE(short, short)
LABCOMM_DECODE(int, int)
LABCOMM_DECODE(long, long long)
LABCOMM_DECODE(float, float)
LABCOMM_DECODE(double, double)

//compatibility with 2013 version
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
239
#define labcomm2006_read_packed32 labcomm2006_read_int
240
241

#if 0
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
242
static inline unsigned int labcomm2006_read_packed32(struct labcomm2006_reader *r)
243
244
245
246
247
248
249
{
  unsigned int result = 0;
  
  while (1) {
    unsigned char tmp;

    if (r->pos >= r->count) {	
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
250
      labcomm2006_reader_fill(r, r->action_context);
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
      if (r->error != 0) {
	goto out;
      }
    }
    tmp = r->data[r->pos];
    r->pos++;
    result = (result << 7) | (tmp & 0x7f);
    if ((tmp & 0x80) == 0) { 
      break; 
    }
  }
out:
  return result;
}
#endif 

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
267
static inline char *labcomm2006_read_string(struct labcomm2006_reader *r)
268
269
270
271
{
  char *result = NULL;
  int length, pos; 
  
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
272
273
  length = labcomm2006_read_packed32(r);
  result = labcomm2006_memory_alloc(r->memory, 1, length + 1);
274
275
  for (pos = 0 ; pos < length ; pos++) {
    if (r->pos >= r->count) {	
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
276
      labcomm2006_reader_fill(r, r->action_context);
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
      if (r->error < 0) {
	goto out;
      }
    }
    result[pos] = r->data[r->pos];
    r->pos++;
  }
out:
  result[pos] = 0;
  return result;
}

/*
 * Semi private encoder declarations
 */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
292
typedef int (*labcomm2006_encoder_function)(struct labcomm2006_writer *,
293
					void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
294
295
296
297
struct labcomm2006_writer_action_context;

struct labcomm2006_writer_action {
  int (*alloc)(struct labcomm2006_writer *w, 
298
	       struct labcomm2006_writer_action_context *action_context);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
299
300
  int (*free)(struct labcomm2006_writer *w, 
	      struct labcomm2006_writer_action_context *action_context);
301
302
303
304
305
306
307
308
309
  /* 'start' is called right before a sample is to be sent. In the 
     case of a sample or typedef, 'value' == NULL.

     Returned value:
       == 0          Success -> continue sending the sample
       == -EALREADY  Success -> silently skip sending the sample,
                                'end' will not be called
       < 0           Error
   */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
310
311
312
  int (*start)(struct labcomm2006_writer *w, 
	       struct labcomm2006_writer_action_context *action_context,
	       int index, struct labcomm2006_signature *signature,
313
	       void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
314
315
316
317
318
319
320
  int (*end)(struct labcomm2006_writer *w, 
	     struct labcomm2006_writer_action_context *action_context);
  int (*flush)(struct labcomm2006_writer *w, 
	       struct labcomm2006_writer_action_context *action_context); 
  int (*ioctl)(struct labcomm2006_writer *w, 
	       struct labcomm2006_writer_action_context *action_context, 
	       int index, struct labcomm2006_signature *signature, 
321
322
323
	       uint32_t ioctl_action, va_list args);
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
324
325
326
struct labcomm2006_writer_action_context {
  struct labcomm2006_writer_action_context *next;
  const struct labcomm2006_writer_action *action;
327
328
329
  void *context;  
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
330
331
332
333
334
struct labcomm2006_writer {
  struct labcomm2006_writer_action_context *action_context;
  struct labcomm2006_memory *memory;
  /* The following fields are initialized by labcomm2006_encoder_new */
  struct labcomm2006_encoder *encoder;
335
336
337
338
339
340
341
  unsigned char *data;
  int data_size;
  int count;
  int pos;
  int error;
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
342
int labcomm2006_writer_alloc(struct labcomm2006_writer *w, 
343
			 struct labcomm2006_writer_action_context *action_context);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
344
345
346
347
348
int labcomm2006_writer_free(struct labcomm2006_writer *w, 
			struct labcomm2006_writer_action_context *action_context);
int labcomm2006_writer_start(struct labcomm2006_writer *w, 
			 struct labcomm2006_writer_action_context *action_context,
			 int index, struct labcomm2006_signature *signature,
349
			 void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
350
351
352
353
354
355
356
int labcomm2006_writer_end(struct labcomm2006_writer *w, 
		       struct labcomm2006_writer_action_context *action_context);
int labcomm2006_writer_flush(struct labcomm2006_writer *w, 
			 struct labcomm2006_writer_action_context *action_context); 
int labcomm2006_writer_ioctl(struct labcomm2006_writer *w, 
			 struct labcomm2006_writer_action_context *action_context, 
			 int index, struct labcomm2006_signature *signature, 
357
358
			 uint32_t ioctl_action, va_list args);

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
359
360
361
362
int labcomm2006_internal_encoder_register(
  struct labcomm2006_encoder *encoder, 
  struct labcomm2006_signature *signature, 
  labcomm2006_encoder_function encode);
363

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
364
365
366
367
int labcomm2006_internal_encode(
  struct labcomm2006_encoder *encoder, 
  struct labcomm2006_signature *signature, 
  labcomm2006_encoder_function encode,
368
369
  void *value);

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
370
371
int labcomm2006_internal_encoder_ioctl(struct labcomm2006_encoder *encoder, 
				   struct labcomm2006_signature *signature,
372
373
				   uint32_t ioctl_action, va_list args);

Anders Blomdell's avatar
Anders Blomdell committed
374
375
376
int labcomm2006_internal_sizeof(struct labcomm2006_signature *signature,
                                void *v);

377
378
379
#if __BYTE_ORDER == __LITTLE_ENDIAN

#define LABCOMM_ENCODE(name, type)					\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
380
  static inline int labcomm2006_write_##name(struct labcomm2006_writer *w, type data) { \
381
382
383
384
    int i;								\
    for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
      if (w->pos >= w->count) { /*buffer is full*/			\
        int err;							\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
385
	err = labcomm2006_writer_flush(w, w->action_context);		\
386
387
388
389
390
391
392
393
394
395
396
	if (err != 0) { return err; }					\
      }									\
      w->data[w->pos] = ((unsigned char*)(&data))[i];			\
      w->pos++;								\
    }									\
    return 0;								\
  }

#else

#define LABCOMM_ENCODE(name, type)					\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
397
  static inline int labcomm2006_write_##name(struct labcomm2006_writer *w, type data) { \
398
399
400
401
    int i;								\
    for (i = 0 ; i < sizeof(type) ; i++) {				\
      if (w->pos >= w->count) {						\
        int err;							\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
402
	err = labcomm2006_writer_flush(w, w->action_context);		\
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
	if (err != 0) { return err; }					\
      }									\
      w->data[w->pos] = ((unsigned char*)(&data))[i];			\
      w->pos++;								\
    }									\
    return 0;								\
  }

#endif

LABCOMM_ENCODE(boolean, unsigned char)
LABCOMM_ENCODE(byte, unsigned char)
LABCOMM_ENCODE(short, short)
LABCOMM_ENCODE(int, int)
LABCOMM_ENCODE(long, long long)
LABCOMM_ENCODE(float, float)
LABCOMM_ENCODE(double, double)

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
421
#define labcomm2006_write_packed32 labcomm2006_write_int
422
423

#if 0
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
424
static inline int labcomm2006_write_packed32(struct labcomm2006_writer *w, 
425
426
427
428
429
430
431
432
433
434
435
					 unsigned int data)
{
  unsigned char tmp[5];
  int i;
  
  for (i = 0 ; i == 0 || data ; i++, data = (data >> 7)) {
    tmp[i] = data & 0x7f;
  }
  for (i = i - 1 ; i >= 0 ; i--) {
    if (w->pos >= w->count) {					
      int err;
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
436
      err = labcomm2006_writer_flush(w, w->action_context);	
437
438
439
440
441
442
443
444
      if (err != 0) { return err; }
    }
    w->data[w->pos++] = tmp[i] | (i?0x80:0x00);
  }
  return 0;
}
#endif

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
445
static inline int labcomm2006_write_string(struct labcomm2006_writer *w, char *s)
446
447
448
449
{
  int length, i, err; 

  length = strlen((char*)s);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
450
  err = labcomm2006_write_packed32(w, length);
451
452
453
454
  if (err != 0) { return err; }
  for (i = 0 ; i < length ; i++) {
    if (w->pos >= w->count) {	
      int err;
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
455
      err = labcomm2006_writer_flush(w, w->action_context);	
456
457
458
459
460
461
462
463
464
      if (err != 0) { return err; }
    }
    w->data[w->pos] = s[i];
    w->pos++;
  }
  return 0;
}

/* Size of packed32 variable is 4 as we use int*/
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
465
static inline int labcomm2006_size_packed32(unsigned int data)
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
{
  return 4;
}

/*
 * Macros for handling arrays indexed by signature index
 */

#define LABCOMM_SIGNATURE_ARRAY_DEF(name, kind)	\
  struct {					\
    int first;					\
    int last;					\
    kind *data;					\
  } name

#define LABCOMM_SIGNATURE_ARRAY_DEF_INIT(name, kind)		\
  LABCOMM_SIGNATURE_ARRAY_DEF(name, kind) = { 0, 0, NULL }

#define LABCOMM_SIGNATURE_ARRAY_INIT(name, kind)		\
  name.first = 0; name.last = 0; name.data = NULL;		\
  name.data = (kind *)name.data; /* typechecking no-op */

#define LABCOMM_SIGNATURE_ARRAY_FREE(memory, name, kind)	\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
489
  if (name.data) { labcomm2006_memory_free(memory, 0, name.data); }	\
490
491
  name.data = (kind *)NULL; /* typechecking */

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
492
void *labcomm2006_signature_array_ref(struct labcomm2006_memory * memory,
493
494
495
496
497
498
499
500
501
502
503
				  int *first, int *last, void **data,
				  int size, int index);
/*
 * NB: the pointer returned by LABCOMM_SIGNATURE_ARRAY_REF might be
 *     rendered invalid by a subsequent call to LABCOMM_SIGNATURE_ARRAY_REF
 *     on the same SIGNATURE_ARRAY, so make sure not to use the result if 
 *     any other code might have made a call to LABCOMM_SIGNATURE_ARRAY_REF
 *     on the same SIGNATURE_ARRAY.
 */
#define LABCOMM_SIGNATURE_ARRAY_REF(memory, name, kind, index)		\
  (name.data = (kind *)name.data, /* typechecking no-op */		\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
504
   (kind *)(labcomm2006_signature_array_ref(memory,				\
505
506
507
508
509
510
511
512
513
					&name.first, &name.last,	\
					(void **)&name.data,		\
					sizeof(kind), index)))

#define LABCOMM_SIGNATURE_ARRAY_FOREACH(name, kind, var)		\
  for (name.data = (kind *)name.data, /* typechecking no-op */		\
       var = name.first ; var < name.last ; var++)

/* Give signature a free local index, this may not be used concurrently */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
514
void labcomm2006_set_local_index(struct labcomm2006_signature *signature);
515
516

/* Get the local index for a signature */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
517
int labcomm2006_get_local_index(struct labcomm2006_signature *s);
518
519

#endif