Home | History | Annotate | Line # | Download | only in radeon
mkregtable.c revision 1.1
      1 /* utility to create the register check tables
      2  * this includes inlined list.h safe for userspace.
      3  *
      4  * Copyright 2009 Jerome Glisse
      5  * Copyright 2009 Red Hat Inc.
      6  *
      7  * Authors:
      8  * 	Jerome Glisse
      9  * 	Dave Airlie
     10  */
     11 
     12 #include <sys/types.h>
     13 #include <stdlib.h>
     14 #include <string.h>
     15 #include <stdio.h>
     16 #include <regex.h>
     17 #include <libgen.h>
     18 
     19 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
     20 /**
     21  * container_of - cast a member of a structure out to the containing structure
     22  * @ptr:    the pointer to the member.
     23  * @type:   the type of the container struct this is embedded in.
     24  * @member: the name of the member within the struct.
     25  *
     26  */
     27 #define container_of(ptr, type, member) ({          \
     28 	const typeof(((type *)0)->member)*__mptr = (ptr);    \
     29 		     (type *)((char *)__mptr - offsetof(type, member)); })
     30 
     31 /*
     32  * Simple doubly linked list implementation.
     33  *
     34  * Some of the internal functions ("__xxx") are useful when
     35  * manipulating whole lists rather than single entries, as
     36  * sometimes we already know the next/prev entries and we can
     37  * generate better code by using them directly rather than
     38  * using the generic single-entry routines.
     39  */
     40 
     41 struct list_head {
     42 	struct list_head *next, *prev;
     43 };
     44 
     45 #define LIST_HEAD_INIT(name) { &(name), &(name) }
     46 
     47 #define LIST_HEAD(name) \
     48 	struct list_head name = LIST_HEAD_INIT(name)
     49 
     50 static inline void INIT_LIST_HEAD(struct list_head *list)
     51 {
     52 	list->next = list;
     53 	list->prev = list;
     54 }
     55 
     56 /*
     57  * Insert a new entry between two known consecutive entries.
     58  *
     59  * This is only for internal list manipulation where we know
     60  * the prev/next entries already!
     61  */
     62 #ifndef CONFIG_DEBUG_LIST
     63 static inline void __list_add(struct list_head *new,
     64 			      struct list_head *prev, struct list_head *next)
     65 {
     66 	next->prev = new;
     67 	new->next = next;
     68 	new->prev = prev;
     69 	prev->next = new;
     70 }
     71 #else
     72 extern void __list_add(struct list_head *new,
     73 		       struct list_head *prev, struct list_head *next);
     74 #endif
     75 
     76 /**
     77  * list_add - add a new entry
     78  * @new: new entry to be added
     79  * @head: list head to add it after
     80  *
     81  * Insert a new entry after the specified head.
     82  * This is good for implementing stacks.
     83  */
     84 static inline void list_add(struct list_head *new, struct list_head *head)
     85 {
     86 	__list_add(new, head, head->next);
     87 }
     88 
     89 /**
     90  * list_add_tail - add a new entry
     91  * @new: new entry to be added
     92  * @head: list head to add it before
     93  *
     94  * Insert a new entry before the specified head.
     95  * This is useful for implementing queues.
     96  */
     97 static inline void list_add_tail(struct list_head *new, struct list_head *head)
     98 {
     99 	__list_add(new, head->prev, head);
    100 }
    101 
    102 /*
    103  * Delete a list entry by making the prev/next entries
    104  * point to each other.
    105  *
    106  * This is only for internal list manipulation where we know
    107  * the prev/next entries already!
    108  */
    109 static inline void __list_del(struct list_head *prev, struct list_head *next)
    110 {
    111 	next->prev = prev;
    112 	prev->next = next;
    113 }
    114 
    115 /**
    116  * list_del - deletes entry from list.
    117  * @entry: the element to delete from the list.
    118  * Note: list_empty() on entry does not return true after this, the entry is
    119  * in an undefined state.
    120  */
    121 #ifndef CONFIG_DEBUG_LIST
    122 static inline void list_del(struct list_head *entry)
    123 {
    124 	__list_del(entry->prev, entry->next);
    125 	entry->next = (void *)0xDEADBEEF;
    126 	entry->prev = (void *)0xBEEFDEAD;
    127 }
    128 #else
    129 extern void list_del(struct list_head *entry);
    130 #endif
    131 
    132 /**
    133  * list_replace - replace old entry by new one
    134  * @old : the element to be replaced
    135  * @new : the new element to insert
    136  *
    137  * If @old was empty, it will be overwritten.
    138  */
    139 static inline void list_replace(struct list_head *old, struct list_head *new)
    140 {
    141 	new->next = old->next;
    142 	new->next->prev = new;
    143 	new->prev = old->prev;
    144 	new->prev->next = new;
    145 }
    146 
    147 static inline void list_replace_init(struct list_head *old,
    148 				     struct list_head *new)
    149 {
    150 	list_replace(old, new);
    151 	INIT_LIST_HEAD(old);
    152 }
    153 
    154 /**
    155  * list_del_init - deletes entry from list and reinitialize it.
    156  * @entry: the element to delete from the list.
    157  */
    158 static inline void list_del_init(struct list_head *entry)
    159 {
    160 	__list_del(entry->prev, entry->next);
    161 	INIT_LIST_HEAD(entry);
    162 }
    163 
    164 /**
    165  * list_move - delete from one list and add as another's head
    166  * @list: the entry to move
    167  * @head: the head that will precede our entry
    168  */
    169 static inline void list_move(struct list_head *list, struct list_head *head)
    170 {
    171 	__list_del(list->prev, list->next);
    172 	list_add(list, head);
    173 }
    174 
    175 /**
    176  * list_move_tail - delete from one list and add as another's tail
    177  * @list: the entry to move
    178  * @head: the head that will follow our entry
    179  */
    180 static inline void list_move_tail(struct list_head *list,
    181 				  struct list_head *head)
    182 {
    183 	__list_del(list->prev, list->next);
    184 	list_add_tail(list, head);
    185 }
    186 
    187 /**
    188  * list_is_last - tests whether @list is the last entry in list @head
    189  * @list: the entry to test
    190  * @head: the head of the list
    191  */
    192 static inline int list_is_last(const struct list_head *list,
    193 			       const struct list_head *head)
    194 {
    195 	return list->next == head;
    196 }
    197 
    198 /**
    199  * list_empty - tests whether a list is empty
    200  * @head: the list to test.
    201  */
    202 static inline int list_empty(const struct list_head *head)
    203 {
    204 	return head->next == head;
    205 }
    206 
    207 /**
    208  * list_empty_careful - tests whether a list is empty and not being modified
    209  * @head: the list to test
    210  *
    211  * Description:
    212  * tests whether a list is empty _and_ checks that no other CPU might be
    213  * in the process of modifying either member (next or prev)
    214  *
    215  * NOTE: using list_empty_careful() without synchronization
    216  * can only be safe if the only activity that can happen
    217  * to the list entry is list_del_init(). Eg. it cannot be used
    218  * if another CPU could re-list_add() it.
    219  */
    220 static inline int list_empty_careful(const struct list_head *head)
    221 {
    222 	struct list_head *next = head->next;
    223 	return (next == head) && (next == head->prev);
    224 }
    225 
    226 /**
    227  * list_is_singular - tests whether a list has just one entry.
    228  * @head: the list to test.
    229  */
    230 static inline int list_is_singular(const struct list_head *head)
    231 {
    232 	return !list_empty(head) && (head->next == head->prev);
    233 }
    234 
    235 static inline void __list_cut_position(struct list_head *list,
    236 				       struct list_head *head,
    237 				       struct list_head *entry)
    238 {
    239 	struct list_head *new_first = entry->next;
    240 	list->next = head->next;
    241 	list->next->prev = list;
    242 	list->prev = entry;
    243 	entry->next = list;
    244 	head->next = new_first;
    245 	new_first->prev = head;
    246 }
    247 
    248 /**
    249  * list_cut_position - cut a list into two
    250  * @list: a new list to add all removed entries
    251  * @head: a list with entries
    252  * @entry: an entry within head, could be the head itself
    253  *	and if so we won't cut the list
    254  *
    255  * This helper moves the initial part of @head, up to and
    256  * including @entry, from @head to @list. You should
    257  * pass on @entry an element you know is on @head. @list
    258  * should be an empty list or a list you do not care about
    259  * losing its data.
    260  *
    261  */
    262 static inline void list_cut_position(struct list_head *list,
    263 				     struct list_head *head,
    264 				     struct list_head *entry)
    265 {
    266 	if (list_empty(head))
    267 		return;
    268 	if (list_is_singular(head) && (head->next != entry && head != entry))
    269 		return;
    270 	if (entry == head)
    271 		INIT_LIST_HEAD(list);
    272 	else
    273 		__list_cut_position(list, head, entry);
    274 }
    275 
    276 static inline void __list_splice(const struct list_head *list,
    277 				 struct list_head *prev, struct list_head *next)
    278 {
    279 	struct list_head *first = list->next;
    280 	struct list_head *last = list->prev;
    281 
    282 	first->prev = prev;
    283 	prev->next = first;
    284 
    285 	last->next = next;
    286 	next->prev = last;
    287 }
    288 
    289 /**
    290  * list_splice - join two lists, this is designed for stacks
    291  * @list: the new list to add.
    292  * @head: the place to add it in the first list.
    293  */
    294 static inline void list_splice(const struct list_head *list,
    295 			       struct list_head *head)
    296 {
    297 	if (!list_empty(list))
    298 		__list_splice(list, head, head->next);
    299 }
    300 
    301 /**
    302  * list_splice_tail - join two lists, each list being a queue
    303  * @list: the new list to add.
    304  * @head: the place to add it in the first list.
    305  */
    306 static inline void list_splice_tail(struct list_head *list,
    307 				    struct list_head *head)
    308 {
    309 	if (!list_empty(list))
    310 		__list_splice(list, head->prev, head);
    311 }
    312 
    313 /**
    314  * list_splice_init - join two lists and reinitialise the emptied list.
    315  * @list: the new list to add.
    316  * @head: the place to add it in the first list.
    317  *
    318  * The list at @list is reinitialised
    319  */
    320 static inline void list_splice_init(struct list_head *list,
    321 				    struct list_head *head)
    322 {
    323 	if (!list_empty(list)) {
    324 		__list_splice(list, head, head->next);
    325 		INIT_LIST_HEAD(list);
    326 	}
    327 }
    328 
    329 /**
    330  * list_splice_tail_init - join two lists and reinitialise the emptied list
    331  * @list: the new list to add.
    332  * @head: the place to add it in the first list.
    333  *
    334  * Each of the lists is a queue.
    335  * The list at @list is reinitialised
    336  */
    337 static inline void list_splice_tail_init(struct list_head *list,
    338 					 struct list_head *head)
    339 {
    340 	if (!list_empty(list)) {
    341 		__list_splice(list, head->prev, head);
    342 		INIT_LIST_HEAD(list);
    343 	}
    344 }
    345 
    346 /**
    347  * list_entry - get the struct for this entry
    348  * @ptr:	the &struct list_head pointer.
    349  * @type:	the type of the struct this is embedded in.
    350  * @member:	the name of the list_struct within the struct.
    351  */
    352 #define list_entry(ptr, type, member) \
    353 	container_of(ptr, type, member)
    354 
    355 /**
    356  * list_first_entry - get the first element from a list
    357  * @ptr:	the list head to take the element from.
    358  * @type:	the type of the struct this is embedded in.
    359  * @member:	the name of the list_struct within the struct.
    360  *
    361  * Note, that list is expected to be not empty.
    362  */
    363 #define list_first_entry(ptr, type, member) \
    364 	list_entry((ptr)->next, type, member)
    365 
    366 /**
    367  * list_for_each	-	iterate over a list
    368  * @pos:	the &struct list_head to use as a loop cursor.
    369  * @head:	the head for your list.
    370  */
    371 #define list_for_each(pos, head) \
    372 	for (pos = (head)->next; prefetch(pos->next), pos != (head); \
    373 		pos = pos->next)
    374 
    375 /**
    376  * list_for_each_prev	-	iterate over a list backwards
    377  * @pos:	the &struct list_head to use as a loop cursor.
    378  * @head:	the head for your list.
    379  */
    380 #define list_for_each_prev(pos, head) \
    381 	for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
    382 		pos = pos->prev)
    383 
    384 /**
    385  * list_for_each_safe - iterate over a list safe against removal of list entry
    386  * @pos:	the &struct list_head to use as a loop cursor.
    387  * @n:		another &struct list_head to use as temporary storage
    388  * @head:	the head for your list.
    389  */
    390 #define list_for_each_safe(pos, n, head) \
    391 	for (pos = (head)->next, n = pos->next; pos != (head); \
    392 		pos = n, n = pos->next)
    393 
    394 /**
    395  * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
    396  * @pos:	the &struct list_head to use as a loop cursor.
    397  * @n:		another &struct list_head to use as temporary storage
    398  * @head:	the head for your list.
    399  */
    400 #define list_for_each_prev_safe(pos, n, head) \
    401 	for (pos = (head)->prev, n = pos->prev; \
    402 	     prefetch(pos->prev), pos != (head); \
    403 	     pos = n, n = pos->prev)
    404 
    405 /**
    406  * list_for_each_entry	-	iterate over list of given type
    407  * @pos:	the type * to use as a loop cursor.
    408  * @head:	the head for your list.
    409  * @member:	the name of the list_struct within the struct.
    410  */
    411 #define list_for_each_entry(pos, head, member)				\
    412 	for (pos = list_entry((head)->next, typeof(*pos), member);	\
    413 	     &pos->member != (head); 	\
    414 	     pos = list_entry(pos->member.next, typeof(*pos), member))
    415 
    416 /**
    417  * list_for_each_entry_reverse - iterate backwards over list of given type.
    418  * @pos:	the type * to use as a loop cursor.
    419  * @head:	the head for your list.
    420  * @member:	the name of the list_struct within the struct.
    421  */
    422 #define list_for_each_entry_reverse(pos, head, member)			\
    423 	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
    424 	     prefetch(pos->member.prev), &pos->member != (head); 	\
    425 	     pos = list_entry(pos->member.prev, typeof(*pos), member))
    426 
    427 /**
    428  * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
    429  * @pos:	the type * to use as a start point
    430  * @head:	the head of the list
    431  * @member:	the name of the list_struct within the struct.
    432  *
    433  * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
    434  */
    435 #define list_prepare_entry(pos, head, member) \
    436 	((pos) ? : list_entry(head, typeof(*pos), member))
    437 
    438 /**
    439  * list_for_each_entry_continue - continue iteration over list of given type
    440  * @pos:	the type * to use as a loop cursor.
    441  * @head:	the head for your list.
    442  * @member:	the name of the list_struct within the struct.
    443  *
    444  * Continue to iterate over list of given type, continuing after
    445  * the current position.
    446  */
    447 #define list_for_each_entry_continue(pos, head, member) 		\
    448 	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
    449 	     prefetch(pos->member.next), &pos->member != (head);	\
    450 	     pos = list_entry(pos->member.next, typeof(*pos), member))
    451 
    452 /**
    453  * list_for_each_entry_continue_reverse - iterate backwards from the given point
    454  * @pos:	the type * to use as a loop cursor.
    455  * @head:	the head for your list.
    456  * @member:	the name of the list_struct within the struct.
    457  *
    458  * Start to iterate over list of given type backwards, continuing after
    459  * the current position.
    460  */
    461 #define list_for_each_entry_continue_reverse(pos, head, member)		\
    462 	for (pos = list_entry(pos->member.prev, typeof(*pos), member);	\
    463 	     prefetch(pos->member.prev), &pos->member != (head);	\
    464 	     pos = list_entry(pos->member.prev, typeof(*pos), member))
    465 
    466 /**
    467  * list_for_each_entry_from - iterate over list of given type from the current point
    468  * @pos:	the type * to use as a loop cursor.
    469  * @head:	the head for your list.
    470  * @member:	the name of the list_struct within the struct.
    471  *
    472  * Iterate over list of given type, continuing from current position.
    473  */
    474 #define list_for_each_entry_from(pos, head, member) 			\
    475 	for (; prefetch(pos->member.next), &pos->member != (head);	\
    476 	     pos = list_entry(pos->member.next, typeof(*pos), member))
    477 
    478 /**
    479  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
    480  * @pos:	the type * to use as a loop cursor.
    481  * @n:		another type * to use as temporary storage
    482  * @head:	the head for your list.
    483  * @member:	the name of the list_struct within the struct.
    484  */
    485 #define list_for_each_entry_safe(pos, n, head, member)			\
    486 	for (pos = list_entry((head)->next, typeof(*pos), member),	\
    487 		n = list_entry(pos->member.next, typeof(*pos), member);	\
    488 	     &pos->member != (head); 					\
    489 	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
    490 
    491 /**
    492  * list_for_each_entry_safe_continue
    493  * @pos:	the type * to use as a loop cursor.
    494  * @n:		another type * to use as temporary storage
    495  * @head:	the head for your list.
    496  * @member:	the name of the list_struct within the struct.
    497  *
    498  * Iterate over list of given type, continuing after current point,
    499  * safe against removal of list entry.
    500  */
    501 #define list_for_each_entry_safe_continue(pos, n, head, member) 		\
    502 	for (pos = list_entry(pos->member.next, typeof(*pos), member), 		\
    503 		n = list_entry(pos->member.next, typeof(*pos), member);		\
    504 	     &pos->member != (head);						\
    505 	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
    506 
    507 /**
    508  * list_for_each_entry_safe_from
    509  * @pos:	the type * to use as a loop cursor.
    510  * @n:		another type * to use as temporary storage
    511  * @head:	the head for your list.
    512  * @member:	the name of the list_struct within the struct.
    513  *
    514  * Iterate over list of given type from current point, safe against
    515  * removal of list entry.
    516  */
    517 #define list_for_each_entry_safe_from(pos, n, head, member) 			\
    518 	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
    519 	     &pos->member != (head);						\
    520 	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
    521 
    522 /**
    523  * list_for_each_entry_safe_reverse
    524  * @pos:	the type * to use as a loop cursor.
    525  * @n:		another type * to use as temporary storage
    526  * @head:	the head for your list.
    527  * @member:	the name of the list_struct within the struct.
    528  *
    529  * Iterate backwards over list of given type, safe against removal
    530  * of list entry.
    531  */
    532 #define list_for_each_entry_safe_reverse(pos, n, head, member)		\
    533 	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
    534 		n = list_entry(pos->member.prev, typeof(*pos), member);	\
    535 	     &pos->member != (head); 					\
    536 	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
    537 
    538 struct offset {
    539 	struct list_head list;
    540 	unsigned offset;
    541 };
    542 
    543 struct table {
    544 	struct list_head offsets;
    545 	unsigned offset_max;
    546 	unsigned nentry;
    547 	unsigned *table;
    548 	char *gpu_prefix;
    549 };
    550 
    551 static struct offset *offset_new(unsigned o)
    552 {
    553 	struct offset *offset;
    554 
    555 	offset = (struct offset *)malloc(sizeof(struct offset));
    556 	if (offset) {
    557 		INIT_LIST_HEAD(&offset->list);
    558 		offset->offset = o;
    559 	}
    560 	return offset;
    561 }
    562 
    563 static void table_offset_add(struct table *t, struct offset *offset)
    564 {
    565 	list_add_tail(&offset->list, &t->offsets);
    566 }
    567 
    568 static void table_init(struct table *t)
    569 {
    570 	INIT_LIST_HEAD(&t->offsets);
    571 	t->offset_max = 0;
    572 	t->nentry = 0;
    573 	t->table = NULL;
    574 }
    575 
    576 static void table_print(struct table *t)
    577 {
    578 	unsigned nlloop, i, j, n, c, id;
    579 
    580 	nlloop = (t->nentry + 3) / 4;
    581 	c = t->nentry;
    582 	printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
    583 	       t->nentry);
    584 	for (i = 0, id = 0; i < nlloop; i++) {
    585 		n = 4;
    586 		if (n > c)
    587 			n = c;
    588 		c -= n;
    589 		for (j = 0; j < n; j++) {
    590 			if (j == 0)
    591 				printf("\t");
    592 			else
    593 				printf(" ");
    594 			printf("0x%08X,", t->table[id++]);
    595 		}
    596 		printf("\n");
    597 	}
    598 	printf("};\n");
    599 }
    600 
    601 static int table_build(struct table *t)
    602 {
    603 	struct offset *offset;
    604 	unsigned i, m;
    605 
    606 	t->nentry = ((t->offset_max >> 2) + 31) / 32;
    607 	t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
    608 	if (t->table == NULL)
    609 		return -1;
    610 	memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
    611 	list_for_each_entry(offset, &t->offsets, list) {
    612 		i = (offset->offset >> 2) / 32;
    613 		m = (offset->offset >> 2) & 31;
    614 		m = 1 << m;
    615 		t->table[i] ^= m;
    616 	}
    617 	return 0;
    618 }
    619 
    620 static char gpu_name[10];
    621 static int parser_auth(struct table *t, const char *filename)
    622 {
    623 	FILE *file;
    624 	regex_t mask_rex;
    625 	regmatch_t match[4];
    626 	char buf[1024];
    627 	size_t end;
    628 	int len;
    629 	int done = 0;
    630 	int r;
    631 	unsigned o;
    632 	struct offset *offset;
    633 	char last_reg_s[10];
    634 	int last_reg;
    635 
    636 	if (regcomp
    637 	    (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
    638 		fprintf(stderr, "Failed to compile regular expression\n");
    639 		return -1;
    640 	}
    641 	file = fopen(filename, "r");
    642 	if (file == NULL) {
    643 		fprintf(stderr, "Failed to open: %s\n", filename);
    644 		return -1;
    645 	}
    646 	fseek(file, 0, SEEK_END);
    647 	end = ftell(file);
    648 	fseek(file, 0, SEEK_SET);
    649 
    650 	/* get header */
    651 	if (fgets(buf, 1024, file) == NULL) {
    652 		fclose(file);
    653 		return -1;
    654 	}
    655 
    656 	/* first line will contain the last register
    657 	 * and gpu name */
    658 	sscanf(buf, "%9s %9s", gpu_name, last_reg_s);
    659 	t->gpu_prefix = gpu_name;
    660 	last_reg = strtol(last_reg_s, NULL, 16);
    661 
    662 	do {
    663 		if (fgets(buf, 1024, file) == NULL) {
    664 			fclose(file);
    665 			return -1;
    666 		}
    667 		len = strlen(buf);
    668 		if (ftell(file) == end)
    669 			done = 1;
    670 		if (len) {
    671 			r = regexec(&mask_rex, buf, 4, match, 0);
    672 			if (r == REG_NOMATCH) {
    673 			} else if (r) {
    674 				fprintf(stderr,
    675 					"Error matching regular expression %d in %s\n",
    676 					r, filename);
    677 				fclose(file);
    678 				return -1;
    679 			} else {
    680 				buf[match[0].rm_eo] = 0;
    681 				buf[match[1].rm_eo] = 0;
    682 				buf[match[2].rm_eo] = 0;
    683 				o = strtol(&buf[match[1].rm_so], NULL, 16);
    684 				offset = offset_new(o);
    685 				table_offset_add(t, offset);
    686 				if (o > t->offset_max)
    687 					t->offset_max = o;
    688 			}
    689 		}
    690 	} while (!done);
    691 	fclose(file);
    692 	if (t->offset_max < last_reg)
    693 		t->offset_max = last_reg;
    694 	return table_build(t);
    695 }
    696 
    697 int main(int argc, char *argv[])
    698 {
    699 	struct table t;
    700 
    701 	if (argc != 2) {
    702 		fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
    703 		exit(1);
    704 	}
    705 	table_init(&t);
    706 	if (parser_auth(&t, argv[1])) {
    707 		fprintf(stderr, "Failed to parse file %s\n", argv[1]);
    708 		return -1;
    709 	}
    710 	table_print(&t);
    711 	return 0;
    712 }
    713