Giter VIP home page Giter VIP logo

cligen's Introduction

CLIgen

Build Status codecov Coverity Scan Build Status

CLIgen is a Command-Line Interface generator.

Well, actually it is not really a generator, since it does not generate code for CLI:s. Instead, it builds and interprets datastructures (a parse-tree) which a library (libcligen) interprets in runtime. It is fast and efficient and helps you develop CLI:s easier. You enter a CLI syntax in a text file, and write callback functions in C. The callback functions add the semantics, that is, what the commands in the CLI are supposed to do.

The main documentation is the cligen tutorial which is usually kept up-to-date and is probably the best way to understand CLIgen.

Some background material can be found on the CLIgen project page.

CLIgen is not a system in itself, you need to build your own 'backend'. There is another co-project: 'clixon' which is a whole system where you load dynamic frontend and backend modules. See CLIXON project page and CLIXON github. Clixon provides a system with embedded database, commit semantics, YANG and NETCONF interface, etc. CLIgen is a part of clixon but can be used by itself.

The source code here is built and installed using:

  configure;
  make;
  sudo make install.

The source builds a single library. If you build applications, you should include cligen.h and link with the library.

There are several example applications:

  • cligen_hello Simplest possible. Just builds a 'hello world' greeting by in-line C
  • cligen_file Read a syntax specification from file. You must supply the file.
  • cligen_tutorial Samples of techniques used in cligen_tutorial.pdf

See also Changelog.

For building the C reference documentation using doxygen, do: make doc and place your browser at doc/index.html.

CLIgen is dual license. Either Apache License, Version 2.0 or GNU General Public License Version 2. You choose.

I can be found at [email protected].

getline

CLIgen uses getline with the following copyright:

Copyright (C) 1991, 1992, 1993 by Chris Thewalt ([email protected])

Permission to use, copy, modify, and distribute this software for any purpose and without fee is hereby granted, provided that the above copyright notices appear in all copies and that both the copyright notice and this permission notice appear in supporting documentation. This software is provided "as is" without express or implied warranty.

cligen's People

Contributors

andrnils avatar askorichenko avatar baruchsiach avatar bbergquist0930 avatar dcornejo avatar dcornejo-netgate avatar krihal avatar loos-br avatar mgsmith1000 avatar mico-micic avatar nowaits avatar olofhagsand avatar pheller avatar plushbeaver avatar rbgarga avatar rcmcdonald91 avatar shmuelnatan avatar stasst-siklu avatar tagrenam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cligen's Issues

How to use auth option?

If I have a syntax such as:

aa { 
  bb, auth="show", cb();
  cc { 
    dd, auth="super", cb();
  }
  ee, cb();
} 

How exactly is it enforced that someone with super/show or any authorization can run certain commands?

Using a regular expression with either ^ OR $ breaks the regular expression match logic.

Consider the following pattern.

 typedef system-id {
   type string {
     pattern
       '^[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}';
   }
 }

It has only ^ at the beginning.

clixon> set system-id 1111.1111.1111
CLI syntax error: "set system-id 1111.1111.1111": regexp match fail: 1111.1111.1111 does not match ^[0-9A-Fa-f]{4}.[0-9A-Fa-f]{4}.[0-9A-Fa-f]{4}

Even though it is a valid regular expression match. Was working in 4.3 version.

Workaround is either both ^ $ should be given or without both of them.

Case-Insensitive Command Matching

Given the commands tree

Aa {
  Bb, cb();
}

I would like to able to enter commands without matching case. Currently, entering the command aa bb results in an "Unknown command" error. I would like to be able to enter the command aa bb and have it execute successfully.

Issue regarding terminal settings on serial port

Hi there,

We have been using cligen for a while and it seems to work nicely when accessed over SSH. However on a new device and directly connecting via a console/serial port we are seeing a weird issue regarding garbage characters being showing up when pasting multiple lines at once.

Say I copy paste these 5 commands/lines at once:

just a dummy test command 1
just a dummy test command 2
just a dummy test command 3
just a dummy test command 4
just a dummy test command 5

This is how they are received on the CLI launched via Serial port:

test# just a dummy test command 1
CLI syntax error: Unknown keyword: "just" in "just a dummy test command 1"
test# just a dummy test command 2���������5�
CLI syntax error: Unknown keyword: "just" in "just a dummy test command 2"
test# +jR

i.e. the lines after the 1st one are interpreted as garbage characters.

while on a CLI launched via SSH they are parsed fine:

test# just a dummy test command 1
CLI syntax error: Unknown keyword: "just" in "just a dummy test command 1"
test# just a dummy test command 2
CLI syntax error: Unknown keyword: "just" in "just a dummy test command 2"
test# just a dummy test command 3
CLI syntax error: Unknown keyword: "just" in "just a dummy test command 3"
test# just a dummy test command 4
CLI syntax error: Unknown keyword: "just" in "just a dummy test command 4"
test# just a dummy test command 5
CLI syntax error: Unknown keyword: "just" in "just a dummy test command 5"
test#

With some trial & error we found that commenting this line i.e.

    new_termios.c_iflag |= (IGNBRK|IGNPAR);

resolves the issue on the serial port. Setting either IGNBRK or IGNPAR or both of them brings the issue back but if both are left unset this garbage character issue does not happen.

I do not have much idea about terminal settings & termios. Do you know why we need these bits to be set and any repercussions of keeping these bits unset?

Just for reference these are the default terminal settings of serial port i.e. the content of old_termios:

c_iflag		ICRNL|IUTF8|IXOFF|IXON
c_oflag		ONLCR|OPOST
c_cflag		CLOCAL|CREAD|CSIZE|HUPCL|B38400
c_lflag		ECHO|ECHOCTL|ECHOE|ECHOK|ECHOKE|ICANON|ISIG
c_cc		3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
c_ispeed	38400
c_ospeed	38400

feature request: a method to transform input strings

It would be helpful if there was the ability to transform or input strings - for example if I enter a password and I want to hash it before passing it down to lower levels. Ideally, the transform
function would be user definable.

A possible syntax would be an extension of the string type in the clispec file:
<var:string transform:userTransformFunction()>

Multiple Callbacks Executed When Terminal Command Has Children

I currently have this tree structure in my .cli file:

aa {
    bb, cb(); {
        (
            [cc]
            [dd]
        ), cb();
    }
}

When I execute the command aa bb, the callback cb() is execute twice, however it is only executed once for the commands aa bb cc, aa bb dd, etc. Is this expected behaviour?

Cligen history doesn't work well with multi line commands

To reproduce the issue follow below steps:-

set gl_scrolling_mode to 0 in cligen to enable multiline commands.
now type type a command such that it fits in a single line.(eg: aa bb cc)
Then type a command which spans across multiple lines.(eg: any command that occupies atleast 2 lines on the cli terminal)

Then use the up arrow key twice and you will see data is no longer legible.

Giving empty string as value for integer variable exists the CLI shell

Ex: consider a command that takes integer as keyword value
cli> set value

cli>set value ""              <------------Exists CLI shell

Below diff solves the problem

