Skip to content

Commit 4215e73

Browse files
Chris Trowbridgeadbridge
authored andcommitted
Switch to using mbed-trace for greentea test debug output
1 parent 75682b4 commit 4215e73

34 files changed

+152
-134
lines changed

TESTS/integration/COMMON/common_defines_test.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
* See the License for the specific language governing permissions and
1717
* limitations under the License.
1818
*/
19+
#include "mbed_trace.h"
20+
21+
#define TRACE_GROUP "GRNT"
1922

2023
#define ETHERNET 1
2124
#define WIFI 2

TESTS/integration/COMMON/download_test.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "unity/unity.h"
2626
#include "greentea-client/test_env.h"
2727
#include <string>
28+
#include "common_defines_test.h"
2829

2930
#define MAX_THREADS 5
3031

@@ -91,7 +92,7 @@ size_t download_test(NetworkInterface *interface, const unsigned char *data, siz
9192
break;
9293
}
9394
ThisThread::sleep_for(1000);
94-
printf("[NET-%d] Connection failed. Retry %d of %d\r\n", thread_id, tries, MAX_RETRIES);
95+
tr_info("[NET-%d] Connection failed. Retry %d of %d", thread_id, tries, MAX_RETRIES);
9596
}
9697
TEST_ASSERT_EQUAL_INT_MESSAGE(0, result, "failed to connect");
9798

@@ -109,7 +110,7 @@ size_t download_test(NetworkInterface *interface, const unsigned char *data, siz
109110
} else {
110111
TEST_ASSERT_MESSAGE(0, "wrong thread id");
111112
}
112-
printf("[NET-%d] Registered socket callback function\r\n", thread_id);
113+
tr_info("[NET-%d] Registered socket callback function", thread_id);
113114
event_fired[thread_id] = false;
114115

