1c87c5fbaSopenharmony_ci/*
2c87c5fbaSopenharmony_ci* examples_code_check.c -- Validate the code in EXAMPLES of the man pages
3c87c5fbaSopenharmony_ci*
4c87c5fbaSopenharmony_ci* Exits with a non-zero value if there is a coding error.
5c87c5fbaSopenharmony_ci*
6c87c5fbaSopenharmony_ci* Copyright (C) 2020-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
7c87c5fbaSopenharmony_ci*
8c87c5fbaSopenharmony_ci* SPDX-License-Identifier: BSD-2-Clause
9c87c5fbaSopenharmony_ci*
10c87c5fbaSopenharmony_ci* This file is part of the CoAP library libcoap. Please see README for terms
11c87c5fbaSopenharmony_ci* of use.
12c87c5fbaSopenharmony_ci*/
13c87c5fbaSopenharmony_ci
14c87c5fbaSopenharmony_ci#include <unistd.h>
15c87c5fbaSopenharmony_ci#include <stdio.h>
16c87c5fbaSopenharmony_ci#include <stdlib.h>
17c87c5fbaSopenharmony_ci#include <sys/stat.h>
18c87c5fbaSopenharmony_ci#include <sys/types.h>
19c87c5fbaSopenharmony_ci#include <dirent.h>
20c87c5fbaSopenharmony_ci#include <errno.h>
21c87c5fbaSopenharmony_ci#include <string.h>
22c87c5fbaSopenharmony_ci
23c87c5fbaSopenharmony_ci#ifdef _WIN32
24c87c5fbaSopenharmony_ci#define GCC_OPTIONS "-I../include"
25c87c5fbaSopenharmony_ci#ifndef WEXITSTATUS
26c87c5fbaSopenharmony_ci#define WEXITSTATUS(v) (v & 0xff)
27c87c5fbaSopenharmony_ci#endif /* WEXITSTATUS */
28c87c5fbaSopenharmony_ci#else /* ! _WIN32 */
29c87c5fbaSopenharmony_ci#define GCC_OPTIONS "\
30c87c5fbaSopenharmony_ci  -I../include \
31c87c5fbaSopenharmony_ci  -std=c99 \
32c87c5fbaSopenharmony_ci  -g \
33c87c5fbaSopenharmony_ci  -O2 \
34c87c5fbaSopenharmony_ci  -pedantic \
35c87c5fbaSopenharmony_ci  -Wall \
36c87c5fbaSopenharmony_ci  -Wcast-qual \
37c87c5fbaSopenharmony_ci  -Wextra \
38c87c5fbaSopenharmony_ci  -Wformat-security \
39c87c5fbaSopenharmony_ci  -Winline \
40c87c5fbaSopenharmony_ci  -Wmissing-declarations \
41c87c5fbaSopenharmony_ci  -Wmissing-prototypes \
42c87c5fbaSopenharmony_ci  -Wnested-externs \
43c87c5fbaSopenharmony_ci  -Wpointer-arith \
44c87c5fbaSopenharmony_ci  -Wshadow \
45c87c5fbaSopenharmony_ci  -Wstrict-prototypes \
46c87c5fbaSopenharmony_ci  -Wswitch-default \
47c87c5fbaSopenharmony_ci  -Wswitch-enum \
48c87c5fbaSopenharmony_ci  -Wunused \
49c87c5fbaSopenharmony_ci  -Wwrite-strings \
50c87c5fbaSopenharmony_ci  -Wno-unused-function \
51c87c5fbaSopenharmony_ci  -Wno-unused-but-set-variable \
52c87c5fbaSopenharmony_ci  -Werror \
53c87c5fbaSopenharmony_ci"
54c87c5fbaSopenharmony_ci#endif /* ! _WIN32 */
55c87c5fbaSopenharmony_ci
56c87c5fbaSopenharmony_ciconst char *inline_list[] = {
57c87c5fbaSopenharmony_ci  "coap_free(",
58c87c5fbaSopenharmony_ci  "coap_malloc(",
59c87c5fbaSopenharmony_ci  "coap_encode_var_bytes(",
60c87c5fbaSopenharmony_ci  "coap_option_clrb(",
61c87c5fbaSopenharmony_ci  "coap_option_getb(",
62c87c5fbaSopenharmony_ci  "coap_option_setb(",
63c87c5fbaSopenharmony_ci  "coap_read(",
64c87c5fbaSopenharmony_ci  "coap_run_once(",
65c87c5fbaSopenharmony_ci  "coap_write(",
66c87c5fbaSopenharmony_ci};
67c87c5fbaSopenharmony_ci
68c87c5fbaSopenharmony_ciconst char *define_list[] = {
69c87c5fbaSopenharmony_ci  "coap_string_equal(",
70c87c5fbaSopenharmony_ci  "coap_binary_equal(",
71c87c5fbaSopenharmony_ci  "coap_log(",
72c87c5fbaSopenharmony_ci  "coap_log_emerg(",
73c87c5fbaSopenharmony_ci  "coap_log_alert(",
74c87c5fbaSopenharmony_ci  "coap_log_crit(",
75c87c5fbaSopenharmony_ci  "coap_log_err(",
76c87c5fbaSopenharmony_ci  "coap_log_warn(",
77c87c5fbaSopenharmony_ci  "coap_log_info(",
78c87c5fbaSopenharmony_ci  "coap_log_notice(",
79c87c5fbaSopenharmony_ci  "coap_log_debug(",
80c87c5fbaSopenharmony_ci  "coap_log_oscore(",
81c87c5fbaSopenharmony_ci  "coap_dtls_log(",
82c87c5fbaSopenharmony_ci};
83c87c5fbaSopenharmony_ci
84c87c5fbaSopenharmony_ci/* xxx *function */
85c87c5fbaSopenharmony_ciconst char *pointer_list[] = {
86c87c5fbaSopenharmony_ci  "char ",
87c87c5fbaSopenharmony_ci  "coap_addr_info_t ",
88c87c5fbaSopenharmony_ci  "coap_async_t ",
89c87c5fbaSopenharmony_ci  "coap_attr_t ",
90c87c5fbaSopenharmony_ci  "coap_bin_const_t ",
91c87c5fbaSopenharmony_ci  "coap_binary_t ",
92c87c5fbaSopenharmony_ci  "coap_cache_entry_t ",
93c87c5fbaSopenharmony_ci  "coap_cache_key_t ",
94c87c5fbaSopenharmony_ci  "coap_endpoint_t ",
95c87c5fbaSopenharmony_ci  "coap_context_t ",
96c87c5fbaSopenharmony_ci  "coap_fixed_point_t ",
97c87c5fbaSopenharmony_ci  "coap_oscore_conf_t ",
98c87c5fbaSopenharmony_ci  "coap_optlist_t ",
99c87c5fbaSopenharmony_ci  "coap_session_t ",
100c87c5fbaSopenharmony_ci  "coap_string_t ",
101c87c5fbaSopenharmony_ci  "coap_str_const_t ",
102c87c5fbaSopenharmony_ci  "coap_opt_iterator_t ",
103c87c5fbaSopenharmony_ci  "coap_opt_t ",
104c87c5fbaSopenharmony_ci  "coap_pdu_t ",
105c87c5fbaSopenharmony_ci  "coap_resource_t ",
106c87c5fbaSopenharmony_ci  "coap_subscription_t ",
107c87c5fbaSopenharmony_ci  "coap_tls_version_t ",
108c87c5fbaSopenharmony_ci  "coap_uri_t ",
109c87c5fbaSopenharmony_ci  "const char ",
110c87c5fbaSopenharmony_ci  "const coap_address_t ",
111c87c5fbaSopenharmony_ci  "const coap_bin_const_t ",
112c87c5fbaSopenharmony_ci  "const coap_pdu_t ",
113c87c5fbaSopenharmony_ci};
114c87c5fbaSopenharmony_ci
115c87c5fbaSopenharmony_ci/* xxx function */
116c87c5fbaSopenharmony_ciconst char *number_list[] = {
117c87c5fbaSopenharmony_ci  "coap_log_t ",
118c87c5fbaSopenharmony_ci  "coap_pdu_type_t ",
119c87c5fbaSopenharmony_ci  "coap_mid_t ",
120c87c5fbaSopenharmony_ci  "coap_pdu_code_t ",
121c87c5fbaSopenharmony_ci  "coap_proto_t ",
122c87c5fbaSopenharmony_ci  "coap_session_state_t ",
123c87c5fbaSopenharmony_ci  "coap_session_type_t ",
124c87c5fbaSopenharmony_ci  "int ",
125c87c5fbaSopenharmony_ci  "uint16_t ",
126c87c5fbaSopenharmony_ci  "uint32_t ",
127c87c5fbaSopenharmony_ci  "uint64_t ",
128c87c5fbaSopenharmony_ci  "unsigned int ",
129c87c5fbaSopenharmony_ci  "size_t ",
130c87c5fbaSopenharmony_ci  "const uint8_t ",
131c87c5fbaSopenharmony_ci};
132c87c5fbaSopenharmony_ci
133c87c5fbaSopenharmony_ciconst char *return_void_list[] = {
134c87c5fbaSopenharmony_ci  "coap_option_filter_set",
135c87c5fbaSopenharmony_ci  "coap_resource_set_userdata",
136c87c5fbaSopenharmony_ci  "coap_cache_set_app_data",
137c87c5fbaSopenharmony_ci};
138c87c5fbaSopenharmony_ci
139c87c5fbaSopenharmony_ciint exit_code = 0;
140c87c5fbaSopenharmony_ci
141c87c5fbaSopenharmony_cistatic char name_list[100][100];
142c87c5fbaSopenharmony_cistatic unsigned int name_cnt = 0;
143c87c5fbaSopenharmony_cistatic char return_list[100][100];
144c87c5fbaSopenharmony_cistatic unsigned int return_cnt = 0;
145c87c5fbaSopenharmony_cistatic char man_list[400][100];
146c87c5fbaSopenharmony_cistatic unsigned int man_cnt = 0;
147c87c5fbaSopenharmony_ci
148c87c5fbaSopenharmony_cistatic void
149c87c5fbaSopenharmony_cicheck_synopsis(const char *file) {
150c87c5fbaSopenharmony_ci  char buffer[1024];
151c87c5fbaSopenharmony_ci  char file_name[300];
152c87c5fbaSopenharmony_ci  FILE *fpcode;
153c87c5fbaSopenharmony_ci  int  status;
154c87c5fbaSopenharmony_ci
155c87c5fbaSopenharmony_ci  snprintf(file_name, sizeof(file_name), "tmp/%s-header.c", file);
156c87c5fbaSopenharmony_ci  fpcode = fopen(file_name, "w");
157c87c5fbaSopenharmony_ci  if (!fpcode) {
158c87c5fbaSopenharmony_ci    fprintf(stderr, "fopen: %s: %s (%d)\n", file_name, strerror(errno), errno);
159c87c5fbaSopenharmony_ci    exit_code = 1;
160c87c5fbaSopenharmony_ci    return;
161c87c5fbaSopenharmony_ci  }
162c87c5fbaSopenharmony_ci  fprintf(fpcode, "#include <coap3/coap.h>\n");
163c87c5fbaSopenharmony_ci  fprintf(fpcode, "#ifdef __GNUC__\n");
164c87c5fbaSopenharmony_ci  fprintf(fpcode, "#define U __attribute__ ((unused))\n");
165c87c5fbaSopenharmony_ci  fprintf(fpcode, "#else /* not a GCC */\n");
166c87c5fbaSopenharmony_ci  fprintf(fpcode, "#define U\n");
167c87c5fbaSopenharmony_ci  fprintf(fpcode, "#endif /* GCC */\n");
168c87c5fbaSopenharmony_ci  fprintf(fpcode, "\n");
169c87c5fbaSopenharmony_ci  fprintf(fpcode, "#include \"%s.h\"\n", file);
170c87c5fbaSopenharmony_ci  fclose(fpcode);
171c87c5fbaSopenharmony_ci  file_name[strlen(file_name)-1] = '\000';
172c87c5fbaSopenharmony_ci  snprintf(buffer, sizeof(buffer),
173c87c5fbaSopenharmony_ci           "gcc " GCC_OPTIONS " -c %sc -o %so",
174c87c5fbaSopenharmony_ci           file_name, file_name);
175c87c5fbaSopenharmony_ci  status = system(buffer);
176c87c5fbaSopenharmony_ci  if (WEXITSTATUS(status)) {
177c87c5fbaSopenharmony_ci    exit_code = WEXITSTATUS(status);
178c87c5fbaSopenharmony_ci  }
179c87c5fbaSopenharmony_ci  return;
180c87c5fbaSopenharmony_ci}
181c87c5fbaSopenharmony_ci
182c87c5fbaSopenharmony_cistatic void
183c87c5fbaSopenharmony_cidump_name_synopsis_mismatch(void) {
184c87c5fbaSopenharmony_ci  unsigned int i;
185c87c5fbaSopenharmony_ci
186c87c5fbaSopenharmony_ci  for (i = 0; i < name_cnt; i++) {
187c87c5fbaSopenharmony_ci    if (name_list[i][0] != '\000') {
188c87c5fbaSopenharmony_ci      fprintf(stderr, "NAME: %s not in SYNOPSIS or pointer_list[]\n", name_list[i]);
189c87c5fbaSopenharmony_ci      exit_code = 1;
190c87c5fbaSopenharmony_ci    }
191c87c5fbaSopenharmony_ci  }
192c87c5fbaSopenharmony_ci  name_cnt = 0;
193c87c5fbaSopenharmony_ci}
194c87c5fbaSopenharmony_ci
195c87c5fbaSopenharmony_cistatic void
196c87c5fbaSopenharmony_cidump_return_synopsis_mismatch(void) {
197c87c5fbaSopenharmony_ci  unsigned int i;
198c87c5fbaSopenharmony_ci
199c87c5fbaSopenharmony_ci  for (i = 0; i < return_cnt; i++) {
200c87c5fbaSopenharmony_ci    if (return_list[i][0] != '\000') {
201c87c5fbaSopenharmony_ci      fprintf(stderr, "SYNOPSIS: %s not in RETURN VALUES\n", return_list[i]);
202c87c5fbaSopenharmony_ci      exit_code = 1;
203c87c5fbaSopenharmony_ci    }
204c87c5fbaSopenharmony_ci  }
205c87c5fbaSopenharmony_ci  return_cnt = 0;
206c87c5fbaSopenharmony_ci}
207c87c5fbaSopenharmony_ci
208c87c5fbaSopenharmony_ci/*
209c87c5fbaSopenharmony_ci * It is assumed for a definition that a leading * and trailing * have been
210c87c5fbaSopenharmony_ci * added to buffer.
211c87c5fbaSopenharmony_ci */
212c87c5fbaSopenharmony_cistatic void
213c87c5fbaSopenharmony_cidecode_synopsis_definition(FILE *fpheader, const char *buffer, int in_synopsis) {
214c87c5fbaSopenharmony_ci  size_t len;
215c87c5fbaSopenharmony_ci  char outbuf[1024];
216c87c5fbaSopenharmony_ci  const char *cp;
217c87c5fbaSopenharmony_ci  const char *ecp;
218c87c5fbaSopenharmony_ci  int is_void_func = 0;
219c87c5fbaSopenharmony_ci  int is_number_func = 0;
220c87c5fbaSopenharmony_ci  int is_inline_func = 0;
221c87c5fbaSopenharmony_ci  int is_struct_func = 0;
222c87c5fbaSopenharmony_ci  const char *func_start = NULL;
223c87c5fbaSopenharmony_ci  int is_struct = 0;
224c87c5fbaSopenharmony_ci  unsigned int i;
225c87c5fbaSopenharmony_ci
226c87c5fbaSopenharmony_ci  if (strncmp(buffer, "*void ", sizeof("*void ")-1) == 0) {
227c87c5fbaSopenharmony_ci    if (strncmp(buffer, "*void *", sizeof("*void *")-1) == 0) {
228c87c5fbaSopenharmony_ci      func_start = &buffer[sizeof("*void *")-1];
229c87c5fbaSopenharmony_ci    } else {
230c87c5fbaSopenharmony_ci      is_void_func = 1;
231c87c5fbaSopenharmony_ci      func_start = &buffer[sizeof("*void ")-1];
232c87c5fbaSopenharmony_ci    }
233c87c5fbaSopenharmony_ci  }
234c87c5fbaSopenharmony_ci
235c87c5fbaSopenharmony_ci  for (i = 0; i < sizeof(number_list)/sizeof(number_list[0]); i++) {
236c87c5fbaSopenharmony_ci    if (strncmp(&buffer[1], number_list[i],
237c87c5fbaSopenharmony_ci                strlen(number_list[i])) == 0) {
238c87c5fbaSopenharmony_ci      if (buffer[1 + strlen(number_list[i])] == '*') {
239c87c5fbaSopenharmony_ci        func_start = &buffer[2 + strlen(number_list[i])];
240c87c5fbaSopenharmony_ci      } else {
241c87c5fbaSopenharmony_ci        is_number_func = 1;
242c87c5fbaSopenharmony_ci        func_start = &buffer[1 + strlen(number_list[i])];
243c87c5fbaSopenharmony_ci      }
244c87c5fbaSopenharmony_ci      break;
245c87c5fbaSopenharmony_ci    }
246c87c5fbaSopenharmony_ci  }
247c87c5fbaSopenharmony_ci
248c87c5fbaSopenharmony_ci  for (i = 0; i < sizeof(pointer_list)/sizeof(pointer_list[0]); i++) {
249c87c5fbaSopenharmony_ci    if (strncmp(&buffer[1], pointer_list[i],
250c87c5fbaSopenharmony_ci                strlen(pointer_list[i])) == 0) {
251c87c5fbaSopenharmony_ci      if (buffer[1 + strlen(pointer_list[i])] == '*') {
252c87c5fbaSopenharmony_ci        func_start = &buffer[2 + strlen(pointer_list[i])];
253c87c5fbaSopenharmony_ci      } else {
254c87c5fbaSopenharmony_ci        is_struct_func = i + 1;
255c87c5fbaSopenharmony_ci        func_start = &buffer[1 + strlen(pointer_list[i])];
256c87c5fbaSopenharmony_ci      }
257c87c5fbaSopenharmony_ci      break;
258c87c5fbaSopenharmony_ci    }
259c87c5fbaSopenharmony_ci  }
260c87c5fbaSopenharmony_ci
261c87c5fbaSopenharmony_ci  if (strncmp(buffer, "*struct ", sizeof("*struct ")-1) == 0) {
262c87c5fbaSopenharmony_ci    is_struct = 1;
263c87c5fbaSopenharmony_ci    func_start = &buffer[sizeof("*struct ")-1];
264c87c5fbaSopenharmony_ci  }
265c87c5fbaSopenharmony_ci
266c87c5fbaSopenharmony_ci  if (func_start) {
267c87c5fbaSopenharmony_ci    /* see if COAP_STATIC_INLINE function */
268c87c5fbaSopenharmony_ci    for (i = 0; i < sizeof(inline_list)/sizeof(inline_list[0]); i++) {
269c87c5fbaSopenharmony_ci      if (strncmp(func_start, inline_list[i],
270c87c5fbaSopenharmony_ci                  strlen(inline_list[i])) == 0) {
271c87c5fbaSopenharmony_ci        is_inline_func = 1;
272c87c5fbaSopenharmony_ci        break;
273c87c5fbaSopenharmony_ci      }
274c87c5fbaSopenharmony_ci    }
275c87c5fbaSopenharmony_ci    /* see if #define function */
276c87c5fbaSopenharmony_ci    for (i = 0; i < sizeof(define_list)/sizeof(define_list[0]); i++) {
277c87c5fbaSopenharmony_ci      if (strncmp(func_start, define_list[i], strlen(define_list[i])) == 0) {
278c87c5fbaSopenharmony_ci        break;
279c87c5fbaSopenharmony_ci      }
280c87c5fbaSopenharmony_ci    }
281c87c5fbaSopenharmony_ci    if (i != sizeof(define_list)/sizeof(define_list[0]))
282c87c5fbaSopenharmony_ci      goto cleanup;
283c87c5fbaSopenharmony_ci  }
284c87c5fbaSopenharmony_ci
285c87c5fbaSopenharmony_ci  /* Need to include use of U for unused parameters just before comma */
286c87c5fbaSopenharmony_ci  cp = buffer;
287c87c5fbaSopenharmony_ci  ecp = strchr(cp, ',');
288c87c5fbaSopenharmony_ci  if (!ecp)
289c87c5fbaSopenharmony_ci    ecp = strchr(cp, ')');
290c87c5fbaSopenharmony_ci  outbuf[0] = '\000';
291c87c5fbaSopenharmony_ci  while (ecp) {
292c87c5fbaSopenharmony_ci    len = strlen(outbuf);
293c87c5fbaSopenharmony_ci    if (strncmp(cp, "void", ecp-cp) == 0)
294c87c5fbaSopenharmony_ci      snprintf(&outbuf[len], sizeof(outbuf)-len, "%*.*s%c",
295c87c5fbaSopenharmony_ci               (int)(ecp-cp), (int)(ecp-cp), cp, *ecp);
296c87c5fbaSopenharmony_ci    else
297c87c5fbaSopenharmony_ci      snprintf(&outbuf[len], sizeof(outbuf)-len, "%*.*s U%c",
298c87c5fbaSopenharmony_ci               (int)(ecp-cp), (int)(ecp-cp), cp, *ecp);
299c87c5fbaSopenharmony_ci    cp = ecp+1;
300c87c5fbaSopenharmony_ci    if (*cp) {
301c87c5fbaSopenharmony_ci      ecp = strchr(cp, ',');
302c87c5fbaSopenharmony_ci      if (!ecp)
303c87c5fbaSopenharmony_ci        ecp = strchr(cp, ')');
304c87c5fbaSopenharmony_ci    } else {
305c87c5fbaSopenharmony_ci      ecp = NULL;
306c87c5fbaSopenharmony_ci    }
307c87c5fbaSopenharmony_ci  }
308c87c5fbaSopenharmony_ci  if (*cp) {
309c87c5fbaSopenharmony_ci    len = strlen(outbuf);
310c87c5fbaSopenharmony_ci    snprintf(&outbuf[len], sizeof(outbuf)-len, "%s", cp);
311c87c5fbaSopenharmony_ci  }
312c87c5fbaSopenharmony_ci
313c87c5fbaSopenharmony_ci  len = strlen(outbuf);
314c87c5fbaSopenharmony_ci  if (len > 3 && ((outbuf[len-3] == ';' && outbuf[len-2] == '*') ||
315c87c5fbaSopenharmony_ci                  (outbuf[len-3] == '*' && outbuf[len-2] == ';'))) {
316c87c5fbaSopenharmony_ci    if (is_inline_func) {
317c87c5fbaSopenharmony_ci      strcpy(&outbuf[len-3], ";\n");
318c87c5fbaSopenharmony_ci    }
319c87c5fbaSopenharmony_ci    /* Replace ;* or *; with simple function definition */
320c87c5fbaSopenharmony_ci    else if (is_void_func) {
321c87c5fbaSopenharmony_ci      strcpy(&outbuf[len-3], "{}\n");
322c87c5fbaSopenharmony_ci    } else if (is_number_func) {
323c87c5fbaSopenharmony_ci      strcpy(&outbuf[len-3], "{return 0;}\n");
324c87c5fbaSopenharmony_ci    } else if (is_struct_func) {
325c87c5fbaSopenharmony_ci      snprintf(&outbuf[len-3], sizeof(outbuf)-(len-3),
326c87c5fbaSopenharmony_ci               "{%s v; memset(&v, 0, sizeof(v)); return v;}\n",
327c87c5fbaSopenharmony_ci               pointer_list[is_struct_func - 1]);
328c87c5fbaSopenharmony_ci    } else if (is_struct) {
329c87c5fbaSopenharmony_ci      strcpy(&outbuf[len-3], ";\n");
330c87c5fbaSopenharmony_ci    } else {
331c87c5fbaSopenharmony_ci      strcpy(&outbuf[len-3], "{return NULL;}\n");
332c87c5fbaSopenharmony_ci    }
333c87c5fbaSopenharmony_ci  }
334c87c5fbaSopenharmony_ci  if (outbuf[0] == '*') {
335c87c5fbaSopenharmony_ci    fprintf(fpheader, "%s", &outbuf[1]);
336c87c5fbaSopenharmony_ci  } else {
337c87c5fbaSopenharmony_ci    fprintf(fpheader, "%s", outbuf);
338c87c5fbaSopenharmony_ci  }
339c87c5fbaSopenharmony_cicleanup:
340c87c5fbaSopenharmony_ci  if (in_synopsis && func_start) {
341c87c5fbaSopenharmony_ci    char *wcp = strchr(func_start, '(');
342c87c5fbaSopenharmony_ci
343c87c5fbaSopenharmony_ci    if (!wcp && is_struct)
344c87c5fbaSopenharmony_ci      wcp = strchr(func_start, ';');
345c87c5fbaSopenharmony_ci    if (!wcp) {
346c87c5fbaSopenharmony_ci      wcp = strchr(func_start, '\n');
347c87c5fbaSopenharmony_ci      if (wcp)
348c87c5fbaSopenharmony_ci        *wcp = '\000';
349c87c5fbaSopenharmony_ci      fprintf(stderr, "SYNOPSIS: function %s issue\n", func_start);
350c87c5fbaSopenharmony_ci      return;
351c87c5fbaSopenharmony_ci    }
352c87c5fbaSopenharmony_ci    *wcp = '\000';
353c87c5fbaSopenharmony_ci    for (i = 0; i < name_cnt; i++) {
354c87c5fbaSopenharmony_ci      if (strcmp(name_list[i], func_start) == 0) {
355c87c5fbaSopenharmony_ci        name_list[i][0] = '\000';
356c87c5fbaSopenharmony_ci        break;
357c87c5fbaSopenharmony_ci      }
358c87c5fbaSopenharmony_ci    }
359c87c5fbaSopenharmony_ci    if (i == name_cnt) {
360c87c5fbaSopenharmony_ci      fprintf(stderr, "SYNOPSIS: %s not in NAME\n", func_start);
361c87c5fbaSopenharmony_ci      exit_code = 1;
362c87c5fbaSopenharmony_ci    }
363c87c5fbaSopenharmony_ci    if (!is_void_func && !is_struct) {
364c87c5fbaSopenharmony_ci      for (i = 0; i < return_cnt; i++) {
365c87c5fbaSopenharmony_ci        if (strcmp(func_start, return_list[i]) == 0) {
366c87c5fbaSopenharmony_ci          fprintf(stderr, "SYNOPSIS: %s duplicated\n", func_start);
367c87c5fbaSopenharmony_ci          break;
368c87c5fbaSopenharmony_ci        }
369c87c5fbaSopenharmony_ci      }
370c87c5fbaSopenharmony_ci      if (i != return_cnt)
371c87c5fbaSopenharmony_ci        return;
372c87c5fbaSopenharmony_ci      if (i >= (int)(sizeof(return_list)/sizeof(return_list[0]))) {
373c87c5fbaSopenharmony_ci        fprintf(stderr, "SYNOPSIS: %s insufficient space (%u >= %u)\n", func_start,
374c87c5fbaSopenharmony_ci                i, (int)(sizeof(return_list)/sizeof(return_list[0])));
375c87c5fbaSopenharmony_ci        return;
376c87c5fbaSopenharmony_ci      }
377c87c5fbaSopenharmony_ci      strncpy(return_list[i], func_start, sizeof(return_list[i])-1);
378c87c5fbaSopenharmony_ci      return_cnt++;
379c87c5fbaSopenharmony_ci    }
380c87c5fbaSopenharmony_ci  }
381c87c5fbaSopenharmony_ci  return;
382c87c5fbaSopenharmony_ci}
383c87c5fbaSopenharmony_ci
384c87c5fbaSopenharmony_ciint
385c87c5fbaSopenharmony_cimain(int argc, char *argv[]) {
386c87c5fbaSopenharmony_ci  DIR *pdir;
387c87c5fbaSopenharmony_ci  struct dirent *pdir_ent;
388c87c5fbaSopenharmony_ci  char buffer[1024];
389c87c5fbaSopenharmony_ci  char man_name[1024];
390c87c5fbaSopenharmony_ci  int  status;
391c87c5fbaSopenharmony_ci  size_t i;
392c87c5fbaSopenharmony_ci  int man_missing_first = 1;
393c87c5fbaSopenharmony_ci
394c87c5fbaSopenharmony_ci  if (argc != 2 && argc != 3) {
395c87c5fbaSopenharmony_ci    fprintf(stderr, "usage: %s man_directory [libcoap-3.sym_file]\n", argv[0]);
396c87c5fbaSopenharmony_ci    exit(1);
397c87c5fbaSopenharmony_ci  }
398c87c5fbaSopenharmony_ci
399c87c5fbaSopenharmony_ci  pdir = opendir(argv[1]);
400c87c5fbaSopenharmony_ci  if (pdir == NULL) {
401c87c5fbaSopenharmony_ci    fprintf(stderr, "opendir: %s: %s (%d)\n", argv[1], strerror(errno), errno);
402c87c5fbaSopenharmony_ci    exit(1);
403c87c5fbaSopenharmony_ci  }
404c87c5fbaSopenharmony_ci  if (argc == 3) {
405c87c5fbaSopenharmony_ci    FILE *fp = fopen(argv[2], "r");
406c87c5fbaSopenharmony_ci    char tmp_name[100];
407c87c5fbaSopenharmony_ci
408c87c5fbaSopenharmony_ci    if (fp == NULL) {
409c87c5fbaSopenharmony_ci      fprintf(stderr, "fopen: %s: %s (%d)\n", argv[2], strerror(errno), errno);
410c87c5fbaSopenharmony_ci      exit(1);
411c87c5fbaSopenharmony_ci    }
412c87c5fbaSopenharmony_ci    while (fgets(tmp_name, sizeof(tmp_name), fp) != NULL) {
413c87c5fbaSopenharmony_ci      char *cp = strchr(tmp_name, '\n');
414c87c5fbaSopenharmony_ci
415c87c5fbaSopenharmony_ci      if (cp)
416c87c5fbaSopenharmony_ci        *cp = '\000';
417c87c5fbaSopenharmony_ci      if (tmp_name[0]) {
418c87c5fbaSopenharmony_ci        strncpy(man_list[man_cnt], tmp_name, sizeof(man_list[man_cnt]));
419c87c5fbaSopenharmony_ci        man_cnt++;
420c87c5fbaSopenharmony_ci      }
421c87c5fbaSopenharmony_ci      if (man_cnt == sizeof(man_list) / sizeof(name_list[0])) {
422c87c5fbaSopenharmony_ci        fprintf(stderr, "man_list[] too small (%zd) for entries from %s\n",
423c87c5fbaSopenharmony_ci                sizeof(man_list) / sizeof(name_list[0]), argv[2]);
424c87c5fbaSopenharmony_ci        exit(1);
425c87c5fbaSopenharmony_ci      }
426c87c5fbaSopenharmony_ci    }
427c87c5fbaSopenharmony_ci    fclose(fp);
428c87c5fbaSopenharmony_ci  }
429c87c5fbaSopenharmony_ci  if (chdir(argv[1]) == -1) {
430c87c5fbaSopenharmony_ci    fprintf(stderr, "chdir: %s: %s (%d)\n", argv[1], strerror(errno), errno);
431c87c5fbaSopenharmony_ci    exit(1);
432c87c5fbaSopenharmony_ci  }
433c87c5fbaSopenharmony_ci#if defined(WIN32) || defined(__MINGW32__)
434c87c5fbaSopenharmony_ci  if (mkdir("tmp") == -1 && errno != EEXIST) {
435c87c5fbaSopenharmony_ci    fprintf(stderr, "mkdir: %s: %s (%d)\n", "tmp", strerror(errno), errno);
436c87c5fbaSopenharmony_ci    exit(1);
437c87c5fbaSopenharmony_ci  }
438c87c5fbaSopenharmony_ci#else /* ! WIN32 && ! __MINGW32__ */
439c87c5fbaSopenharmony_ci  if (mkdir("tmp", 0777) == -1 && errno != EEXIST) {
440c87c5fbaSopenharmony_ci    fprintf(stderr, "mkdir: %s: %s (%d)\n", "tmp", strerror(errno), errno);
441c87c5fbaSopenharmony_ci    exit(1);
442c87c5fbaSopenharmony_ci  }
443c87c5fbaSopenharmony_ci#endif /* ! WIN32 && ! __MINGW32__ */
444c87c5fbaSopenharmony_ci
445c87c5fbaSopenharmony_ci  while ((pdir_ent = readdir(pdir)) != NULL) {
446c87c5fbaSopenharmony_ci    if (!strncmp(pdir_ent->d_name, "coap_", sizeof("coap_")-1) &&
447c87c5fbaSopenharmony_ci        strstr(pdir_ent->d_name, ".txt.in")) {
448c87c5fbaSopenharmony_ci      FILE  *fp;
449c87c5fbaSopenharmony_ci      int skip = 1;
450c87c5fbaSopenharmony_ci      int in_examples = 0;
451c87c5fbaSopenharmony_ci      int in_synopsis = 0;
452c87c5fbaSopenharmony_ci      int in_functions = 0;
453c87c5fbaSopenharmony_ci      int in_name = 0;
454c87c5fbaSopenharmony_ci      int in_return = 0;
455c87c5fbaSopenharmony_ci      int count = 1;
456c87c5fbaSopenharmony_ci      char keep_line[1024] = {0};
457c87c5fbaSopenharmony_ci      FILE *fpcode = NULL;
458c87c5fbaSopenharmony_ci      FILE *fpheader = NULL;
459c87c5fbaSopenharmony_ci      char file_name[300];
460c87c5fbaSopenharmony_ci      char *cp;
461c87c5fbaSopenharmony_ci
462c87c5fbaSopenharmony_ci      fprintf(stderr, "Processing: %s\n", pdir_ent->d_name);
463c87c5fbaSopenharmony_ci
464c87c5fbaSopenharmony_ci      snprintf(man_name, sizeof(man_name), "%s", pdir_ent->d_name);
465c87c5fbaSopenharmony_ci      fp = fopen(man_name, "r");
466c87c5fbaSopenharmony_ci      if (fp == NULL) {
467c87c5fbaSopenharmony_ci        fprintf(stderr, "fopen: %s: %s (%d)\n", man_name, strerror(errno), errno);
468c87c5fbaSopenharmony_ci        continue;
469c87c5fbaSopenharmony_ci      }
470c87c5fbaSopenharmony_ci      cp = strstr(man_name, ".txt.in");
471c87c5fbaSopenharmony_ci      if (cp)
472c87c5fbaSopenharmony_ci        *cp = '\000';
473c87c5fbaSopenharmony_ci      name_cnt = 0;
474c87c5fbaSopenharmony_ci      while (fgets(buffer, sizeof(buffer), fp) != NULL) {
475c87c5fbaSopenharmony_ci        if (strncmp(buffer, "NAME", sizeof("NAME")-1) == 0) {
476c87c5fbaSopenharmony_ci          in_name = 1;
477c87c5fbaSopenharmony_ci          continue;
478c87c5fbaSopenharmony_ci        }
479c87c5fbaSopenharmony_ci        if (strncmp(buffer, "SYNOPSIS", sizeof("SYNOPSIS")-1) == 0) {
480c87c5fbaSopenharmony_ci          in_name = 0;
481c87c5fbaSopenharmony_ci          in_synopsis = 1;
482c87c5fbaSopenharmony_ci          snprintf(file_name, sizeof(file_name), "tmp/%s.h",
483c87c5fbaSopenharmony_ci                   pdir_ent->d_name);
484c87c5fbaSopenharmony_ci          fpheader = fopen(file_name, "w");
485c87c5fbaSopenharmony_ci          if (!fpheader) {
486c87c5fbaSopenharmony_ci            fprintf(stderr, "fopen: %s: %s (%d)\n", file_name,
487c87c5fbaSopenharmony_ci                    strerror(errno), errno);
488c87c5fbaSopenharmony_ci            goto bad;
489c87c5fbaSopenharmony_ci          }
490c87c5fbaSopenharmony_ci          continue;
491c87c5fbaSopenharmony_ci        }
492c87c5fbaSopenharmony_ci        if (strncmp(buffer, "FUNCTIONS", sizeof("FUNCTIONS")-1) == 0) {
493c87c5fbaSopenharmony_ci          in_synopsis = 0;
494c87c5fbaSopenharmony_ci          dump_name_synopsis_mismatch();
495c87c5fbaSopenharmony_ci          in_functions = 1;
496c87c5fbaSopenharmony_ci          snprintf(file_name, sizeof(file_name), "tmp/%s.h",
497c87c5fbaSopenharmony_ci                   pdir_ent->d_name);
498c87c5fbaSopenharmony_ci          fpheader = fopen(file_name, "w");
499c87c5fbaSopenharmony_ci          if (!fpheader) {
500c87c5fbaSopenharmony_ci            fprintf(stderr, "fopen: %s: %s (%d)\n", file_name,
501c87c5fbaSopenharmony_ci                    strerror(errno), errno);
502c87c5fbaSopenharmony_ci            goto bad;
503c87c5fbaSopenharmony_ci          }
504c87c5fbaSopenharmony_ci          continue;
505c87c5fbaSopenharmony_ci        }
506c87c5fbaSopenharmony_ci        if (strncmp(buffer, "DESCRIPTION", sizeof("DESCRIPTION")-1) == 0) {
507c87c5fbaSopenharmony_ci          in_synopsis = 0;
508c87c5fbaSopenharmony_ci          dump_name_synopsis_mismatch();
509c87c5fbaSopenharmony_ci          if (fpheader)
510c87c5fbaSopenharmony_ci            fclose(fpheader);
511c87c5fbaSopenharmony_ci          fpheader = NULL;
512c87c5fbaSopenharmony_ci          check_synopsis(pdir_ent->d_name);
513c87c5fbaSopenharmony_ci          continue;
514c87c5fbaSopenharmony_ci        }
515c87c5fbaSopenharmony_ci        if (strncmp(buffer, "RETURN VALUES", sizeof("RETURN VALUES")-1) == 0 ||
516c87c5fbaSopenharmony_ci            strncmp(buffer, "RETURN VALUE", sizeof("RETURN VALUE")-1) == 0) {
517c87c5fbaSopenharmony_ci          if (in_functions) {
518c87c5fbaSopenharmony_ci            if (fpheader)
519c87c5fbaSopenharmony_ci              fclose(fpheader);
520c87c5fbaSopenharmony_ci            fpheader = NULL;
521c87c5fbaSopenharmony_ci            check_synopsis(pdir_ent->d_name);
522c87c5fbaSopenharmony_ci          }
523c87c5fbaSopenharmony_ci          in_name = 0;
524c87c5fbaSopenharmony_ci          in_synopsis = 0;
525c87c5fbaSopenharmony_ci          dump_name_synopsis_mismatch();
526c87c5fbaSopenharmony_ci          in_functions = 0;
527c87c5fbaSopenharmony_ci          in_return = 1;
528c87c5fbaSopenharmony_ci          continue;
529c87c5fbaSopenharmony_ci        }
530c87c5fbaSopenharmony_ci        if (strncmp(buffer, "TESTING", sizeof("TESTING")-1) == 0) {
531c87c5fbaSopenharmony_ci          if (in_functions) {
532c87c5fbaSopenharmony_ci            if (fpheader)
533c87c5fbaSopenharmony_ci              fclose(fpheader);
534c87c5fbaSopenharmony_ci            fpheader = NULL;
535c87c5fbaSopenharmony_ci            check_synopsis(pdir_ent->d_name);
536c87c5fbaSopenharmony_ci          }
537c87c5fbaSopenharmony_ci          in_name = 0;
538c87c5fbaSopenharmony_ci          in_synopsis = 0;
539c87c5fbaSopenharmony_ci          in_functions = 0;
540c87c5fbaSopenharmony_ci          in_return = 0;
541c87c5fbaSopenharmony_ci          continue;
542c87c5fbaSopenharmony_ci        }
543c87c5fbaSopenharmony_ci        if (strncmp(buffer, "EXAMPLES", sizeof("EXAMPLES")-1) == 0 ||
544c87c5fbaSopenharmony_ci            strncmp(buffer, "EXAMPLE", sizeof("EXAMPLE")-1) == 0) {
545c87c5fbaSopenharmony_ci          if (in_functions) {
546c87c5fbaSopenharmony_ci            if (fpheader)
547c87c5fbaSopenharmony_ci              fclose(fpheader);
548c87c5fbaSopenharmony_ci            fpheader = NULL;
549c87c5fbaSopenharmony_ci            check_synopsis(pdir_ent->d_name);
550c87c5fbaSopenharmony_ci          }
551c87c5fbaSopenharmony_ci          in_name = 0;
552c87c5fbaSopenharmony_ci          in_synopsis = 0;
553c87c5fbaSopenharmony_ci          in_return = 0;
554c87c5fbaSopenharmony_ci          dump_name_synopsis_mismatch();
555c87c5fbaSopenharmony_ci          dump_return_synopsis_mismatch();
556c87c5fbaSopenharmony_ci          in_functions = 0;
557c87c5fbaSopenharmony_ci          in_examples = 1;
558c87c5fbaSopenharmony_ci          continue;
559c87c5fbaSopenharmony_ci        }
560c87c5fbaSopenharmony_ci        if (strncmp(buffer, "SEE ALSO", sizeof("SEE ALSO")-1) == 0) {
561c87c5fbaSopenharmony_ci          if (in_functions) {
562c87c5fbaSopenharmony_ci            if (fpheader)
563c87c5fbaSopenharmony_ci              fclose(fpheader);
564c87c5fbaSopenharmony_ci            fpheader = NULL;
565c87c5fbaSopenharmony_ci            check_synopsis(pdir_ent->d_name);
566c87c5fbaSopenharmony_ci          }
567c87c5fbaSopenharmony_ci          in_name = 0;
568c87c5fbaSopenharmony_ci          in_synopsis = 0;
569c87c5fbaSopenharmony_ci          in_return = 0;
570c87c5fbaSopenharmony_ci          dump_name_synopsis_mismatch();
571c87c5fbaSopenharmony_ci          dump_return_synopsis_mismatch();
572c87c5fbaSopenharmony_ci          in_functions = 0;
573c87c5fbaSopenharmony_ci          in_examples = 1;
574c87c5fbaSopenharmony_ci          break;
575c87c5fbaSopenharmony_ci        }
576c87c5fbaSopenharmony_ci
577c87c5fbaSopenharmony_ci        if (in_name) {
578c87c5fbaSopenharmony_ci          /* Working in NAME section */
579c87c5fbaSopenharmony_ci          if (buffer[0] == '\n')
580c87c5fbaSopenharmony_ci            continue;
581c87c5fbaSopenharmony_ci          if (buffer[0] == '-')
582c87c5fbaSopenharmony_ci            continue;
583c87c5fbaSopenharmony_ci          cp = strchr(buffer, '\n');
584c87c5fbaSopenharmony_ci          if (cp)
585c87c5fbaSopenharmony_ci            *cp = '\000';
586c87c5fbaSopenharmony_ci          cp = strchr(buffer, ',');
587c87c5fbaSopenharmony_ci          if (cp)
588c87c5fbaSopenharmony_ci            *cp = '\000';
589c87c5fbaSopenharmony_ci          if (strcmp(man_name, buffer) == 0)
590c87c5fbaSopenharmony_ci            continue;
591c87c5fbaSopenharmony_ci          if (strlen(buffer) >= sizeof(name_list[0])) {
592c87c5fbaSopenharmony_ci            fprintf(stderr, "NAME: %s is too long (%u >= %u)\n", buffer,
593c87c5fbaSopenharmony_ci                    (int)strlen(buffer), (int)sizeof(name_list[0]));
594c87c5fbaSopenharmony_ci            continue;
595c87c5fbaSopenharmony_ci          }
596c87c5fbaSopenharmony_ci          for (i = 0; i < name_cnt; i++) {
597c87c5fbaSopenharmony_ci            if (strncmp(buffer, name_list[i], sizeof(name_list[i])) == 0) {
598c87c5fbaSopenharmony_ci              fprintf(stderr, "NAME: %s duplicated\n", buffer);
599c87c5fbaSopenharmony_ci              break;
600c87c5fbaSopenharmony_ci            }
601c87c5fbaSopenharmony_ci          }
602c87c5fbaSopenharmony_ci          if (i != name_cnt)
603c87c5fbaSopenharmony_ci            continue;
604c87c5fbaSopenharmony_ci          if (i >= (int)(sizeof(name_list)/sizeof(name_list[0]))) {
605c87c5fbaSopenharmony_ci            fprintf(stderr, "NAME: %s insufficient space (%zu >= %u)\n", buffer,
606c87c5fbaSopenharmony_ci                    i, (int)(sizeof(name_list)/sizeof(name_list[0])));
607c87c5fbaSopenharmony_ci            continue;
608c87c5fbaSopenharmony_ci          }
609c87c5fbaSopenharmony_ci          memcpy(name_list[i], buffer, sizeof(name_list[i])-1);
610c87c5fbaSopenharmony_ci          name_list[i][sizeof(name_list[i])-1] = '\000';
611c87c5fbaSopenharmony_ci          name_cnt++;
612c87c5fbaSopenharmony_ci          for (i = 0; i < man_cnt; i++) {
613c87c5fbaSopenharmony_ci            if (strncmp(man_list[i], buffer, sizeof(man_list[i])) == 0) {
614c87c5fbaSopenharmony_ci              man_list[i][0] = '\000';
615c87c5fbaSopenharmony_ci              break;
616c87c5fbaSopenharmony_ci            }
617c87c5fbaSopenharmony_ci          }
618c87c5fbaSopenharmony_ci        }
619c87c5fbaSopenharmony_ci
620c87c5fbaSopenharmony_ci        if (in_synopsis) {
621c87c5fbaSopenharmony_ci          /* Working in SYNOPSIS section */
622c87c5fbaSopenharmony_ci          size_t len;
623c87c5fbaSopenharmony_ci          char outbuf[1024];
624c87c5fbaSopenharmony_ci
625c87c5fbaSopenharmony_ci          if (buffer[0] == '*' && buffer[1] != '#') {
626c87c5fbaSopenharmony_ci            /* Start of a new entry */
627c87c5fbaSopenharmony_ci            snprintf(outbuf, sizeof(outbuf), "%s", buffer);
628c87c5fbaSopenharmony_ci            while (fgets(buffer, sizeof(buffer), fp) != NULL) {
629c87c5fbaSopenharmony_ci              if (buffer[0] == '\n') {
630c87c5fbaSopenharmony_ci                break;
631c87c5fbaSopenharmony_ci              }
632c87c5fbaSopenharmony_ci              len = strlen(outbuf);
633c87c5fbaSopenharmony_ci              outbuf[len-1] = ' ';
634c87c5fbaSopenharmony_ci              snprintf(&outbuf[len], sizeof(outbuf) - len, "%s", buffer);
635c87c5fbaSopenharmony_ci            }
636c87c5fbaSopenharmony_ci            decode_synopsis_definition(fpheader, outbuf, 1);
637c87c5fbaSopenharmony_ci            continue;
638c87c5fbaSopenharmony_ci          }
639c87c5fbaSopenharmony_ci          if (buffer[0] == '\n')
640c87c5fbaSopenharmony_ci            continue;
641c87c5fbaSopenharmony_ci          if (buffer[0] == '-')
642c87c5fbaSopenharmony_ci            continue;
643c87c5fbaSopenharmony_ci          if (buffer[0] == 'F') {
644c87c5fbaSopenharmony_ci            /* For specific ..... is the end */
645c87c5fbaSopenharmony_ci            in_synopsis = 0;
646c87c5fbaSopenharmony_ci            if (fpheader)
647c87c5fbaSopenharmony_ci              fclose(fpheader);
648c87c5fbaSopenharmony_ci            fpheader = NULL;
649c87c5fbaSopenharmony_ci            check_synopsis(pdir_ent->d_name);
650c87c5fbaSopenharmony_ci            continue;
651c87c5fbaSopenharmony_ci          }
652c87c5fbaSopenharmony_ci        }
653c87c5fbaSopenharmony_ci
654c87c5fbaSopenharmony_ci        if (in_functions) {
655c87c5fbaSopenharmony_ci          /* Working in FUNCTIONS section */
656c87c5fbaSopenharmony_ci          size_t len;
657c87c5fbaSopenharmony_ci          char outbuf[1024];
658c87c5fbaSopenharmony_ci
659c87c5fbaSopenharmony_ci          if (strncmp(buffer, "Prototype:\n", sizeof("Prototype:\n")-1)== 0) {
660c87c5fbaSopenharmony_ci            /* Start of a new entry */
661c87c5fbaSopenharmony_ci            outbuf[0] = '*';
662c87c5fbaSopenharmony_ci            outbuf[1] = '\000';
663c87c5fbaSopenharmony_ci            while (fgets(buffer, sizeof(buffer), fp) != NULL) {
664c87c5fbaSopenharmony_ci              if (buffer[0] == '\n') {
665c87c5fbaSopenharmony_ci                break;
666c87c5fbaSopenharmony_ci              }
667c87c5fbaSopenharmony_ci              len = strlen(outbuf);
668c87c5fbaSopenharmony_ci              if (outbuf[len-1] == '\n')
669c87c5fbaSopenharmony_ci                outbuf[len-1] = ' ';
670c87c5fbaSopenharmony_ci              snprintf(&outbuf[len], sizeof(outbuf) - len, "%s", buffer);
671c87c5fbaSopenharmony_ci            }
672c87c5fbaSopenharmony_ci            len = strlen(outbuf);
673c87c5fbaSopenharmony_ci            len--;
674c87c5fbaSopenharmony_ci            snprintf(&outbuf[len], sizeof(outbuf) - len, "*\n");
675c87c5fbaSopenharmony_ci            decode_synopsis_definition(fpheader, outbuf, 0);
676c87c5fbaSopenharmony_ci            continue;
677c87c5fbaSopenharmony_ci          }
678c87c5fbaSopenharmony_ci        }
679c87c5fbaSopenharmony_ci
680c87c5fbaSopenharmony_ci        if (in_return) {
681c87c5fbaSopenharmony_ci          cp = strstr(buffer, "*coap_");
682c87c5fbaSopenharmony_ci          while (cp) {
683c87c5fbaSopenharmony_ci            char *ecp = strchr(cp+1, '*');
684c87c5fbaSopenharmony_ci
685c87c5fbaSopenharmony_ci            if (!ecp) {
686c87c5fbaSopenharmony_ci              fprintf(stderr, "RETURN VALUES: %s undecipherable\n", cp + 1);
687c87c5fbaSopenharmony_ci              exit_code = 1;
688c87c5fbaSopenharmony_ci              break;
689c87c5fbaSopenharmony_ci            }
690c87c5fbaSopenharmony_ci            *ecp = '\000';
691c87c5fbaSopenharmony_ci            for (i = 0; i < return_cnt; i++) {
692c87c5fbaSopenharmony_ci              if (strcmp(cp+1, return_list[i]) == 0) {
693c87c5fbaSopenharmony_ci                return_list[i][0] = '\000';
694c87c5fbaSopenharmony_ci                break;
695c87c5fbaSopenharmony_ci              }
696c87c5fbaSopenharmony_ci            }
697c87c5fbaSopenharmony_ci            if (i == return_cnt) {
698c87c5fbaSopenharmony_ci              for (i = 0;
699c87c5fbaSopenharmony_ci                   i < sizeof(return_void_list)/sizeof(return_void_list[0]);
700c87c5fbaSopenharmony_ci                   i++) {
701c87c5fbaSopenharmony_ci                if (strcmp(cp+1, return_void_list[i]) == 0)
702c87c5fbaSopenharmony_ci                  break;
703c87c5fbaSopenharmony_ci              }
704c87c5fbaSopenharmony_ci              if (i == sizeof(return_void_list)/sizeof(return_void_list[0])) {
705c87c5fbaSopenharmony_ci                fprintf(stderr, "RETURN VALUES: %s not defined in SYNOPSIS\n", cp + 1);
706c87c5fbaSopenharmony_ci                exit_code = 1;
707c87c5fbaSopenharmony_ci              }
708c87c5fbaSopenharmony_ci            }
709c87c5fbaSopenharmony_ci            cp = strstr(ecp+1, "*coap_");
710c87c5fbaSopenharmony_ci          }
711c87c5fbaSopenharmony_ci        }
712c87c5fbaSopenharmony_ci
713c87c5fbaSopenharmony_ci        if (!in_examples) {
714c87c5fbaSopenharmony_ci          continue;
715c87c5fbaSopenharmony_ci        }
716c87c5fbaSopenharmony_ci        /* Working in EXAMPLES section */
717c87c5fbaSopenharmony_ci        if (skip) {
718c87c5fbaSopenharmony_ci          if (!strcmp(buffer, "----\n") || !strcmp(buffer, "---\n") ||
719c87c5fbaSopenharmony_ci              !strcmp(buffer, "--\n") || !strcmp(buffer, "-\n") ||
720c87c5fbaSopenharmony_ci              !strcmp(buffer, "-----\n")) {
721c87c5fbaSopenharmony_ci            /* Found start of code */
722c87c5fbaSopenharmony_ci            if (strcmp(buffer, "----\n")) {
723c87c5fbaSopenharmony_ci              fprintf(stderr,
724c87c5fbaSopenharmony_ci                      "Unexpected start of code '%.*s' - expected ----\n",
725c87c5fbaSopenharmony_ci                      (int)strlen(buffer)-1, buffer);
726c87c5fbaSopenharmony_ci            }
727c87c5fbaSopenharmony_ci            snprintf(file_name, sizeof(file_name), "tmp/%s-%d.c",
728c87c5fbaSopenharmony_ci                     pdir_ent->d_name, count++);
729c87c5fbaSopenharmony_ci            fpcode = fopen(file_name, "w");
730c87c5fbaSopenharmony_ci            if (!fpcode) {
731c87c5fbaSopenharmony_ci              fprintf(stderr, "fopen: %s: %s (%d)\n", file_name,
732c87c5fbaSopenharmony_ci                      strerror(errno), errno);
733c87c5fbaSopenharmony_ci              goto bad;
734c87c5fbaSopenharmony_ci            } else {
735c87c5fbaSopenharmony_ci              fprintf(fpcode, "/* %s */\n", keep_line);
736c87c5fbaSopenharmony_ci            }
737c87c5fbaSopenharmony_ci            skip = 0;
738c87c5fbaSopenharmony_ci            fprintf(stderr, "Processing: %s EXAMPLE - '%d'\n",
739c87c5fbaSopenharmony_ci                    pdir_ent->d_name,
740c87c5fbaSopenharmony_ci                    count-1);
741c87c5fbaSopenharmony_ci          } else if (buffer[0] == '*') {
742c87c5fbaSopenharmony_ci            snprintf(keep_line, sizeof(keep_line), "%s", buffer);
743c87c5fbaSopenharmony_ci          }
744c87c5fbaSopenharmony_ci          continue;
745c87c5fbaSopenharmony_ci        }
746c87c5fbaSopenharmony_ci        if (!strcmp(buffer, "----\n") || !strcmp(buffer, "---\n") ||
747c87c5fbaSopenharmony_ci            !strcmp(buffer, "--\n") || !strcmp(buffer, "-\n") ||
748c87c5fbaSopenharmony_ci            !strcmp(buffer, "-----\n")) {
749c87c5fbaSopenharmony_ci          /* Found end of code */
750c87c5fbaSopenharmony_ci
751c87c5fbaSopenharmony_ci          skip = 1;
752c87c5fbaSopenharmony_ci          if (fpcode)
753c87c5fbaSopenharmony_ci            fclose(fpcode);
754c87c5fbaSopenharmony_ci          keep_line[0] = '\000';
755c87c5fbaSopenharmony_ci          file_name[strlen(file_name)-1] = '\000';
756c87c5fbaSopenharmony_ci          snprintf(buffer, sizeof(buffer),
757c87c5fbaSopenharmony_ci                   "gcc " GCC_OPTIONS " -c %sc -o %so",
758c87c5fbaSopenharmony_ci                   file_name, file_name);
759c87c5fbaSopenharmony_ci          status = system(buffer);
760c87c5fbaSopenharmony_ci          if (WEXITSTATUS(status)) {
761c87c5fbaSopenharmony_ci            exit_code = WEXITSTATUS(status);
762c87c5fbaSopenharmony_ci          }
763c87c5fbaSopenharmony_ci          continue;
764c87c5fbaSopenharmony_ci        }
765c87c5fbaSopenharmony_ci        if (fpcode) {
766c87c5fbaSopenharmony_ci          if (strstr(buffer, "LIBCOAP_API_VERSION")) {
767c87c5fbaSopenharmony_ci            fprintf(fpcode, "#include <coap3/coap.h>\n");
768c87c5fbaSopenharmony_ci            fprintf(fpcode, "#ifdef __GNUC__\n");
769c87c5fbaSopenharmony_ci            fprintf(fpcode, "#define U __attribute__ ((unused))\n");
770c87c5fbaSopenharmony_ci            fprintf(fpcode, "#else /* not a GCC */\n");
771c87c5fbaSopenharmony_ci            fprintf(fpcode, "#define U\n");
772c87c5fbaSopenharmony_ci            fprintf(fpcode, "#endif /* GCC */\n");
773c87c5fbaSopenharmony_ci            fprintf(fpcode, "#include \"%s.h\"\n", pdir_ent->d_name);
774c87c5fbaSopenharmony_ci            fprintf(fpcode, "#undef U\n");
775c87c5fbaSopenharmony_ci            continue;
776c87c5fbaSopenharmony_ci          }
777c87c5fbaSopenharmony_ci          fprintf(fpcode, "%s", buffer);
778c87c5fbaSopenharmony_ci        }
779c87c5fbaSopenharmony_ci      }
780c87c5fbaSopenharmony_cibad:
781c87c5fbaSopenharmony_ci      fclose(fp);
782c87c5fbaSopenharmony_ci    }
783c87c5fbaSopenharmony_ci  }
784c87c5fbaSopenharmony_ci  closedir(pdir);
785c87c5fbaSopenharmony_ci  for (i = 0; i < man_cnt; i++) {
786c87c5fbaSopenharmony_ci    if (man_list[i][0]) {
787c87c5fbaSopenharmony_ci      if (man_missing_first) {
788c87c5fbaSopenharmony_ci        man_missing_first = 0;
789c87c5fbaSopenharmony_ci        fprintf(stderr, "\nMissing man pages (for reference only)\n");
790c87c5fbaSopenharmony_ci      }
791c87c5fbaSopenharmony_ci      fprintf(stderr, "%s\n", man_list[i]);
792c87c5fbaSopenharmony_ci    }
793c87c5fbaSopenharmony_ci  }
794c87c5fbaSopenharmony_ci  exit(exit_code);
795c87c5fbaSopenharmony_ci}
796