arrays in Multi-Edit

Get help with installation and running Multi-Edit here. Bug reports can be posted here but please not post feature requests here.

Moderator: Moderators

arrays in Multi-Edit

Postby Eric Pement on Thu Apr 22, 2004 3:32 am

I want more information about Multi-Edit and arrays. I've already read the section on "Structures and Arrays" in the CMAC help files. First, I take it from this example in the help files:
Code: Select all
struct ts m;

   m.s1 = "This is a test";
   m.s2 = "This is a another test";
   m.i = 10;
   make_message( m.s1 );

that these "structure variables" can be treated like associative arrays, somewhat like arrays in awk or hashes in perl. Right?

So is the dot operator what separates the array name from its index or subscript? If so, how does that syntax compare or differ from the syntax in the next example, which looks like "arrayname.var[integer]" ?

Second, is there any facility similar to split(...) to directly split a string into an indexed array based on a field separator?

Third, what is the facility for directly obtaining the size/length of an array (that is, a count of the number of members it contains) ? Are array indices zero-based (like perl) or one-based (like awk)?

What's the best way to quickly populate an array? Is there anything like push, pop, splice, etc.? Thanks.
Eric Pement - pemente [at] northpark [dot] edu
Eric Pement
Registered User
 
Posts: 55
Joined: Wed Oct 15, 2003 10:53 pm
Location: Chicago

Postby Michal Vodicka on Thu Apr 22, 2004 5:41 am

Nope. Forgot about databases, perl, awk etc. There are no associative arrays in CMAC. Read examples in manual again, I guess everything what is possible is there.

Actually, arrays are pretty simple. Note array of strings isn't supported. If you need it or something more sophisticated, use text buffer (window).
Michal Vodicka
Developer
 
Posts: 425
Joined: Fri Jul 25, 2003 8:16 pm
Location: Prague, Czech Republic

Postby deleyd on Thu Apr 22, 2004 4:59 pm

Those are all good questions. Hopefully the new CMAC manual will cover this more indepth.

The example code given in HELP about arrays and structures actually generates an error when the index jx=100, because arrays start at zero:
Code: Select all
struct ts
    {
      int tarray[100];
    }

    void test_array
    {
      struct ts m;
      int jx;

      for(jx=0;jx<=100;jx++)
      {
        m.tarray[jx] = jx; // Attempting to write to an array
                           // that is out of bounds will
                           // generate a run-time error
      }
      make_message( str(m.tarray[22]) );
    }

in CMAC arrays can only be created inside a structure.
Above, m is the structure, tarray[100] is the array inside the structure. The array goes from tarray[0] - tarray[99]. To reference an array element you have to specify the structure (m) and the array within the structure

m.tarray[0]
m.tarray[1]
m.tarray[2]

...
m.tarray[99]

CMAC does not support "an array of strings". (Note above it's an array of integers).
User avatar
deleyd
Developer
 
Posts: 1020
Joined: Tue Jul 29, 2003 4:27 pm
Location: Santa Barbara, CA

Postby ReidSweatman on Fri Apr 23, 2004 12:14 am

Yes, CMac arrays are zero-based, one of the few things in Multi-Edit that is.

They can only occur within a struct, and can use any basic data type except for strings and nested structs (unless you nest them using a version of the technique that follows, which will become truly Byzantine). Thus, to some extent, you might consider the struct as a necessary but annoying wrapper around the array (although the struct can also contain other data elements).

If you need to keep an array around as a global, you have to go through a bit more, and there's a couple of gotchas along the way. The following example shows one way to use the global cum string cum struct; you could also split the initialization out as a separate macro, or eliminate it altogether if you could guarantee the global would always have a legitimate value on entering the macro. It's generally better to CYA in situations like this, though. Note that the initialized array-in-a-struct is first created in the string form used to save it as a global using the Str_To_Struct() kernel function; always do it this way. This sample does nothing of import, and the particular values the array is initialized to have no special import; you'll initialize it the way you want for your own application. Use this sample as a template, though (in fact, create a template if you do this kind of thing often). First, at minimum, put the following into your source (.s) file:
Code: Select all
#define ARRAY_SIZE  100

struct tag_State {                  // persistent-state structure
    int aArray[ARRAY_SIZE];
}

void mSampleMacro() {
    struct tag_State S;             // local temporary for persistent state
    str sState = g_sState;          // Str_To_Struct() requires a local string
    if(sState == "") {              // initialize the string if necessary
        int iArray;
        for(iArray = 0; iArray < ARRAY_SIZE; ++iArray)
            S.aArray[iArray] = iArray;
        Struct_To_Str(sState, S);
    }
    Str_To_Struct(S, sState);       // otherwise, unpack it into a struct

    // do your business with S.aArray[]

    Struct_To_Str(sState, S);       // repack the struct into a string
    g_sState   = sState;            // and save it out as a global
}

Then put the following into your header (.sh) file:
Code: Select all
global {
    str g_sState "@MT_State";       // state data that must be persistent between macro calls
}


Note that globals are not themselves variables, and so, can't be directly passed to a kernel function or macro that expects a variable; hence, the use of a local temporary variable.

And a final note: I kept this sample as lean as possible, since the idea isn't all that clear to begin with, but in production code we recommend that you always use at least the TTRACE_ENTER() and TTRACE_LEAVE() macros. It's a lot easier to put them in when you write the macros than to try and go back and plug lots of them in later on when you need to debug something.
Reid Sweatman
User avatar
ReidSweatman
Developer
 
Posts: 455
Joined: Tue Jul 01, 2003 8:35 pm
Location: 2000 Light-years from Home

Postby deleyd on Fri Apr 23, 2004 3:54 pm

gwhite gives an example of using a hidden window as "an array of strings," each line being a string.
http://www.multieditsoftware.com/forums/viewtopic.php?p=1560#1560
User avatar
deleyd
Developer
 
Posts: 1020
Joined: Tue Jul 29, 2003 4:27 pm
Location: Santa Barbara, CA

Postby ReidSweatman on Sun Apr 25, 2004 10:41 am

I posted this quick note yesterday, but it vanished for some reason, so here it is again.

About two years ago I invented the same thing, only rigged to do multi-dimensional arrays. If you dig around in the system code, you'll find a lot places where hidden windows are used for a number of "scratchpad" kinds of things, including arrays. It's not a bad approach. As one example you probably aren't aware of, the paste buffers discussed in another thread are implemented as a list in a hidden window, then serialized out to disk for persistence. Look in your Multi-Edit temp directory for a file called buffer.0 (it may not exist at any given time). That's the paste buffer, and when you've been doing paste operations, it's open as a hidden window.

This is also the reason why you can't actually open the full number of windows Multi-Edit allows: it's already using some of them for its own purposes, which you don't see because they're hidden (although it is possible to make them visible; not a recommended action, unless you really know what you're doing).
Reid Sweatman
User avatar
ReidSweatman
Developer
 
Posts: 455
Joined: Tue Jul 01, 2003 8:35 pm
Location: 2000 Light-years from Home


Return to Support

Who is online

Users browsing this forum: No registered users and 0 guests