115116
/* setup request */
@@ -118,7 +119,7 @@ size_t download_test(NetworkInterface *interface, const unsigned char *data, siz
118119
/* construct request */
119120
size_t req_len = snprintf(request, REQ_BUF_SIZE - 1, req_template, dl_path, dl_host);
120121
request[req_len] = 0;
121-
printf("[NET-%d] Request header (%u): %s\r\n", thread_id, req_len, request);
122+
tr_info("[NET-%d] Request header (%u): %s", thread_id, req_len, request);
122123

123124
/* send request to server */
124125
result = tcpsocket.send(request, req_len);
@@ -128,7 +129,7 @@ size_t download_test(NetworkInterface *interface, const unsigned char *data, siz
128129
char *receive_buffer = &g_receive_buffer[thread_id * RECV_BUF_SIZE];
129130

130131
tcpsocket.set_blocking(false);
131-
printf("[NET-%d] Non-blocking socket mode set\r\n", thread_id);
132+
tr_info("[NET-%d] Non-blocking socket mode set", thread_id);
132133

133134
size_t received_bytes = 0;
134135
int body_index = -1;
@@ -164,7 +165,7 @@ size_t download_test(NetworkInterface *interface, const unsigned char *data, siz
164165
if (body_index < 0) {
165166
continue;
166167
} else {
167-
printf("[NET-%d] Found body index: %d\r\n", thread_id, body_index);
168+
tr_info("[NET-%d] Found body index: %d", thread_id, body_index);
168169

169170
/* remove header before comparison */
170171
memmove(receive_buffer, &receive_buffer[body_index + 4], result - body_index - 4);
@@ -184,9 +185,9 @@ size_t download_test(NetworkInterface *interface, const unsigned char *data, siz
184185
speed = float(received_bytes) / timer.read();
185186
percent = float(received_bytes) * 100 / float(data_length);
186187
time_left = (data_length - received_bytes) / speed;
187-
printf("[NET-%d] Received bytes: %u, (%.2f%%, %.2fKB/s, ETA: %02d:%02d:%02d)\r\n",
188-
thread_id, received_bytes, percent, speed / 1024,
189-
time_left / 3600, (time_left / 60) % 60, time_left % 60);
188+
tr_info("[NET-%d] Received bytes: %u, (%.2f%%, %.2fKB/s, ETA: %02d:%02d:%02d)",
189+
thread_id, received_bytes, percent, speed / 1024,
190+
time_left / 3600, (time_left / 60) % 60, time_left % 60);
190191
}
191192
} while ((result > 0) && (received_bytes < data_length));
192193
}
@@ -195,10 +196,10 @@ size_t download_test(NetworkInterface *interface, const unsigned char *data, siz
195196

196197
timer.stop();
197198
float f_received_bytes = float(received_bytes);
198-
printf("[NET-%d] Downloaded: %.2fKB (%.2fKB/s, %.2f secs)\r\n", thread_id,
199-
f_received_bytes / 1024.,
200-
f_received_bytes / (timer.read() * 1024.),
201-
timer.read());
199+
tr_info("[NET-%d] Downloaded: %.2fKB (%.2fKB/s, %.2f secs)", thread_id,
200+
f_received_bytes / 1024.,
201+
f_received_bytes / (timer.read() * 1024.),
202+
timer.read());
202203

203204
return received_bytes;
204205
}

TESTS/integration/COMMON/file_test.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "mbed.h"
2525
#include "unity/unity.h"
26+
#include "common_defines_test.h"
2627

2728
void file_test_write(const char *file, size_t offset, const unsigned char *data, size_t data_length, size_t block_size)
2829
{
@@ -57,8 +58,8 @@ void file_test_write(const char *file, size_t offset, const unsigned char *data,
5758
TEST_ASSERT_EQUAL_INT_MESSAGE(0, result, "could not close file");
5859

5960
timer.stop();
60-
printf("[FS] Wrote: \"%s\" %.2fKB (%.2fKB/s, %.2f secs)\r\n", file,
61-
float(data_length) / 1024, float(data_length) / timer.read() / 1024, timer.read());
61+
tr_info("[FS] Wrote: \"%s\" %.2fKB (%.2fKB/s, %.2f secs)", file,
62+
float(data_length) / 1024, float(data_length) / timer.read() / 1024, timer.read());
6263
}
6364

6465
void file_test_read(const char *file, size_t offset, const unsigned char *data, size_t data_length, size_t block_size)
@@ -99,7 +100,7 @@ void file_test_read(const char *file, size_t offset, const unsigned char *data,
99100

100101
free(buffer);
101102

102-
printf("[FS] Read : \"%s\" %.2fKB (%.2fKB/s, %.2f secs)\r\n", file,
103-
float(data_length) / 1024, float(data_length) / timer.read() / 1024, timer.read());
103+
tr_info("[FS] Read : \"%s\" %.2fKB (%.2fKB/s, %.2f secs)", file,
104+
float(data_length) / 1024, float(data_length) / timer.read() / 1024, timer.read());
104105
}
105106

TESTS/integration/net-single/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ static control_t setup_network(const size_t call_count)
6868
if (err == NSAPI_ERROR_OK) {
6969
break;
7070
} else {
71-
printf("[ERROR] Connecting to network. Retrying %d of %d.\r\n", tries, MAX_RETRIES);
71+
tr_error("[ERROR] Connecting to network. Retrying %d of %d.", tries, MAX_RETRIES);
7272
}
7373
}
7474
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
75-
printf("[NET] IP address is '%s'\n", interface->get_ip_address());
76-
printf("[NET] MAC address is '%s'\n", interface->get_mac_address());
75+
tr_info("[NET] IP address is '%s'", interface->get_ip_address());
76+
tr_info("[NET] MAC address is '%s'", interface->get_mac_address());
7777
return CaseNext;
7878
}
7979

TESTS/integration/net-threaded/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ static control_t setup_network(const size_t call_count)
6868
if (err == NSAPI_ERROR_OK) {
6969
break;
7070
} else {
71-
printf("[ERROR] Connecting to network. Retrying %d of %d.\r\n", tries, MAX_RETRIES);
71+
tr_error("[ERROR] Connecting to network. Retrying %d of %d.", tries, MAX_RETRIES);
7272
}
7373
}
7474
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
75-
printf("[NET] IP address is '%s'\n", net->get_ip_address());
76-
printf("[NET] MAC address is '%s'\n", net->get_mac_address());
75+
tr_info("[NET] IP address is '%s'", net->get_ip_address());
76+
tr_info("[NET] MAC address is '%s'", net->get_mac_address());
7777
return CaseNext;
7878
}
7979

TESTS/integration/stress-net-fs/main.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,12 @@ static control_t setup_network(const size_t call_count)
7272
if (err == NSAPI_ERROR_OK) {
7373
break;
7474
} else {
75-
printf("[ERROR] Connecting to network. Retrying %d of %d...\r\n", tries, MAX_RETRIES);
75+
tr_error("[ERROR] Connecting to network. Retrying %d of %d...", tries, MAX_RETRIES);
7676
}
7777
}
7878
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
79-
printf("[NET] IP address is '%s'\n", interface->get_ip_address());
80-
printf("[NET] MAC address is '%s'\n", interface->get_mac_address());
79+
tr_info("[NET] IP address is '%s'", interface->get_ip_address());
80+
tr_info("[NET] MAC address is '%s'", interface->get_mac_address());
8181
return CaseNext;
8282
}
8383