supervisor@deeksha_march9_spine>srv2:~/development/cligen $ git diff
diff --git a/cligen_match.c b/cligen_match.c
index 2318610..6cc4af7 100644
--- a/cligen_match.c
+++ b/cligen_match.c
@@ -155,6 +155,9 @@ match_object(cligen_handle h,
 {
   int    match = 0;
   size_t len = 0;
+  enum cv_type t;
+
+  t = co->co_vtype;
 
   if (str)
       len = strlen(str);
@@ -190,8 +193,13 @@ match_object(cligen_handle h,
       }
     break;
   case CO_VARIABLE:
-      if (str == NULL || len==0)
-          match++;
+      if (str == NULL || len==0) {
+           if ((t>= CGV_INT8) && (t<=CGV_DEC64)) {
+               *reason = cligen_reason("'%s' is not a number", str);
+           } else {
+               match++;
+           }
+      }
       else
           if ((match = match_variable(h, co, str, reason)) < 0)
               return -1;
supervisor@deeksha_march9_spine>srv2:~/development/cligen $

Dynamic column name expansion support for recursively referenced nodes/tree.

.cli file:

show("show entries") {
           table("Display table entries") <table_name:string> ("Table name") {
		          column("Column name") @ {
				     <col_name:string cust_col_expansion()>  {
				     value("Column value") <col_val:string>("Search value"), custom_callback();
				     }
                }
           }
}

I have a requirement where i want to get certain entries from a table based on <col_name> and <co_val>
I have a custom expansion function cust_col_expansion that adds keywords col1 , col2 and col3.

cli> show table list1 column <PRESS ?>
<col_name>  column name
col1                 column 1
col2                 column 2
col3                 column 3
cli> show table list1 column col1 value <PRESS ?>
<col_val>      Enter value to be searched
cli> show table list1 column col1 value attr1            <------- scenario 1 
cli> show table list1 column col1 value val1 col2 value attr2    <-------- scenario 2 

In scenario 1: the generated parse tree will have 1 'col_name' node with value 'col1' and one 'col_val' node with value attr1
In scenario 2 : the generated parse tree will have 2 'col_name' nodes with value 'col1' and 'col2' and 2 'col_val' nodes with value attr1 and attr2

so my question is: is there any way we can dynamically change the node names 'col_name' and 'col_val' using some custom expansions so that the generated parse tree in the backend has unique nodes as referring these nodes using unique names can be useful in recursive case

Help-text support for multiple types

(Request from [email protected])
Consider the following multi-type statements:

  (<peer:ipv4addr>("IPv4 address") | <peer:string>("Peer group name");

or

  {
    <peer:int32>("IPv4 address");
    <peer:string length[5:10]>("Peer group name");
   }

In both cases, CLIgen will produce only a single help text., even though there are two different instances (and uses) of peer:

  cli> ?
  <peer>                IPv4 address

The proposal is to enhance the help-texts so that all different help-texts (not only one) is shown. Such as:

  cli> ?
  <peer>                Peer group name
  <peer>                IPv4 address

Note that this will also apply in case of differing help texts of the same type.

serial terminals line wrap at 21 characters

When accessing the CLI using a serial port, the content wraps before the edge of the screen:

localhost.localdomain tnsr(config)# auth u
ser dsfjlkdsadfmdslkf
fhtosprjdemsofjtneyfq

where this was typed as a single line. notice that it wraps after 21 characters on the second and succeeding lines.

this does not happen when accessing the CLI via ssh.

the problem seems to be in cligen_handle.c:cligen_gwinsz() - a serial console seems to report a screen dimension of 0 x 0. in cligen_handle.c:cligen_terminal_length_set() any line length is set to a minimum of 21 characters.

in the case where the terminal dimensions are not available (0 x 0), it should disable all the special scrolling behavior and allow the terminal to deal with over length lines. or something like that.

Syntax to enter commands regardless of order

Is there a syntax to specify a valid command regardless of the order the command is entered?

For example, I want the following commands to be valid:

cli> aa bb cc dd
cli> aa bb dd cc
cli> aa cc bb dd
cli> aa cc dd bb
cli> aa dd cc bb
cli> aa dd bb cc

Right now I believe you would have to explicitly state each command in the syntax like so:

aa { 
  bb { 
    cc dd;
    dd cc;
  }
  cc { 
    bb dd;
    dd bb;
  }
  dd { 
    bb cc;
    cc bb;
  }
}

It is fine implementing this when there are only a few commands which you want like this. (i.e here we have 3 keyword, so only 3! (6) to consider)

However, if you have lots of commands like this. then the amount of permutations that you need to consider grows quickly!

Any solution to this?

request: move some structs to a private header file

Request that you move some of the structures which are not publicly exposed - cbuf, and cvec come to mind - to separate private header files which are not installed.

in our use case, we have added functions that are not of general interest and rather than maintain them as diffs to the cligen core, we could simply create a new file and avoid conflicts and errors.

Check if cg_obj is optional

Is there anyway currently to determine if a cg_obj is an optional? I am currently implementing a command to print the full command tree and would like to avoid printing all permutations for optionals. For example, with the tree

aa {
    bb {
        [
           [cc]
           [dd]
        ]
        ee;
    }
}

I would like to get the output

aa bb cc
aa bb dd
aa bb ee

but am currently getting

aa bb ee
aa bb cc ee
aa bb cc dd ee
aa bb dd ee
aa bb dd cc ee

If there is some way I could determine that cc and dd are optionals it would make this much easier.

CLI syntax help

Hello,
I am trying to write a cli using your cligen module. I am facing a issue.
Below is my syntax:-

aa
{
[bb]
[cc]
[dd];
}

now on cli prompt output:-
cli>aa bb cc dd --- valid output
cli>aa cc dd bb --- not a valid output

I am wondering why i am not able to give the second command.
Is there a restriction on order of parameters at the same level. If yes, I would like to have an order independent command processing. Can we have a syntax which will help in in achieving my goal.

when i do
cli> aa cc ?
it should show both
bb
dd

as help ouptut.

Thanks and Regards,
Deepak Sharma

Vararg Variables for Terminal Commands

For a terminal command with variable, I would love the ability to enter multiple values for the variable. For example, implementing the bash command ls with the cli format
ls("list files")[<ls-var:string>], cb();
I would like to be able to enter commands with multiple variables (eg. ls -l -a, ls -a dirname, etc.) without having to enter the variables in quotes (ls "-l -a") to simulate typical bash syntax. Is this something that would be feasible? I looked into using sets for this but it doesn't seem to fit this use case

Choice with space is not working in CLIgen code:

Choice with a space is not parsed by Cligen code.

Example:

  1. choice ("Choice example") <string choice:unknown|NoSpace|with\ space>, fn_cb(); -->not working
  2. choice ("Choice example") <string choice:unknown|NoSpace|”with space”>, fn_cb(); -->not working

As per yang RFC, space is a valid character in choice type.

Please note: Auto-complete work for first case, but when you press enter, it will say invalid token.

Possible OOM

size_t diff;

On some platforms size_t type may be defined as:

typedef undefined int size_t

and block which allocates memory may not happen.

cbuf_append function in cligen_buf.c

expansion does not work for keywords when another tree is referenced in the .cli file

Issue is seen when redundant keywords are present in the referenced tree at the same hierarchy

consider tree syntax :
file:op.cli
treename= "op";
show {
word1;
word2;
}

file : test.cli
show {
word3;
word4;
}
@op;

cli: op> show <PRESS ?>
word1
word2
cli :op>
cli: cfg><PRESS ?>
show
show                    <------------------ duplicate keywords
cli: cfg> show <PRESS ?>     <-------------------no suggestion are seen

Expected behaviour :

cli: cfg> show <PRESS ?>
word1
word2
word3
word4
cli: cfg>

Question about cligen supporting command line scope/level

When a user provides a valid incomplete command, is it possible for cligen to put the user into the scope/level of the syntax structure of that command rather than returning the "Unkown command" error message ?

For example, given the following syntax....
aa {
bb;
cc;
dd {
ee;
}
}

The user types the command : "aa\n" . Cligen would then not return "Unknown Command", but allows the user to perform the commands defined inside the "aa" block at the next prompt. The prompt could contain the current scope/level of the command.

cli>aa
cli(aa)>dd
cli(aa/dd)>ee

Thanks,
Marek Gimza

Add ability to escape the comment character

Escaping the comment character (which clixon sets to '#') is useful to enter strings that include the comment character. Specifically, passwords might contain all sort of special characters.

Currently the low level cli_trim() routine handles comments removal. So implementing escaping of the comment character would require moving it to higher level syntax aware code.

cligen parse abnormal

Hi olofhagsand:

I used latest cligen code(2018-01-27 7925db3)with following cli file,

snmp set <$cfg_type%g:string choice:sysname> ,cb();     
                                                    
snmp <$test:string choice:hello>,cb();                  
snmp set <$priv_cfg_type%g:string choice:priv> ,cb();   
                                                    
snmp set <$access_cfg_type%g:string choice:access>,cb();

Best way to implement output pipes?

Hello,

What would be the best way to implement output modifiers, e.g. show something | include bla to filter out the output of the given command?
Other example, but probably different implementation: show configuration | display json, which would totally change the output (produce a JSON output of the configuration in that case).

Thanks,
Sylvain

How to best implement passwords in clixon ?

Hello!

From the documentation I see that cligen provides ability to hook a translation function. Using that one can convert the plain text into an encrypted / obfuscated text to be stored in the db I think. How to go about it in RESTCONF? Does the clixon backend have some ability to tweak the data before it get's stored in the candidate / running db itself? Or is there a way for the restconf application to covert the transform the entered plain text password into an encrypted one ?

Thanks!

EDIT : Wrong repo ! Raised the issue on clicon/clixon#127. Sorry for the confusion!

Option to Enter Command Without Variables

Given the .cli syntax

aa<aa-var:string>), cb();

I would like to be able to type the command aa without a variable, as well as aa <variable>. Is the possible to achieve currently?

Help with hidden commands

Hello,

I'm trying to develop a CLI using cligen, and I would like to have some hidden (non-documented) commands. I have read in the tutorial that it's possible using the keyword "hide". However I have not managed to make it work when the command contains variables (parameters).

The cligen_tutorial example contains a simple hidden command. It is possible to reproduce the issue if the definition of the command in the file "tutorial.cli" is changed as shown below:

#secret,hide,secret("message");
secret("Help text") param:string,hide,secret("message");

Then the parameter is hide but not the command.

Am I doing something wrong?

Thanks and Regards,
Sergio

Query does not work with "hierarchical" sets

Given a "hierarchical" cligen set command structure as follows:

  a @{
    b;
    c; @{
      d;
      e;
    }
  }

It is possible to issue command: a c b and a c d b, but query and completion does not work properly.
For example, the following lacks the "b" option:

> a c ?
  <cr>
  d                    
  e    

expected behavior:

> a c ?
  <cr>
  b        <-------------
  d                    
  e    

A Couple Bugs in Set syntax

Given the following syntax:

aa @{
    bb<int32>;
    cc;
    dd;
}

If i type in the following, I see the following:

cli > aa bb <TAB>
 cc                    dd                    <int32>

This should instead produce:

cli > aa bb <TAB>
 <int32>

Another bug I have found is associated with the following syntax:

aa @{
    bb;
    cc;
    dd;
}
aa ff;

If I type in the following and then hit tab, I see:

cli> aa ff <TAB>
 bb                    cc                    dd  

In the case I should not see anything when hitting tab. It should look like this:

cli> aa ff <TAB>
cli> aa ff 

Expansion plugin defined in .cli gets called twice for each expansion

Expansion plugin defined in .cli gets called twice for each expansion.

I have also debugged and found that the below code snippet might the causing the issue.

static int                                                                      
cli_tab_hook(cligen_handle h,                                                   
         int          *cursorp)                                                 
{                                                                               
    int retval = -1;                                                            
    int completed = 0;                                                          
                                                                                
    if (cli_try_complete(h, cursorp, &completed) < 0)                           
    goto done;                                                                  
    if (!completed){                                                            
    if (cli_show_help_commands(h, cligen_buf(h), cligen_tabmode(h) & CLIGEN_TABMODE_COLUMNS) < 0)
        goto done;                                                              
    }                                                                           
    retval = 0;                                                                 
 done:                                                                          
    return retval;                                                              
}

In the above code snippet cli_try_complete as well as cli_show_help_commands both call the expansion function.
In the above code completed variable is not at all modified by cli_try_complete API.
As per my understanding completed should be set to 1 if we get the full expansion.

As per discussion over chat with Olof cli_try_complete indeed has issues as completed is never set.

Performance issue when parsed string size is damn large

for (i=0;i<strlen(str);i++)

for (i=0;i<strlen(str);i++)

Performance slow down, when string size is large. Since invoke 'strlen' too many times.

for (i=0;i<strlen(str);i++)
if (str[i] != '\')
str[j++] = str[i];
for (;j<strlen(str);j++)
str[j] = '\0';

May can replace by below:

size_t len = strlen(str);
for (i=0;i<len;i++)
if (str[i] != '\')
str[j++] = str[i];
for (;j<len;j++)
str[j] = '\0';

Change CLIgen comments

In CLIgen runtime, comments are characters on a line after the special "comment" character which is default '#'.
Example:
# This is a comment
cmd a#this is a comment
You can set the comment character to \0 in which no comments are allowed.

However, thus may be somewhat too basic/raw. In bash for example (https://linux.die.net/man/1/sh), comments

In a non-interactive shell, or an interactive shell in which the interactive_comments option to the shopt builtin is enabled (see SHELL BUILTIN COMMANDS below), a word beginning with # causes that word and all remaining characters on that line to be ignored. An interactive shell without the interactive_comments option enabled does not allow comments. The interactive_comments option is on by default in interactive shells.

CLIgen does not have the concept of "interactive".

The proposal is to introduce a word beginning with # causes that word and all remaining characters on that line to be ignored. This is different from the current behavior where all occurrences of # are used as comment.

Ability to use show attribute to display a multiword string

I want to be able to display a multiword string when hitting tab using the show attribute. I have tried to use the following syntax:

aa<int32 show:"A number">

But I get an error stating complaining about the "

When I try to use the following

aa<int32 show:A\ number>

When I tab it see the following:

cli> aa 
<A\ number>

Any way to use show so that I see the following:

cli> aa 
<A number>

Seen unexpected behavior with memory issue when input string length is >= 1048 char

Hi,

I have not seen any issue if input string is small but seen unexpected behavior when taking a input string >= 1024

getting below bt

#0 __GI_raise (sig=sig@entry=6)
at /usr/src/debug/glibc/2.26-r0/git/sysdeps/unix/sysv/linux/raise.c:51
#1 0x00000034fca355e5 in __GI_abort ()
at /usr/src/debug/glibc/2.26-r0/git/stdlib/abort.c:90
#2 0x00000034fca74bde in __libc_message (action=action@entry=do_abort,
fmt=fmt@entry=0x34fcb744d3 "%s\n") aaaaaaaa
at /usr/src/debug/glibc/2.26-r0/git/sysdeps/posix/libc_fatal.c:181 aaaaaaaa
#3 0x00000034fca7abaa in malloc_printerr (
str=str@entry=0x34fcb72628 "corrupted size vs. prev_size")
at /usr/src/debug/glibc/2.26-r0/git/malloc/malloc.c:5368
#4 0x00000034fca7bcc4 in _int_free (av=av@entry=0x34fcda9c40 <main_arena>,
p=, have_lock=have_lock@entry=1)
at /usr/src/debug/glibc/2.26-r0/git/malloc/malloc.c:4302
#5 0x00000034fca7e222 in _int_realloc (av=av@entry=0x34fcda9c40 <main_arena>,
oldp=oldp@entry=0x1163c40, oldsize=oldsize@entry=1056, nb=nb@entry=80)
at /usr/src/debug/glibc/2.26-r0/git/malloc/malloc.c:4666
#6 0x00000034fca8082b in __GI___libc_realloc (oldmem=0x1163c50, bytes=72)
at /usr/src/debug/glibc/2.26-r0/git/malloc/malloc.c:3231
#7 0x000000350760837d in pt_realloc (pt=0x729548) at cligen_gen.c:315
#8 0x0000003507609d4c in co_insert (pt=0x729548, co1=0x7209d0)
at cligen_gen.c:1010
#9 0x0000003507617755 in pt_expand_treeref (h=0x66c8b0, coprev=0x0,

is any restriction on input length ?

Thank

Compiling with `-DNDEBUG` results in failure of test applications.

I stumbled onto an interesting bug related to the use of asserts() and the -DNDEBUG compiler flag. I have been experimenting with using CMake to build Cligen (you can find that attempt here: https://github.com/theonemcdonald/cligen/tree/cmake).

The CMake default CFLAGS for each build type are as follows:

CMAKE_C_FLAGS_DEBUG: -g
CMAKE_C_FLAGS_RELEASE: -O3 -DNDEBUG
CMAKE_C_FLAGS_RELWITHDEBINFO: -O2 -g -DNDEBUG
CMAKE_C_FLAGS_MINSIZEREL: -Os -DNDEBUG

The failure case can be readily observed by compiling Cligen with -DNDEBUG and running the cligen_hello test application. In this case, typing hello<tab><tab><tab>... causes Cligen to just keep repeating the hello keyword:

image

building without -DNDEBUG yields the correct behavior:

image

The issue appears to be related to an assert() call having undesired side-effects.

After consulting with Olof, we determined this to be a likely culprit that should be explored further:

assert((levels = cligen_cvv_levels(cvt)) >= 0);

cligen_match.c:239:18: warning: variable 'levels' is uninitialized when used here [-Wuninitialized]
    if (level >= levels)
                 ^~~~~~
cligen_match.c:236:15: note: initialize the variable 'levels' to silence this warning
    int levels;
              ^
               = 0

CLIgen code stuck in recursion at the time of parsing

Hi,

I am trying to parse following sample input file and cligen code hangs at the time of parsing. I enabled debug flag and screen is flooded with following message.
cgy_list_push

The cligen file I am using is as below:

`#CLIgen input file
treename="main";
@config_command;

treename="config_command";
show("Retrieve yang object data") @show, show_cb();

treename="container_inventory_list_show";
list(""), fn_cb();{
("list key name"), fn_cb();
{
[aa ("des")]
[ab ("des")]
[ac ("des")]
[ad ("des")]
[ae ("des")]
[af ("des")]
[ag ("des")]
[ah ("des")]
[ai ("des")]
[aj ("des")]
[ak ("des")]
[al ("des")]
[am ("des")]
[an ("des")]
[ao ("des")]
[ap ("des")]
[aq ("des")]
[ar ("des")]
[as ("des")]
[at ("des")]
[au ("des")]
[av ("des")]
[aw ("des")]
[ax ("des")]
[ay ("des")]
[az ("des")]
[ba ("des")]
[bb ("des")]
[bc ("des")]
[bd ("des")]
[be ("des")]
[bf ("des")], fn_cb();
}
}

treename="container_inventory_show";
inventory(""), fn_cb();
{
[@container_inventory_list_show], fn_cb();
}

treename="container_show";
container(""), fn_cb();
{
<string length[1:32]>("The name of the container."), fn_cb();
{
[@container_inventory_show], fn_cb();
}
}

treename="show";
@container_show;
`

  • I tried to narrow down the problem and come up with following observations: If i remove some parameters from container_inventory_list_show tree (say if I remove ax to be), the code works perfectly fine. After adding new parameter one by one in same tree, the code become slower. And after adding few more parameters, the cligen code hang in parsing.
  • The issue is not in bison because I tried with different bison versions (2.6, 3.0.4, 3.2 etc) and issue still there.

Command not recognized when it has 'expand' syntax is used

This is from the last code on master pulled today 2019-03-19

brett@brett-Precision-7740:~/git/cligen$ ./cligen_tutorial -f tutorial.cli 
Syntax:
aa bb, cb();{
      ca("help ca") <int32:int32>, letters();{
            dd, letters();
            ee, letters();
         }
      cb("help cb"), letters();{
         dd, letters();
         ee, letters();
      }
      ff, cb();
   }
access-list("ACL") permit("permit") <src:ipv4addr show:"A.B.C.D">("Source address") <dst:ipv4addr show:"A.B.C.D">("Destination address");
add @sub, add();
change{
   prompt <new:string>("New prompt"), setprompt();
   tree, changetree(0 : (null) = tree1
);
}
del @sub, del();
ex <a:int32 show:"number">("A number");
hello("Greet the world") world, hello(0 : (null) = Hello World!
);
increment <var:string translate:incstr()>, cb();
interface <ifname:string interface("")>("interface name"), cb();
ip("The IP protocol"){
   tcp("The TCP protocol") <port:int32>("Port number"), cb(0 : (null) = tcp
);
   udp("The UDP protocol") <addr:ipv4addr>("IPv4 address"), cb(0 : (null) = udp
);
}
quit("quit the CLI"), quit();
recurse @tutorial;
secret, hide, secret(0 : (null) = message
);
values{
   aa, cb();
   <int32:int32>, cb();
   <int64:int64>, cb();
   <string:string>, cb();
}
Syntax:
x y, fn(0 : (null) = a
);
Syntax:
change tree, changetree(0 : (null) = tutorial
);
z x;
cli> interface eth0
CLI syntax error in: "interface eth0": Unknown command
cli> 

The interface function is being called to provide the list of options, but then the command is not recognized nor is the callback function cb called.

is decimal 64 broken?

Does not seem to be working regardless of if you provide fraction digits, (always set to 0 for whatever reason).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.