File: postqueue.h

package info (click to toggle)
yodl 4.04.00-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,720 kB
  • sloc: ansic: 7,803; perl: 683; cpp: 570; sh: 411; xml: 190; makefile: 164
file content (156 lines) | stat: -rw-r--r-- 4,766 bytes parent folder | download | duplicates (3)
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