Skip to content

Commit c17239a

Browse files
committed
pgm 22.9, merge parts files, WIP
1 parent 440de08 commit c17239a

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,4 @@ spec/parts-list-io-spec
173173
22/part-structs-io-profiler
174174
22/parts-array-io-profiler
175175
22/parts-list-io-profiler
176+
22/22.9-merge-parts

22/22.9-merge-parts.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#if defined(__linux__) || defined(__linux) || defined(__gnu_linux__)
2+
#include <sys/types.h> /* for off_t */
3+
#endif
4+
#include <stdio.h>
5+
#include <sys/stat.h>
6+
#include "error.h"
7+
#include "part-type.h"
8+
9+
int main(int argc, char *argv[])
10+
{
11+
if (argc != 4)
12+
invocation_error(argv[0], "[input file 1] [input file 2] [output file]");
13+
14+
char *larger_filename, *smaller_filename, *output_filename = argv[3];
15+
struct stat file1_stat, file2_stat;
16+
off_t record_size = (off_t)get_part_record_size();
17+
off_t smaller_size;
18+
size_t larger_count, smaller_count;
19+
20+
if (stat(argv[1], &file1_stat) != 0)
21+
exit_error(errno, argv[0], argv[1]);
22+
23+
if (file1_stat.st_size % record_size)
24+
fprintf(stderr, "Corrupt file '%s': size must be multiple of %ld\n",
25+
argv[1],
26+
(size_t)record_size);
27+
28+
if (stat(argv[2], &file2_stat) != 0)
29+
exit_error(errno, argv[0], argv[2]);
30+
31+
if (file2_stat.st_size % record_size)
32+
fprintf(stderr, "Corrupt file '%s': size must be multiple of %ld\n",
33+
argv[2],
34+
(size_t)record_size);
35+
36+
if (file1_stat.st_size > file2_stat.st_size) {
37+
larger_filename = argv[1];
38+
smaller_filename = argv[2];
39+
smaller_size = file2_stat.st_size;
40+
larger_count = file1_stat.st_size / record_size;
41+
smaller_count = file2_stat.st_size / record_size;
42+
} else {
43+
larger_filename = argv[2];
44+
smaller_filename = argv[1];
45+
smaller_size = file1_stat.st_size;
46+
larger_count = file2_stat.st_size / record_size;
47+
smaller_count = file1_stat.st_size / record_size;
48+
}
49+
50+
size_t combined_size = (size_t) file1_stat.st_size + file2_stat.st_size;
51+
Part merge_buffer = (Part)malloc(combined_size);
52+
if (!merge_buffer)
53+
memory_error(__FILE__, __LINE__, __func__);
54+
55+
Part other_buffer = malloc(smaller_size);
56+
if (!other_buffer)
57+
memory_error(__FILE__, __LINE__, __func__);
58+
59+
FILE *larger_stream, *smaller_stream;
60+
61+
if ((larger_stream = fopen(larger_filename, "rb")) == NULL) {
62+
exit_error(errno,argv[0], larger_filename);
63+
}
64+
65+
if ((smaller_stream = fopen(smaller_filename, "rb")) == NULL) {
66+
if (fclose(larger_stream) == EOF)
67+
print_error(errno, __FILE__, larger_filename);
68+
exit_error(errno,argv[0], smaller_filename);
69+
}
70+
71+
if (fread(merge_buffer, record_size, larger_count, larger_stream) < larger_count) {
72+
print_error(errno, argv[0], larger_filename);
73+
if (fclose(larger_stream) == EOF)
74+
print_error(errno, __FILE__, larger_filename);
75+
if (fclose(smaller_stream) == EOF)
76+
print_error(errno, __FILE__, smaller_filename);
77+
exit(EXIT_FAILURE);
78+
}
79+
if (fread(other_buffer, record_size, smaller_count, smaller_stream) < smaller_count) {
80+
print_error(errno, argv[0], smaller_filename);
81+
if (fclose(larger_stream) == EOF)
82+
print_error(errno, __FILE__, larger_filename);
83+
if (fclose(smaller_stream) == EOF)
84+
print_error(errno, __FILE__, smaller_filename);
85+
exit(EXIT_FAILURE);
86+
}
87+
if (fclose(larger_stream) == EOF)
88+
print_error(errno, __FILE__, larger_filename);
89+
if (fclose(smaller_stream) == EOF)
90+
exit_error(errno, __FILE__, smaller_filename);
91+
92+
93+
for (size_t s = 0; s < smaller_count; s++) {
94+
for (size_t l = 0; l < larger_count; l++) {
95+
if ((merge_buffer + l)->number == (other_buffer + s)->number) {
96+
if (strcmp((merge_buffer + l)->name, (other_buffer + s)->name) != 0) {
97+
fprintf(stderr, "Part #%d: name conflict\n", (merge_buffer + l)->number);
98+
continue;
99+
}
100+
if (!set_part_on_hand((merge_buffer + l), (other_buffer + s)->on_hand)) {
101+
fprintf(stderr, "Invalid new quantity on hand for Part #%d\n", (merge_buffer + l)->number);
102+
continue;
103+
}
104+
}
105+
}
106+
}
107+
108+
/*
109+
* for each record in the smaller
110+
* check each part number in the larger until:
111+
* same number is found:
112+
* if name values differ
113+
* report to stderr
114+
* continue
115+
* combine in stock values
116+
* if the new value is invalid
117+
* report to stderr
118+
* continue
119+
* larger part number is found:
120+
* increment "added" counter
121+
* shift all subsequent elements in the larger buffer
122+
* copy record from smaller into the hole
123+
* we reach the end without finding a larger part number
124+
* increment "added" counter
125+
* copy record from smaller at end
126+
*
127+
* open the output file
128+
* fwrite the output buffer
129+
* close the output file
130+
*/
131+
132+
133+
return 0;
134+
}

0 commit comments

Comments
 (0)