1 2 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 31 32 33 34 35 36 37 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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#ifndef INCLUDED_POSTQUEUE_H_
#define INCLUDED_POSTQUEUE_H_
#if 0
Postprocessing is realized by a template-method design pattern-like
construction in C.
The algorithm proceeds as follows:
Each element of the index file is read, and its keyword (the word
following the offset) is determined. Then the 'construct' function associated
with that keyword is called. We agree with the construct functions that they
return a pointer to a hashitem, which is then processed by storing it either
into the the symbol table or into the work-queue. The construct functions
can use all postqueue_...() new_...(), message_()... string_..()
args_...(), and file_...() functions.
Then, when all commands are available, the queued commands are
processed. For this, the appropriate 'handle' functions are called. Use 0 for
situations where no handling is required.
To conserve memory, having handled a Q-item, its HashItem is erased. The
caller can prevent the destruction of information stored at the HashItems
d_value pointer by setting the HashItems destructor to root_nop. This way the
information remains available for other parts of the program, if made known to
these parts using, e.g., a well-known variable name.
The handling struct is hashed by keywords found in the Task struct, having
the following elements:
typedef struct
{
char const *d_key;
HashItem *(*d_constructor)(long offset, char const *key,
char *rest);
void (*d_handler)(HashItem *item);
}
Task;
In order to construct a postprocessor, use the postprocessor and postqueue
c.s. directories, and link them to an appropriate handler directory.
The main function should be set up as follows:
int main(int argc, char **argv)
{
postqueue_initialize(argc, argv, "-getopt-options string",
long_options_pointer);
if (!args_ok() || args_nArgs() != 2) /* check arguments */
usage();
postQueue_construct(task_pointer);
postQueue_process();
}
The usage() function must be defined for the particular postprocessor
and end in exit(1)
the long_options_pointer must end in an element of all zeroes, and otherwise
consist of LongOption values. See args.h: each element has 3 fields:
char const *: name of the long option (without --)
type: one of
required_argument - an argument is required
no_argument - the option has no argument
optional_argument - the argument is optional
char: the (character) value associated with this option E.g., 'v' with
version, of a unique other value if no corresponding single char.
option is available.
The task-struct is defined in this header file. The array passed to the
constructor must have a final zero-element The constructor returns a hashitem
The hashitem is appended to the task-queue. The type of the hashitem is not
used by the postprocessor, and may be used at will by the constructor or
handler functions.
After processing the index file, the task queue is processed, where each
element of the queue is processed by its handler.
Since this class and its functions are always used by the postprocessors, it
includes for convenience the basic header files:
stdio.h,
root, new, message, string, hashmap, hashitem, file, args
#endif
#include <stdio.h>
#include "../root/root.h"
#include "../args/args.h"
#include "../new/new.h"
#include "../message/message.h"
#include "../file/file.h"
#include "../hashmap/hashmap.h"
#include "../hashitem/hashitem.h"
#include "../string/string.h"
typedef struct
{
char const *d_key;
HashItem *(*d_constructor)(char const *key, char *rest);
void (*d_handler)(long offset, HashItem *item);
}
Task;
extern int postqueue_data;
void postqueue_construct(Task *taskptr);
// PM: postqueue_destruct
void postqueue_process(void); /* erases and destroys the HashItem structs */
/* after calling their handlers */
/*
Internal use only. Not used outside of this directory, needed here
to allow proper compilation of the static inline functions below
*/
typedef struct
{
long d_offset;
HashItem *d_item;
void (*d_handler)(long, HashItem *);
}
QueueItem;
typedef struct
{
char **d_argv;
QueueItem **d_queue;
unsigned d_size; /* available number of pointer locations */
unsigned d_length; /* actually used # of items */
FILE *d_istream;
}
PostQueue;
extern PostQueue postQueue;
/* public interface continues from here */
static inline FILE *postqueue_istream(void)
{
return postQueue.d_istream;
}
#endif
|