-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharbeitDec.c
More file actions
305 lines (257 loc) · 10.7 KB
/
arbeitDec.c
File metadata and controls
305 lines (257 loc) · 10.7 KB
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/*********************************************************/
/* File: sort.c */
/* */
/* Description: This file contains source code for */
/* a program written in C which sorts */
/* text files. It is a demonstration */
/* of LISP-like list procedures. */
/* */
/* Version Date History */
/* 1.00 14SEP88 Original */
/*********************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*********************************************************/
/* typedefs */
/*********************************************************/
typedef void *POINTER; /* General purpose pointer */
typedef struct /* A CONS is two pointers */
{
POINTER car;
POINTER cdr;
} CONS;
typedef CONS *LIST; /* A LIST is a pointer to */
/* a CONS */
/*********************************************************/
/* return codes at the program level */
/*********************************************************/
#define RET_NORMAL 0 /* Normal return code */
#define RET_IOERR 2 /* I/O Error */
#define RET_MEMERR 3 /* Memory allocation error */
/*********************************************************/
/* Manifest Constants */
/*********************************************************/
#define LINESIZE 500 /* size of local buffer */
/* lines larger then this will */
/* read as multiple lines */
/*********************************************************/
/* Prototypes */
/*********************************************************/
LIST reverse(LIST lst);
LIST merge(LIST lst1,LIST lst2,int (*compare)());
LIST sort(LIST lst,int (*compare)());
CONS *cons(POINTER a,POINTER b);
LIST cpush(CONS *z,LIST *lst);
LIST push(POINTER item,LIST *lst);
CONS *cpop(POINTER *lst);
POINTER pop(POINTER *lst);
LIST outputlist(LIST lst,FILE *stream);
int string_compare(char *a,char *b);
char *getaline(FILE *stream);
/*********************************************************/
/* main sort program */
/* */
/* Reads lines of text from stdin, sorts them, and */
/* outputs the result to stdout. */
/*********************************************************/
int main(void)
{
LIST mylist=NULL; /* List of text records as */
/* read from stdin */
char *lp; /* pointer to duplicate string*/
while ( (lp = getaline(stdin)) != NULL )
push(lp,&mylist);
outputlist(sort(mylist,string_compare),stdout);
return RET_NORMAL;
}
/*********************************************************/
/* getaline get a line of text */
/* */
/* Returns a pointer to a line of text read from */
/* stream. Returns NULL if end of file. Exits */
/* on error. */
/*********************************************************/
char *getaline(FILE *stream)
{
char line[LINESIZE]; /* input buffer */
char *lp; /* points to strdup buffer */
if (fgets(line,LINESIZE,stream) != NULL)
{
if ( (lp = strdup(line)) != NULL)
return lp; /* normal return */
else
exit(RET_MEMERR); /* strdup could not malloc */
}
else
{
if (feof(stream))
return NULL; /* end of file */
else
exit(RET_IOERR); /* I/O error in fgets */
}
}
/*********************************************************/
/* string_compare compares strings */
/* */
/* Returns TRUE value if string a is ordered after */
/* string b. Returns FASE if string a is equal to */
/* or ordered before string b. */
/*********************************************************/
int string_compare(char *a,char *b)
{
return strcmp(a,b) > 0;
}
/*********************************************************/
/* push push an item onto a list */
/* */
/* Uses cons to create a CONS and sets its car cell */
/* to item. Its cdr is set to *lst. *lst is set to */
/* point to the CONS created. A pointer to the CONS */
/* is also returned. */
/*********************************************************/
LIST push(POINTER item,LIST *lst)
{
return *lst = cons(item,*lst);
}
/*********************************************************/
/* cons create a CONS */
/* */
/* Uses malloc to allocate a CONS and set its */
/* car cell to a and its cdr cell to b. Exits if */
/* malloc fails! */
/*********************************************************/
CONS *cons(POINTER a,POINTER b)
{
CONS *z;
z = (CONS *) malloc(sizeof(CONS));
if (z == NULL) exit(RET_MEMERR);
z->car = a;
z->cdr = b;
return z;
}
/*********************************************************/
/* pop pop an item off a list */
/* */
/* Uses cpop to pop a CONS off lst. Return NULL */
/* if lst is empty. free the CONS and return the */
/* car cell of the CONS. */
/*********************************************************/
POINTER pop(LIST *lst)
{
POINTER item;
CONS *z;
z = cpop(lst);
if(z == NULL) return NULL; /* list is empty */
item = z->car; /* get what cons pointed to*/
free(z); /* release the cons */
return item;
}
/*********************************************************/
/* cpop pop a CONS off a list */
/* */
/* if *lst is empty return NULL, else set *lst to the */
/* the car cell of the first CONS on *lst and return */
/* a pointer to the first CONS on *lst. */
/*********************************************************/
CONS *cpop(LIST *lst)
{
LIST rvalue;
rvalue = *lst;
if (rvalue != NULL)
*lst = rvalue->cdr;
return rvalue;
}
/*********************************************************/
/* outputlist output each item in a list */
/* */
/* start with the first item in the list, output it */
/* to stream assuming it is a string, repeat for each */
/* item in the list. Return lst. */
/*********************************************************/
LIST outputlist(LIST lst,FILE *stream)
{
CONS *acons;
LIST l=lst;
while ( acons=cpop(l) != NULL )
fputs( (char *) acons->car,stream);
return lst;
}
/*********************************************************/
/* cpush cons push */
/* */
/* Adds a CONS to the head of a list */
/* modify the cdr cell of *z to point to *lst. set */
/* *lst to point to the CONS z and return a pointer */
/* to the CONS. */
/*********************************************************/
LIST cpush(CONS *z,LIST *lst)
{
z->cdr = *lst;
return *lst = z;
}
/*********************************************************/
/* reverse reverse a list */
/* */
/* distructively modify the cdr cells of the CONS */
/* which make up lst so that a new list is created */
/* which is the reverse of the original list. */
/* return the new list. */
/*********************************************************/
LIST reverse(LIST lst)
{
LIST rlst=NULL;
while (lst != NULL) cpush(cpop(&lst),&rlst);
return rlst;
}
/*********************************************************/
/* split split a list in half */
/* */
/* Find the mid CONS in lst. set its cdr cell to */
/* NULL. return the remainder of lst, i.e. a pointer */
/* to the next CONS after the mid CONS. */
/*********************************************************/
LIST split(LIST lst)
{
LIST tail=lst->cdr;
if ( (lst == NULL) || (tail == NULL) )
return lst;
while( (tail != NULL) && ( (tail=tail->cdr) != NULL) )
{
lst = lst->cdr;
tail = tail->cdr;
}
tail = lst->cdr;
lst->cdr=NULL;
return tail;
}
/*********************************************************/
/* sort sort a list */
/* */
/* If cmp is a two argument ordering procedure, */
/* sort the items in lst based on cmp and */
/* return the results */
/*********************************************************/
LIST sort( LIST lst,int (*cmp)())
{
LIST lst2;
if ((lst == NULL) || (lst->cdr == NULL)) return lst;
lst2 = split(lst);
return merge(sort(lst,cmp),sort(lst2,cmp),cmp);
}
/*********************************************************/
/* merge merge two lists */
/* */
/* If cmp is a two argument ordering procedure, */
/* merge the items in l1 and l2 based on cmp and */
/* return the results */
/*********************************************************/
LIST merge(LIST l1,LIST l2,int (*cmp)())
{
LIST rlst=NULL;
while ( (l1 != NULL) && (l2 != NULL) )
cpush((cmp(l2->car,l1->car) ? cpop(&l1) : cpop(&l2)), &rlst);
while ( l1 != NULL ) cpush(cpop(&l1),&rlst);
while ( l2 != NULL ) cpush(cpop(&l2),&rlst);
return reverse(rlst);
}