简体   繁体   中英

I need to gen several bools simultaneously

I have:

struct MyStruct {
     !Ipv4En : bool;
     !Ipv6En : bool;
     keep Ipv4En == TRUE or Ipv6En == TRUE;

     MyMethod() is {
         gen Ipv4En;
         gen Ipv6En;
     };
 };

I always get Ipv4En TRUE, because those 2 bools are not generated together. They can't be generated when I gen MyStruct. How can I generate them together?

Meanwhile I patched it (don't like the solution): I've deleted ! in the definition.

temp : MyStruct;
gen temp;

Ipv4En = temp.Ipv4En;
Ipv6En = temp.Ipv6En;

Since a gen action only takes a single gen-item , you have to group the two variables you want solved together. You can do this by defining a new struct :

struct IpVersionInfo {
  Ipv4En: bool;
  Ipv6En: bool;

  keep Ipv4En == TRUE or Ipv6En == TRUE;
};

Instead of having two variables for your enables, you use a single variable of this new struct type:

struct MyStruct {
    !ipVersionInfo: IpVersionInfo;

    MyMethod() is {
        gen ipVersionInfo;
    };
};

If you run a couple of iterations, you'll see that you can reach all combinations:

extend sys {

    run() is also {
        for i from 1 to 20 {
            var s: MyStruct = new;
            s.MyMethod();
            outf(
                    "Ipv4En = %s, Ipv6En = %s\n",
                    s.ipVersionInfo.Ipv4En,
                    s.ipVersionInfo.Ipv6En);
        };
    };

};

This requires an API change, though, so you'll need to update all code that referenced Ipv4En and Ipv6En .

Aside from grouping the two fields in a struct , there are also other ways of solving your problem. Another example would be to define an enum that contains values for your legal cases:

type ip_version_info_e: [ V4, V6, BOTH ];

As before, you can use a variable of this type in your struct :

struct MyStruct {
    !ip_version_info: ip_version_info_e;

    MyMethod() is {
        gen ip_version_info;
    };
};

If you run a couple of iterations of the new code you'll see that it also reaches all possible combinations:

extend sys {

    run() is also {
        for i from 1 to 20 {
            var s: MyStruct = new;
            s.MyMethod();
            outf(
                    "Ipv4En = %s, Ipv6En = %s\n",
                    s.ip_version_info in [ V4, BOTH ],
                    s.ip_version_info in [ V6, BOTH ]);
        };
    };

};

Regardless of how you decide to solve the problem, you should hide the internal implementation from any client code that uses MyStruct . Notice that the out statements from above look different depending on how we chose to handle the IP version settings. Instead of having client code look too deep inside MyStruct you should define the following two methods:

isIpv4Enabled(): bool;
isIpv6Enabled(): bool;

In the case where we grouped the two Boolean variables in a struct , the implementations of these two methods are:

struct MyStruct {
    // ...

    isIpv4Enabled(): bool is {
        result = ipVersionInfo.Ipv4En;
    };

    isIpv6Enabled(): bool is {
        result = ipVersionInfo.Ipv6En;
    };
};

In the case where we defined an enum , we have:

struct MyStruct {
    // ...

    isIpv4Enabled(): bool is {
        result = ip_version_info in [ V4, BOTH ];
    };

    isIpv6Enabled(): bool is {
        result = ip_version_info in [ V6, BOTH ];
    };
};

In both cases, though, the client code for printing would be the same:

extend sys {

    run() is also {
        for i from 1 to 20 {
            var s: MyStruct = new;
            s.MyMethod();
            outf(
                    "Ipv4En = %s, Ipv6En = %s\n",
                    s.isIpv4Enabled(),
                    s.isIpv4Enabled());
        };
    };

};

This is a major advantage. This way you are free to change your implementation of MyStruct in the future and not have to touch any other code that uses it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM