Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1186 | savelij | 1 | /* pbind.c */ |
2 | /*****************************************************************************/ |
||
3 | /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */ |
||
4 | /* */ |
||
5 | /* AS-Portierung */ |
||
6 | /* */ |
||
7 | /* Bearbeitung von AS-P-Dateien */ |
||
8 | /* */ |
||
9 | /*****************************************************************************/ |
||
10 | |||
11 | #include "stdinc.h" |
||
12 | #include <ctype.h> |
||
13 | #include <string.h> |
||
14 | |||
15 | #include "version.h" |
||
16 | #include "be_le.h" |
||
17 | #include "stdhandl.h" |
||
18 | #include "bpemu.h" |
||
19 | #include "strutil.h" |
||
20 | #include "stringlists.h" |
||
21 | #include "cmdarg.h" |
||
22 | #include "msg_level.h" |
||
23 | #include "toolutils.h" |
||
24 | #include "nls.h" |
||
25 | #include "nlmessages.h" |
||
26 | #include "pbind.rsc" |
||
27 | #ifdef _USE_MSH |
||
28 | # include "pbind.msh" |
||
29 | #endif |
||
30 | #include "ioerrs.h" |
||
31 | |||
32 | #define BufferSize 8192 |
||
33 | |||
34 | static const char *Creator = "BIND 1.42"; |
||
35 | |||
36 | static FILE *TargFile; |
||
37 | static String TargName; |
||
38 | static Byte *Buffer; |
||
39 | |||
40 | static void OpenTarget(void) |
||
41 | { |
||
42 | TargFile = fopen(TargName, OPENWRMODE); |
||
43 | if (!TargFile) ChkIO(TargName); |
||
44 | if (!Write2(TargFile, &FileID)) ChkIO(TargName); |
||
45 | } |
||
46 | |||
47 | static void CloseTarget(void) |
||
48 | { |
||
49 | Byte EndHeader = FileHeaderEnd; |
||
50 | |||
51 | if (fwrite(&EndHeader, 1, 1, TargFile) != 1) |
||
52 | ChkIO(TargName); |
||
53 | if (fwrite(Creator, 1, strlen(Creator), TargFile) != strlen(Creator)) |
||
54 | ChkIO(TargName); |
||
55 | if (fclose(TargFile) == EOF) |
||
56 | ChkIO(TargName); |
||
57 | if (Magic != 0) |
||
58 | unlink(TargName); |
||
59 | } |
||
60 | |||
61 | static void ProcessFile(char *FileName) |
||
62 | { |
||
63 | FILE *SrcFile; |
||
64 | Word TestID; |
||
65 | Byte InpHeader, InpCPU, InpSegment, InpGran; |
||
66 | LongInt InpStart, SumLen; |
||
67 | Word InpLen, TransLen; |
||
68 | Boolean doit; |
||
69 | |||
70 | SrcFile = fopen(FileName, OPENRDMODE); |
||
71 | if (!SrcFile) |
||
72 | ChkIO(FileName); |
||
73 | |||
74 | if (!Read2(SrcFile, &TestID)) |
||
75 | chk_wr_read_error(FileName); |
||
76 | if (TestID != FileMagic) |
||
77 | FormatError(FileName, getmessage(Num_FormatInvHeaderMsg)); |
||
78 | |||
79 | if (msg_level >= e_msg_level_normal) |
||
80 | { |
||
81 | chkio_printf(OutName, "%s==>>%s", FileName, TargName); |
||
82 | } |
||
83 | |||
84 | SumLen = 0; |
||
85 | |||
86 | do |
||
87 | { |
||
88 | ReadRecordHeader(&InpHeader, &InpCPU, &InpSegment, &InpGran, FileName, SrcFile); |
||
89 | |||
90 | if (InpHeader == FileHeaderStartAdr) |
||
91 | { |
||
92 | if (!Read4(SrcFile, &InpStart)) |
||
93 | chk_wr_read_error(FileName); |
||
94 | WriteRecordHeader(&InpHeader, &InpCPU, &InpSegment, &InpGran, TargName, TargFile); |
||
95 | if (!Write4(TargFile, &InpStart)) |
||
96 | ChkIO(TargName); |
||
97 | } |
||
98 | |||
99 | else if (InpHeader == FileHeaderDataRec) |
||
100 | { |
||
101 | if (!Read4(SrcFile, &InpStart)) |
||
102 | chk_wr_read_error(FileName); |
||
103 | if (!Read2(SrcFile, &InpLen)) |
||
104 | chk_wr_read_error(FileName); |
||
105 | |||
106 | if (ftell(SrcFile)+InpLen >= FileSize(SrcFile) - 1) |
||
107 | FormatError(FileName, getmessage(Num_FormatInvRecordLenMsg)); |
||
108 | |||
109 | doit = FilterOK(InpCPU); |
||
110 | |||
111 | if (doit) |
||
112 | { |
||
113 | SumLen += InpLen; |
||
114 | WriteRecordHeader(&InpHeader, &InpCPU, &InpSegment, &InpGran, TargName, TargFile); |
||
115 | if (!Write4(TargFile, &InpStart)) |
||
116 | ChkIO(TargName); |
||
117 | if (!Write2(TargFile, &InpLen)) |
||
118 | ChkIO(TargName); |
||
119 | while (InpLen > 0) |
||
120 | { |
||
121 | TransLen = min(BufferSize, InpLen); |
||
122 | if (fread(Buffer, 1, TransLen, SrcFile) != TransLen) |
||
123 | chk_wr_read_error(FileName); |
||
124 | if (fwrite(Buffer, 1, TransLen, TargFile) != TransLen) |
||
125 | ChkIO(TargName); |
||
126 | InpLen -= TransLen; |
||
127 | } |
||
128 | } |
||
129 | else |
||
130 | { |
||
131 | if (fseek(SrcFile, InpLen, SEEK_CUR) == -1) |
||
132 | ChkIO(FileName); |
||
133 | } |
||
134 | } |
||
135 | else |
||
136 | SkipRecord(InpHeader, FileName, SrcFile); |
||
137 | } |
||
138 | while (InpHeader != FileHeaderEnd); |
||
139 | |||
140 | if (msg_level >= e_msg_level_normal) |
||
141 | { |
||
142 | chkio_printf(OutName, " ("); |
||
143 | chkio_printf(OutName, Integ32Format, SumLen); |
||
144 | chkio_printf(OutName, " %s)\n", getmessage((SumLen == 1) ? Num_Byte : Num_Bytes)); |
||
145 | } |
||
146 | |||
147 | if (fclose(SrcFile) == EOF) |
||
148 | ChkIO(FileName); |
||
149 | } |
||
150 | |||
151 | /* ------------------------------ */ |
||
152 | |||
153 | static const as_cmd_rec_t BINDParams[] = |
||
154 | { |
||
155 | { "f" , CMD_FilterList } |
||
156 | }; |
||
157 | |||
158 | int main(int argc, char **argv) |
||
159 | { |
||
160 | char *p_target_name; |
||
161 | as_cmd_results_t cmd_results; |
||
162 | |||
163 | if (!NLS_Initialize(&argc, argv)) |
||
164 | exit(4); |
||
165 | be_le_init(); |
||
166 | |||
167 | stdhandl_init(); |
||
168 | as_cmdarg_init(*argv); |
||
169 | msg_level_init(); |
||
170 | toolutils_init(*argv); |
||
171 | nls_init(); |
||
172 | #ifdef _USE_MSH |
||
173 | nlmessages_init_buffer(pbind_msh_data, sizeof(pbind_msh_data), MsgId1, MsgId2); |
||
174 | #else |
||
175 | nlmessages_init_file("pbind.msg", *argv, MsgId1, MsgId2); |
||
176 | #endif |
||
177 | ioerrs_init(*argv); |
||
178 | |||
179 | Buffer = (Byte*) malloc(sizeof(Byte) * BufferSize); |
||
180 | |||
181 | as_cmd_register(BINDParams, as_array_size(BINDParams)); |
||
182 | if (e_cmd_err == as_cmd_process(argc, argv, "BINDCMD", &cmd_results)) |
||
183 | { |
||
184 | fprintf(stderr, "%s%s\n", getmessage(cmd_results.error_arg_in_env ? Num_ErrMsgInvEnvParam : Num_ErrMsgInvParam), cmd_results.error_arg); |
||
185 | fprintf(stderr, "%s\n", getmessage(Num_ErrMsgProgTerm)); |
||
186 | exit(1); |
||
187 | } |
||
188 | |||
189 | if ((msg_level >= e_msg_level_verbose) || cmd_results.write_version_exit) |
||
190 | { |
||
191 | String Ver; |
||
192 | as_snprintf(Ver, sizeof(Ver), "PBIND V%s", Version); |
||
193 | WrCopyRight(Ver); |
||
194 | } |
||
195 | |||
196 | if (cmd_results.write_help_exit) |
||
197 | { |
||
198 | char *ph1, *ph2; |
||
199 | |||
200 | chkio_printf(OutName, "%s%s%s\n", getmessage(Num_InfoMessHead1), as_cmdarg_get_executable_name(), getmessage(Num_InfoMessHead2)); |
||
201 | for (ph1 = getmessage(Num_InfoMessHelp), ph2 = strchr(ph1, '\n'); ph2; ph1 = ph2+1, ph2 = strchr(ph1, '\n')) |
||
202 | { |
||
203 | *ph2 = '\0'; |
||
204 | chkio_printf(OutName, "%s\n", ph1); |
||
205 | *ph2 = '\n'; |
||
206 | } |
||
207 | } |
||
208 | |||
209 | if (cmd_results.write_version_exit || cmd_results.write_help_exit) |
||
210 | exit(0); |
||
211 | |||
212 | if (StringListEmpty(cmd_results.file_arg_list)) |
||
213 | { |
||
214 | fprintf(stderr, "%s: %s\n", as_cmdarg_get_executable_name(), getmessage(Num_ErrMessNoInputFiles)); |
||
215 | exit(1); |
||
216 | } |
||
217 | |||
218 | p_target_name = MoveAndCutStringListLast(&cmd_results.file_arg_list); |
||
219 | strmaxcpy(TargName, p_target_name ? p_target_name : "", STRINGSIZE); |
||
220 | free(p_target_name); p_target_name = NULL; |
||
221 | if (!*TargName) |
||
222 | { |
||
223 | chkio_fprintf(stderr, OutName, "%s\n", getmessage(Num_ErrMsgTargetMissing)); |
||
224 | exit(1); |
||
225 | } |
||
226 | AddSuffix(TargName, STRINGSIZE, getmessage(Num_Suffix)); |
||
227 | |||
228 | OpenTarget(); |
||
229 | |||
230 | while (True) |
||
231 | { |
||
232 | char *p_src_name = MoveAndCutStringListFirst(&cmd_results.file_arg_list); |
||
233 | |||
234 | if (!p_src_name) |
||
235 | break; |
||
236 | if (*p_src_name) |
||
237 | DirScan(p_src_name, ProcessFile); |
||
238 | free(p_src_name); |
||
239 | } |
||
240 | |||
241 | CloseTarget(); |
||
242 | |||
243 | return 0; |
||
244 | } |