1 | /* $Id: sq.c 3956 2010-01-05 20:56:56Z zacheiss $ |
---|
2 | * |
---|
3 | * Generic Queue Routines |
---|
4 | * |
---|
5 | * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology. |
---|
6 | * For copying and distribution information, please see the file |
---|
7 | * <mit-copyright.h>. |
---|
8 | */ |
---|
9 | |
---|
10 | #include <mit-copyright.h> |
---|
11 | #include <moira.h> |
---|
12 | |
---|
13 | #include <stdlib.h> |
---|
14 | #include <string.h> |
---|
15 | |
---|
16 | RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/lib/sq.c $ $Id: sq.c 3956 2010-01-05 20:56:56Z zacheiss $"); |
---|
17 | |
---|
18 | struct save_queue *sq_create(void) |
---|
19 | { |
---|
20 | struct save_queue *sq; |
---|
21 | |
---|
22 | sq = malloc(sizeof(struct save_queue)); |
---|
23 | if (!sq) |
---|
24 | return sq; |
---|
25 | sq->q_next = sq; |
---|
26 | sq->q_prev = sq; |
---|
27 | sq->q_lastget = 0; |
---|
28 | return sq; |
---|
29 | } |
---|
30 | |
---|
31 | int sq_save_data(struct save_queue *sq, void *data) |
---|
32 | { |
---|
33 | struct save_queue *q; |
---|
34 | |
---|
35 | q = malloc(sizeof(struct save_queue)); |
---|
36 | if (!q) |
---|
37 | return 0; |
---|
38 | q->q_next = sq; |
---|
39 | q->q_prev = sq->q_prev; |
---|
40 | sq->q_prev->q_next = q; |
---|
41 | sq->q_prev = q; |
---|
42 | q->q_data = data; |
---|
43 | return 1; |
---|
44 | } |
---|
45 | |
---|
46 | int sq_save_args(int argc, char *argv[], void *sq) |
---|
47 | { |
---|
48 | char **argv_copy; |
---|
49 | int i, n; |
---|
50 | |
---|
51 | argv_copy = malloc(argc * sizeof(char *)); |
---|
52 | if (!argv_copy) |
---|
53 | return 0; |
---|
54 | for (i = 0; i < argc; i++) |
---|
55 | { |
---|
56 | n = strlen(argv[i]) + 1; |
---|
57 | argv_copy[i] = malloc(n); |
---|
58 | if (!argv_copy[i]) |
---|
59 | { |
---|
60 | for (i--; i >= 0; i--) |
---|
61 | free(argv_copy[i]); |
---|
62 | free(argv_copy); |
---|
63 | return 0; |
---|
64 | } |
---|
65 | memcpy(argv_copy[i], argv[i], n); |
---|
66 | } |
---|
67 | |
---|
68 | return sq_save_data(sq, argv_copy); |
---|
69 | } |
---|
70 | |
---|
71 | int sq_save_unique_data(struct save_queue *sq, void *data) |
---|
72 | { |
---|
73 | struct save_queue *q; |
---|
74 | |
---|
75 | for (q = sq->q_next; q != sq; q = q->q_next) |
---|
76 | { |
---|
77 | if (q->q_data == data) |
---|
78 | return 1; |
---|
79 | } |
---|
80 | |
---|
81 | return sq_save_data(sq, data); |
---|
82 | } |
---|
83 | |
---|
84 | int sq_save_unique_string(struct save_queue *sq, char *data) |
---|
85 | { |
---|
86 | struct save_queue *q; |
---|
87 | |
---|
88 | for (q = sq->q_next; q != sq; q = q->q_next) |
---|
89 | { |
---|
90 | if (!strcmp(q->q_data, data)) |
---|
91 | return 1; |
---|
92 | } |
---|
93 | |
---|
94 | return sq_save_data(sq, data); |
---|
95 | } |
---|
96 | |
---|
97 | /* in sq_get_data and sq_remove_data, `data' is actually a pointer to the |
---|
98 | variable to put the data in to. */ |
---|
99 | |
---|
100 | int sq_get_data(struct save_queue *sq, void *data) |
---|
101 | { |
---|
102 | void **dptr = data; |
---|
103 | |
---|
104 | if (sq->q_lastget == NULL) |
---|
105 | sq->q_lastget = sq->q_next; |
---|
106 | else |
---|
107 | sq->q_lastget = sq->q_lastget->q_next; |
---|
108 | |
---|
109 | if (sq->q_lastget == sq) |
---|
110 | return 0; |
---|
111 | *dptr = sq->q_lastget->q_data; |
---|
112 | return 1; |
---|
113 | } |
---|
114 | |
---|
115 | int sq_remove_data(struct save_queue *sq, void *data) |
---|
116 | { |
---|
117 | void **dptr = data; |
---|
118 | |
---|
119 | if (sq->q_next != sq) |
---|
120 | { |
---|
121 | *dptr = sq->q_next->q_data; |
---|
122 | sq->q_next = sq->q_next->q_next; |
---|
123 | free(sq->q_next->q_prev); |
---|
124 | sq->q_next->q_prev = sq; |
---|
125 | return 1; |
---|
126 | } |
---|
127 | return 0; |
---|
128 | } |
---|
129 | |
---|
130 | void sq_remove_last_data(struct save_queue *sq) |
---|
131 | { |
---|
132 | struct save_queue *rem = sq->q_lastget; |
---|
133 | |
---|
134 | if (rem != NULL) |
---|
135 | { |
---|
136 | rem->q_next->q_prev = sq->q_lastget = rem->q_prev; |
---|
137 | rem->q_prev->q_next = rem->q_next; |
---|
138 | free(rem); |
---|
139 | } |
---|
140 | } |
---|
141 | |
---|
142 | int sq_empty(struct save_queue *sq) |
---|
143 | { |
---|
144 | if (sq->q_next == sq) |
---|
145 | return 1; |
---|
146 | else |
---|
147 | return 0; |
---|
148 | } |
---|
149 | |
---|
150 | void sq_destroy(struct save_queue *sq) |
---|
151 | { |
---|
152 | struct save_queue *q; |
---|
153 | |
---|
154 | for (q = sq->q_next; q != sq; q = sq->q_next) |
---|
155 | { |
---|
156 | sq->q_next = q->q_next; |
---|
157 | free(q); |
---|
158 | } |
---|
159 | free(sq); |
---|
160 | } |
---|
161 | |
---|