@@ -205,7 +205,7 @@ void test_malloc()
205205

206206
void *bufferTest = NULL;
207207
TEST_ASSERT_MESSAGE(size > 0, "Size must not be zero for test");
208-
printf("Allocating %d bytes", (int)size);
208+
tr_info("Allocating %d bytes", (int)size);
209209
bufferTest = malloc(size);
210210
TEST_ASSERT(bufferTest != NULL);
211211
free(bufferTest);

TESTS/netsocket/dns/asynchronous_dns_cache.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ void ASYNCHRONOUS_DNS_CACHE()
5656
int delay_ms = (ticker_us - started_us) / 1000;
5757

5858
static int delay_first = delay_ms / 2;
59-
printf("Delays: first: %i, delay_ms: %i\n", delay_first, delay_ms);
59+
tr_info("Delays: first: %i, delay_ms: %i", delay_first, delay_ms);
6060
// Check that cached accesses are at least twice as fast as the first one
6161
TEST_ASSERT_TRUE(i == 0 || delay_ms <= delay_first);
6262

63-
printf("DNS: query \"%s\" => \"%s\", time %i ms\n",
64-
dns_test_hosts[0], data.addr.get_ip_address(), delay_ms);
63+
tr_info("DNS: query \"%s\" => \"%s\", time %i ms",
64+
dns_test_hosts[0], data.addr.get_ip_address(), delay_ms);
6565
}
6666
}

TESTS/netsocket/dns/asynchronous_dns_cancel.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void ASYNCHRONOUS_DNS_CANCEL()
4242
count++;
4343
} else {
4444
// No memory to initiate DNS query, callback will not be called
45-
printf("Error: No resources to initiate DNS query for %s\n", dns_test_hosts[i]);
45+
tr_error("Error: No resources to initiate DNS query for %s", dns_test_hosts[i]);
4646
data[i].result = data[i].req_result;
4747
data[i].value_set = true;
4848
}
@@ -63,21 +63,21 @@ void ASYNCHRONOUS_DNS_CANCEL()
6363

6464
for (unsigned int i = 0; i < MBED_CONF_APP_DNS_TEST_HOSTS_NUM; i++) {
6565
if (!data[i].value_set) {
66-
printf("DNS: query \"%s\" => cancel\n", dns_test_hosts[i]);
66+
tr_info("DNS: query \"%s\" => cancel", dns_test_hosts[i]);
6767
continue;
6868
}
6969
TEST_ASSERT(data[i].result == NSAPI_ERROR_OK || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
7070
if (data[i].result == NSAPI_ERROR_OK) {
71-
printf("DNS: query \"%s\" => \"%s\"\n",
72-
dns_test_hosts[i], data[i].addr.get_ip_address());
71+
tr_info("DNS: query \"%s\" => \"%s\"",
72+
dns_test_hosts[i], data[i].addr.get_ip_address());
7373
} else if (data[i].result == NSAPI_ERROR_DNS_FAILURE) {
74-
printf("DNS: query \"%s\" => DNS failure\n", dns_test_hosts[i]);
74+
tr_error("DNS: query \"%s\" => DNS failure", dns_test_hosts[i]);
7575
} else if (data[i].result == NSAPI_ERROR_TIMEOUT) {
76-
printf("DNS: query \"%s\" => timeout\n", dns_test_hosts[i]);
76+
tr_error("DNS: query \"%s\" => timeout", dns_test_hosts[i]);
7777
} else if (data[i].result == NSAPI_ERROR_NO_MEMORY) {
78-
printf("DNS: query \"%s\" => no memory\n", dns_test_hosts[i]);
78+
tr_error("DNS: query \"%s\" => no memory", dns_test_hosts[i]);
7979
} else if (data[i].result == NSAPI_ERROR_BUSY) {
80-
printf("DNS: query \"%s\" => busy\n", dns_test_hosts[i]);
80+
tr_error("DNS: query \"%s\" => busy", dns_test_hosts[i]);
8181
}
8282
}
8383

TESTS/netsocket/dns/asynchronous_dns_non_async_and_async.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ void ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC()
3737
for (unsigned int i = 0; i < MBED_CONF_APP_DNS_TEST_HOSTS_NUM; i++) {
3838
SocketAddress addr;
3939
int err = get_interface()->gethostbyname(dns_test_hosts[i], &addr);
40-
printf("DNS: query \"%s\" => \"%s\"\n",
41-
dns_test_hosts[i], addr.get_ip_address());
40+
tr_info("DNS: query \"%s\" => \"%s\"",
41+
dns_test_hosts[i], addr.get_ip_address());
4242

4343
TEST_ASSERT_EQUAL(0, err);
4444
TEST_ASSERT((bool)addr);
@@ -49,8 +49,8 @@ void ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC()
4949

5050
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, data.result);
5151

52-
printf("DNS: query \"%s\" => \"%s\"\n",
53-
dns_test_hosts_second[0], data.addr.get_ip_address());
52+
tr_info("DNS: query \"%s\" => \"%s\"",
53+
dns_test_hosts_second[0], data.addr.get_ip_address());
5454

5555
TEST_ASSERT(strlen(data.addr.get_ip_address()) > 1);
5656
}

TESTS/netsocket/dns/dns_tests.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#ifndef DNS_TESTS_H
1919
#define DNS_TESTS_H
2020

21+
#include "mbed_trace.h"
22+
23+
#define TRACE_GROUP "GRNT"
24+
2125
#ifndef MBED_CONF_APP_DNS_SIMULT_QUERIES
2226
#ifdef MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES
2327
#define MBED_CONF_APP_DNS_SIMULT_QUERIES MBED_CONF_CELLULAR_OFFLOAD_DNS_QUERIES

TESTS/netsocket/dns/main.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,20 @@ void do_asynchronous_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsign
9090
TEST_ASSERT(data[i].result == NSAPI_ERROR_OK || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
9191
if (data[i].result == NSAPI_ERROR_OK) {
9292
(*exp_ok)++;
93-
printf("DNS: query \"%s\" => \"%s\"\n",
94-
hosts[i], data[i].addr.get_ip_address());
93+
tr_info("DNS: query \"%s\" => \"%s\"",
94+
hosts[i], data[i].addr.get_ip_address());
9595
} else if (data[i].result == NSAPI_ERROR_DNS_FAILURE) {
9696
(*exp_dns_failure)++;
97-
printf("DNS: query \"%s\" => DNS failure\n", hosts[i]);
97+
tr_error("DNS: query \"%s\" => DNS failure", hosts[i]);
9898
} else if (data[i].result == NSAPI_ERROR_TIMEOUT) {
9999
(*exp_timeout)++;
100-
printf("DNS: query \"%s\" => timeout\n", hosts[i]);
100+
tr_error("DNS: query \"%s\" => timeout", hosts[i]);
101101
} else if (data[i].result == NSAPI_ERROR_NO_MEMORY) {
102102
(*exp_no_mem)++;
103-
printf("DNS: query \"%s\" => no memory\n", hosts[i]);
103+
tr_error("DNS: query \"%s\" => no memory", hosts[i]);
104104
} else if (data[i].result == NSAPI_ERROR_BUSY) {
105105
(*exp_no_mem)++;
106-
printf("DNS: query \"%s\" => busy\n", hosts[i]);
106+
tr_error("DNS: query \"%s\" => busy", hosts[i]);
107107
}
108108
}
109109

@@ -127,22 +127,22 @@ void do_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsigned int op_cou
127127

128128
if (err == NSAPI_ERROR_OK) {
129129
(*exp_ok)++;
130-
printf("DNS: query \"%s\" => \"%s\"\n",
131-
hosts[i], address.get_ip_address());
130+
tr_info("DNS: query \"%s\" => \"%s\"",
131+
hosts[i], address.get_ip_address());
132132
} else if (err == NSAPI_ERROR_DNS_FAILURE) {
133133
(*exp_dns_failure)++;
134-
printf("DNS: query \"%s\" => DNS failure\n", hosts[i]);
134+
tr_error("DNS: query \"%s\" => DNS failure", hosts[i]);
135135
} else if (err == NSAPI_ERROR_TIMEOUT) {
136136
(*exp_timeout)++;
137-
printf("DNS: query \"%s\" => timeout\n", hosts[i]);
137+
tr_error("DNS: query \"%s\" => timeout", hosts[i]);
138138
} else if (err == NSAPI_ERROR_NO_MEMORY) {
139139
(*exp_no_mem)++;
140-
printf("DNS: query \"%s\" => no memory\n", hosts[i]);
140+
tr_error("DNS: query \"%s\" => no memory", hosts[i]);
141141
} else if (err == NSAPI_ERROR_BUSY) {
142142
(*exp_no_mem)++;
143-
printf("DNS: query \"%s\" => busy\n", hosts[i]);
143+
tr_error("DNS: query \"%s\" => busy", hosts[i]);
144144
} else {
145-
printf("DNS: query \"%s\" => %d, unexpected answer\n", hosts[i], err);
145+
tr_error("DNS: query \"%s\" => %d, unexpected answer", hosts[i], err);
146146
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_BUSY || err == NSAPI_ERROR_DNS_FAILURE || err == NSAPI_ERROR_TIMEOUT);
147147
}
148148
}
@@ -160,13 +160,13 @@ static void net_bringup()
160160
net = NetworkInterface::get_default_instance();
161161
nsapi_error_t err = net->connect();
162162
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
163-
printf("MBED: IP address is '%s'\n", net->get_ip_address() ? net->get_ip_address() : "null");
163+
tr_info("MBED: IP address is '%s'", net->get_ip_address() ? net->get_ip_address() : "null");
164164
}
165165

166166
static void net_bringdown()
167167
{
168168
NetworkInterface::get_default_instance()->disconnect();
169-
printf("MBED: ifdown\n");
169+
tr_info("MBED: ifdown");
170170
}
171171

172172
// Test setup

TESTS/netsocket/dns/synchronous_dns_cache.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ void SYNCHRONOUS_DNS_CACHE()
4949
// Check that cached accesses are at least twice as fast as the first one
5050
TEST_ASSERT_TRUE(i == 0 || delay_ms <= delay_first);
5151

52-
printf("DNS: query \"%s\" => \"%s\", time %i ms\n",
53-
dns_test_hosts[0], address.get_ip_address(), delay_ms);
52+
tr_info("DNS: query \"%s\" => \"%s\", time %i ms",
53+
dns_test_hosts[0], address.get_ip_address(), delay_ms);
5454
}
5555
}

TESTS/netsocket/tcp/main.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ static void _ifup()
7272
NetworkInterface *net = NetworkInterface::get_default_instance();
7373
nsapi_error_t err = net->connect();
7474
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
75-
printf("MBED: TCPClient IP address is '%s'\n", net->get_ip_address() ? net->get_ip_address() : "null");
75+
tr_info("MBED: TCPClient IP address is '%s'", net->get_ip_address() ? net->get_ip_address() : "null");
7676
}
7777

7878
static void _ifdown()
7979
{
8080
NetworkInterface::get_default_instance()->disconnect();
81-
printf("MBED: ifdown\n");
81+
tr_info("MBED: ifdown");
8282
}
8383

8484
nsapi_error_t tcpsocket_connect_to_srv(TCPSocket &sock, uint16_t port)
@@ -88,17 +88,17 @@ nsapi_error_t tcpsocket_connect_to_srv(TCPSocket &sock, uint16_t port)
8888
NetworkInterface::get_default_instance()->gethostbyname(ECHO_SERVER_ADDR, &tcp_addr);
8989
tcp_addr.set_port(port);
9090

91-
printf("MBED: Server '%s', port %d\n", tcp_addr.get_ip_address(), tcp_addr.get_port());
91+
tr_info("MBED: Server '%s', port %d", tcp_addr.get_ip_address(), tcp_addr.get_port());
9292

9393
nsapi_error_t err = sock.open(NetworkInterface::get_default_instance());
9494
if (err != NSAPI_ERROR_OK) {
95-
printf("Error from sock.open: %d\n", err);
95+
tr_error("Error from sock.open: %d", err);
9696
return err;
9797
}
9898

9999
err = sock.connect(tcp_addr);
100100
if (err != NSAPI_ERROR_OK) {
101-
printf("Error from sock.connect: %d\n", err);
101+
tr_error("Error from sock.connect: %d", err);
102102
return err;
103103
}
104104

TESTS/netsocket/tcp/tcp_tests.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#define TCP_TESTS_H
2020

2121
#include "../test_params.h"
22+
#include "mbed_trace.h"
23+
24+
#define TRACE_GROUP "GRNT"
2225

2326
NetworkInterface *get_interface();
2427
void drop_bad_packets(TCPSocket &sock, int orig_timeout);

0 commit comments

Comments
 (0)