All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Andrew 👽  Yourtchenko" <ayourtch@gmail.com>
To: cocci@systeme.lip6.fr
Subject: [Cocci] how to make substitutions at the end of the function, vs. the end of the block ?
Date: Fri, 16 Jul 2021 09:31:03 +0000	[thread overview]
Message-ID: <CAPi140P-O0B+BiAa7i+WbdfmG3HnA3yCZdy4+SeKa=2jRreTyg@mail.gmail.com> (raw)

Hi all,

I work on the VPP project (http://fd.io/ - open source software
dataplane), and yesterday tried to use coccinelle to make a relatively
non-trivial change
as in the mail https://lists.fd.io/g/vpp-dev/message/17532 - it seemed
to be a very good candidate - boring enough to be painful to do by
hand, complex enough to make sed inadequate for it.

I came up with this semantic patch:


@ detect_func @
identifier CLI_FN, AVM, AIN, ACMD;
fresh identifier LAIN = "line_" ## AIN;

statement S1;

typedef clib_error_t, vlib_main_t, unformat_input_t, vlib_cli_command_t;
@@

static clib_error_t *CLI_FN (vlib_main_t * AVM, unformat_input_t *
AIN, vlib_cli_command_t * ACMD)
{
+ clib_error_t *e = 0;
+  unformat_input_t *LAIN;
...
+ if (!unformat_user (AIN, unformat_line_input, LAIN)) {
+    return 0;
+ }
+
-  while (unformat_check_input (AIN) != UNFORMAT_END_OF_INPUT)
+ while (unformat_check_input (LAIN) != UNFORMAT_END_OF_INPUT)
S1
<...
- return ERR;
+ e = ERR;
+ goto done;
...>
+done:
+ unformat_free(LAIN);
+ return e;
}


I attempt to run it on this test file:

ubuntu@vpp-dev:~$ cat ~/test.c
static clib_error_t *
syn_filter_enable_disable_command_fn (vlib_main_t * vm,
				      unformat_input_t * input,
				      vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm = vnet_get_main ();
  u32 sw_if_index = ~0;
  int enable_disable = 1;
  int rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "disable"))
	enable_disable = 0;
      else if (unformat (input, "%U", unformat_vnet_sw_interface,
			 vnm, &sw_if_index))
	;
      else
	break;
    }

  if (sw_if_index == ~0)
    return clib_error_return (0, "Please specify an interface...");

  rv = syn_filter_enable_disable (sw_if_index, enable_disable);

  switch (rv)
    {
    case 0:
      break;

    case VNET_API_ERROR_INVALID_SW_IF_INDEX:
      return clib_error_return
	(0, "Invalid interface, only works on physical ports");
      break;

    case VNET_API_ERROR_UNIMPLEMENTED:
      return clib_error_return (0,
				"Device driver doesn't support redirection");
      break;

    case VNET_API_ERROR_INVALID_VALUE:
      return clib_error_return (0, "feature arc not found");

    case VNET_API_ERROR_INVALID_VALUE_2:
      return clib_error_return (0, "feature node not found");

    default:
      return clib_error_return (0, "syn_filter_enable_disable returned %d",
				rv);
    }
  return 0;
}
ubuntu@vpp-dev:~$


However, when I run it, the "done: " label, etc. gets inserted twice:

ubuntu@vpp-dev:~$ spatch --sp-file /tmp/rules.sp
--allow-inconsistent-paths  ~/test.c
init_defs_builtins: /usr/bin/../lib/coccinelle/standard.h
HANDLING: /home/ubuntu/test.c
diff =
--- /home/ubuntu/test.c
+++ /tmp/cocci-output-56896-8f35c5-test.c
@@ -3,12 +3,18 @@ syn_filter_enable_disable_command_fn (vl
 				      unformat_input_t * input,
 				      vlib_cli_command_t * cmd)
 {
+  clib_error_t *e = 0;
+  unformat_input_t *line_input;
   vnet_main_t *vnm = vnet_get_main ();
   u32 sw_if_index = ~0;
   int enable_disable = 1;
   int rv;

-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+  if (!unformat_user(input, unformat_line_input, line_input)) {
+      return 0;
+  }
+
+while (unformat_check_input(line_input) != UNFORMAT_END_OF_INPUT)
     {
       if (unformat (input, "disable"))
 	enable_disable = 0;
@@ -48,6 +54,12 @@ syn_filter_enable_disable_command_fn (vl
     default:
       return clib_error_return (0, "syn_filter_enable_disable returned %d",
 				rv);
-    }
+    done:
+      unformat_free(line_input);
+      return e;
+  }
   return 0;
+done:
+  unformat_free(line_input);
+  return e;
 }
ubuntu@vpp-dev:~$


I get a feeling I am missing something fundamental - but RTFM did not
help much... Could anyone please nudge me in the correct direction ?

Thanks a lot!

--a
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

             reply	other threads:[~2021-07-30 10:59 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-16  9:31 Andrew 👽  Yourtchenko [this message]
2021-07-31 19:20 ` [Cocci] how to make substitutions at the end of the function, vs. the end of the block ? Mansour Moufid

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAPi140P-O0B+BiAa7i+WbdfmG3HnA3yCZdy4+SeKa=2jRreTyg@mail.gmail.com' \
    --to=ayourtch@gmail.com \
    --cc=cocci@systeme.lip6.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.