]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/cmd_attach.c
cmd_attach.c: Correct workaround for GCC bug PR61443
[z180-stamp.git] / avr / cmd_attach.c
CommitLineData
cb4fb1ed
L
1/*
2 * (C) Copyright 2016 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7/*
4122fe90 8 * attach channels to devices
cb4fb1ed
L
9 */
10
11#include "common.h"
12#include <string.h>
13#include <stdbool.h>
14
15#include "command.h"
16#include "z180-serv.h"
17#include "getopt-min.h"
cb4fb1ed
L
18
19
20static const FLASH char * const FLASH rc_messages[] = {
21 FSTR("OK"),
22 FSTR("Unknown error"),
23 FSTR("Disk number out of range 0..7"),
24 FSTR("Disk allready attached"),
25 FSTR("Disk not attached"),
26 FSTR("File not found"),
27 FSTR("Not enough memory"),
28 FSTR("Error opening file"),
29 FSTR("File allready attached to other drive"),
30 };
31
32static
33void printerror(int rc, uint8_t unit, char *fn)
34{
35 if (rc < 0 || (unsigned) rc >= ARRAY_SIZE(rc_messages))
36 rc = 1;
37
3f88ef88
L
38#if GCC_BUG_61443
39 printf_P(PSTR("Attachment of '%s' to dsk%d failed: "), fn, unit);
40 my_puts_P(rc_messages[rc]);
41 my_puts_P(PSTR("!\n"));
cb4fb1ed
L
42#else
43 printf_P(PSTR("Attachment of '%s' to dsk%d failed: %S!\n"),
44 fn, unit, rc_messages[rc]);
45#endif
46}
47
48/*
49 * attach [[options] [unit [diskfile]]]
50 *
51 * detach unit
52 * attach -d unit
53 *
54 * attach -o reattach unit
55 * attach -o reattach unit diskfile
56 *
57 * attach unit diskfile
58 *
59 */
60
61command_ret_t do_attach(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
62{
63 uint8_t unit;
64 char *filename = NULL;
65 bool detach = false;
4122fe90 66 bool detach_all = false;
cb4fb1ed
L
67 drv_opt_t options = 0;
68 int res;
69
70 (void) cmdtp; (void) flag;
71
72
4122fe90 73 if (argv[0][0] == 'd') {
cb4fb1ed
L
74 /* we are called as 'detach' */
75 detach = true;
4122fe90 76 } else if (argc == 1) {
cb4fb1ed
L
77 /* no arguments */
78 drv_list();
79 return CMD_RET_SUCCESS;
80 }
81
82 /* reset getopt() */
beafa6d6 83 optind = 0;
cb4fb1ed
L
84
85 int opt;
4122fe90 86 while ((opt = getopt(argc, argv, PSTR("darwo:"))) != -1) {
cb4fb1ed
L
87 switch (opt) {
88 case 'd':
89 detach = true;
90 break;
4122fe90
L
91 case 'a':
92 detach_all = true;
93 break;
cb4fb1ed
L
94 case 'r':
95 options |= DRV_OPT_RO;
96 break;
97 case 'w':
98 options &= ~DRV_OPT_RO;
99 break;
100 case 'o':
101 {
102 static const FLASH char delim[] = {", "};
103 char *p = strtok_P(optarg, delim);
104 while (p != NULL) {
105 if (!strcmp_P(p, PSTR("ro")))
106 options |= DRV_OPT_RO;
107 else if (!strcmp_P(p, PSTR("rw")))
108 options &= ~DRV_OPT_RO;
109 else if (!strcmp_P(p, PSTR("debug")))
110 options |= DRV_OPT_DEBUG;
111 else if (!strcmp_P(p, PSTR("nodebug")))
112 options &= ~DRV_OPT_DEBUG;
113 else if (!strcmp_P(p, PSTR("reattach")))
114 options |= DRV_OPT_REATTATCH;
115 else
116 return CMD_RET_USAGE;
117
118 p = strtok_P(NULL, delim);
119 }
120 }
121 break;
122 default: /* '?' */
123 return CMD_RET_USAGE;
124 }
125 }
126
127 /* remaining arguments */
128 argc -= optind;
4122fe90
L
129 if ( !( (argc == 0 && detach && detach_all) ||
130 (argc == 1 && detach) ||
131 (argc == 1 && (options & DRV_OPT_REATTATCH)) ||
132 argc == 2) )
cb4fb1ed
L
133 return CMD_RET_USAGE;
134
4122fe90 135 if (argc > 0 && ((strlen(argv[optind]) != 4) ||
cb4fb1ed 136 strncmp_P(argv[optind], PSTR("dsk"), 3) ||
4122fe90 137 (unit = argv[optind][3] - '0') >= CONFIG_CPM_MAX_DRIVE)) {
cb4fb1ed
L
138
139 printf_P(PSTR("Unknown device: '%s'\n"), argv[optind]);
140 return CMD_RET_FAILURE;
141 }
142
143 if (detach) {
4122fe90
L
144 if (detach_all)
145 for (uint8_t i = 0; i < CONFIG_CPM_MAX_DRIVE; i++)
146 drv_detach(i);
147 else
148 drv_detach(unit);
cb4fb1ed
L
149 return CMD_RET_SUCCESS;
150 }
151
152 if (argc == 2)
153 filename = argv[++optind];
154
155 res = drv_attach(unit, filename, options);
156 if (res)
157 printerror(res, unit, filename);
158
159 return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
160}