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 | } |