COPYRIGHT
    Copyright (c) 2001 Dave Oberholtzer (daveo@obernet.com) and Measurisk.
    All rights reserved. This program is free software; you can redistribute
    it and/or modify it under the same terms as Perl itself.

DISCLAIMER
    This doc is longer than it should be because in includes elements of
    *README*, *INSTALL* and the *man* page. In a later release I will
    properly separate them. Getting it to work well seemed much more
    important.

    And above all, remember that THIS IS AN ALPHA RELEASE. Your input will
    help move it through BETA to STABLE more quickly.

    Please read about Missing Values (specifically that translation tables
    are not yet supported). "Unit of Work" stuff is not tested and in some
    cases not written (see notes below).

    My sense of humor is a bit dry. As this moves toward STABLE, I will try
    to tone it down a bit.

NAME
    FameHLI::API consists of:

        FameHLI::API - Perl5 port of Fame C-HLI functions
        FameHLI::API::HLI - port of Fame hli.h variables
        FameHLI::API::EXT - helper function

SYNOPSIS
    All C-HLI functions are implemented using the same name as the C-HLI
    functions with the *FameHLI::API::* prefix and a capital first letter.

        use FameHLI::API;
        use FameHLI::API::HLI(:all);
        my $rc;
        $rc = FameHLI::API::Cfmini();
        if ($rc != HSUCC) {
          printf("There was an error %d: %s\n", $rc,
            FameHLI::API::EXT::ErrDesc($rc));
        }
        $rc = FameHLI::API::Cfmfin();

DESCRIPTION
    FameHLI::API is an XS port of the Fame C-HLI. It provides access to the
    FAME C-HLI function library as well as the 'hli.h' #define values. The
    interface is written entirely using XS and Perl.

    Unlike many modules, this one is simply a library of functions as
    opposed to any objects. Objects, on the other hand, can now be easily
    developed using this library and added to the *FameHLI* namespace.

    The 'library' includes:

    *   Nearly all of the cfm* functions (exceptions are noted and are
        primarily limited to "Unit of Work" and "Missing Value" functions)

    *   HLI #define variables are available (noting the aforementioned
        issues surrounding Missing Values)

    *   Several 'Helper Functions' which return textual descriptions of HLI
        codes

    In addition, the build package includes sample/test scripts showing the
    use of the functions. These scripts can be found in the "t"
    subdirectories of their respective sections:

        FameHLI::API        ->  ./t/*.t
        FameHLI::API::HLI   ->  ./HLI/t/*.t
        FameHLI::API::EXT   ->  ./EXT/t/*.t

    If you used the *cpan* module and/or need more help finding these files
    you should either talk to your SysAdmin or Local Perl Guru to find out
    where *cpan* keeps its *build* tree or try to use `find':

      find / -name API.xs > /tmp/API.search

    Be aware that this could take a LONG time and, unless you are running as
    *root*, will produce a LOT of "you can't look there" warnings. After all
    is through, you should look at */tmp/API.search* and you should only see
    one useful entry. The file should live in the *FameHLI::API* base
    directory and from there you should be able to find the *t/*
    subdirectories mentioned above.

RETURN VALUE
    Each function will return the status as indicated by the Programmers
    Guide to the C-HLI. Since the functions behave (in most cases) exactly
    as described in FAME's rather hefty documentation, I will forego
    retyping that text.

    Many C-HLI functions take pointers so as to return values via the
    argument list. These values are returned to Perl via the argument list
    as well.

  Scalars

    Scalar values are returned in scalar variables.

  Arrays

    Arrays are returned to Perl in scalar references to anonymous arrays. To
    access values in one of these arrays you must use the 'pointer' or
    'dereferencing' notation. For instance, to access the first element of
    an array reference you would use:

        my $val;
        my $rc = FameHLI::API::Cfmrrng($dbkey, $objname, $range,
                                    $valary, HNTMIS, $mistt);
            if ($rc == HSUCC) {
            $val = $valary->[0];
        } else {
            carp("Couldn't find $objname!");
        }

    You noted, of course, that since Missing Values translation tables
    aren't supported you opted for "No Translation of Missing Values". The
    `$mistt' can be any scalar as it will be completely ignored. I do not
    ignore `tmiss' so you will get very unpredictable results if you specify
    anything other than HNTMIS.

ERRORS
    Perl will let you know about strange errors, either by warnings or by
    dumping core. I haven't gotten a core dump in quite a while so either I
    have found most of the evil bugs or I have gotten more careful of what
    to avoid. ;-)

EXAMPLES
    The best source of examples will come from the FAME C-HLI documentation.
    The main difference is that `status' has been removed from the argument
    list and is now returned as the value of the function.

  "C"

        int status;
        cfmini(&status);

  Perl

        $rc = FameHLI::API::Cfmini();

PREREQUISITES
    FameHLI::API requires

    *   Fame (Forcasting, Analytical, Modeling Environment) installed on
        your system. (www.fame.com) (tested with 8.0 and 9.0 beta)

    *   Perl and a compiler (tested with Perl 5.6.0 and gcc 2.95.2)

    *   A working knowledge of Fame and the C-HLI and/or access to the Fame
        C-HLI documentation. If you have Fame, you should have the
        documentation online (or download the PDF from www.fame.com).

ENVIRONMENT
    You will need to have the various *FAME* environment variables set as
    noted in the Fame documentation.

BUILDING THE MODULE
    Building the module is handled in the standard way. There is a pre-test
    which checks for the $FAME and $HLI environment variables and then
    checks for "hli.h" and "libchli.so". Passing that, it continues on in
    the normal fashion.

    'make test' runs a suite of test scripts (located in the "t/"
    subdirectory). These tests leave associated "*.log" files in the build
    directory. The names of the tests will look familiar if you have seen
    the outline of the on-line Fame HELP Index.

    Before running 'make test' you should copy the "PWD.sample" file to the
    parent directory as "PWD" and edit it to contain valid values. Refer to
    the PWD section under FILES below.

        perl Makefile.PL

    or alternatively

        perl Makefile.PL LIB=~/lib

    and then

        make
        make test

INSTALLATION
    'make install' will install the module in the normal way. If you have
    allowed the default location for the installation you may need 'root'
    access. If, on the other hand, you chose the alternative installation
    method above, you will need to ensure that either the given directory is
    in the PERL5LIB library path or you have the command "use lib
    '/your/path/to/lib';" in your program before the module can be used.

        make install

PORTABILITY
    This module was developed and tested under the following conditions:

       - Developed with Perl 5.6.0 on Solaris 2.6
       - Compiled using 'gcc' version 2.95.2
       - Tested on Solaris 2.6 using Fame 8.032 and 9.0(beta)

FILES
    As with any installation using the Fame software, you will need current
    license files in the path list specified by either the *FAME* or
    *FAME_PATH* environment variables.

  PWD

    The PWD file should contain values which are correct for your system.
    The values needed are:

    *   SERVICE - the service port of an MCADBS. This MCADBS will need to
        have at least one database open. This is used to test `Cfmrmev'
        which will look for FAMESERIES (noted below) in that MCADBS

    *   HOSTNAME - The host on which your MCADBS runs.

    *   FAMESERIES - the name of a time series object available from the
        just noted MCADBS. The series MUST have some values in it as the
        `Cfmrmev' will look for the `LASTVALUE' of that series.

    *   FAMEISSUER - the name of a string scalar object available from the
        same MCADBS. If you were to specify "IBM.CLOSE" for FAMESERIES you
        could specify "IBM.ISSUER" for this object.

    *   FAMEDB - the name of the database which contains the data in the
        same MCADBS. Using the examples above, you would specify "PRC" as
        your database (North American Pricing).

    *   USERNAME - If the above referenced MCADBS requires a username and
        password, this is where you specify it.

        Mine doesn't require username/password so I haven't tested this
        feature yet. If you test it, please let me know so I can either fix
        it or remove this comment.

    *   PASSWORD - the password for the aforementioned USERNAME

    *   SITESERVER - the name of a SiteServer MCADBS instance which has the
        North American Pricing database available.

    *   SPINDEX - the string needed to open a given spindex daily database
        in a standard "open" command.

    *   SPINDATE - the date of the SPINDEX database

CAVEATS (Bugs/Features)
    This module has not yet been tested against a Windows installation. If
    you do try it there and it works, please let me know. If it doesn't
    work, please let me know how you fixed it. :-) I will attempt to get
    those fixes in the next release.

  And Speaking of Windows

    At the time of this writing, HDMODE does not work correctly (or at all)
    on Windows NT. This is a known condition and Fame is working on a fix.
    It should become available after the next NT build for Fame.

  Missing Values

    Missing values are implemented as references to a string whose value (as
    would be expected) is "NA", "NC" or "ND". Translation tables are not yet
    implemented. Therefore, since references aren't valid in FameLand, you
    can check to see if any returned value is a reference. If so, it is
    probably one of the 3 Missing Values. Simply dereference it to see which
    one.

  String Length arguments

    In any C-HLI function which returns a string, you are required to
    provide space for that string as well as telling the C-HLI how much
    space you provided. The length arguments are option in FameHLI::API and
    are, for the most part, ignored even if you do proivde them.

  Object Name Conversion

    In any C-HLI functions which take an OBJNAM as one of the arguments, the
    HLI "trims the name and converts it to uppercase." This is true of some
    other string arguments as well. I don't do that here. I don't see the
    point, do you? The HLI does it because the HLI is very concerned with
    NOT screwing up core memory. If they have to malloc some space, copy the
    string and convert it then they have some extra work (time consumption)
    to do. If, however, they convert it in place, they can avoid that extra
    work. They have to have an UPPER CASE objnam so that they can look it up
    in the internal database namespace.

    I currently copy the objnam to a static buffer and pass that buffer to
    HLI to play with. If I want to return the converted string back, I will
    need to free up your old variable, malloc some new space, assign that to
    your variable and play some calling-stack games.

    If anyone can give me a valid reason to do this, I will put it in.
    Otherwise, I take the object name as READ ONLY.

TO DO LIST
    There are a few areas which still need improvement. These improvements
    will be in later releases. (Order will be dependent on demand.)

  Error Checking / Handling

    In this early release of FameHLI::API there is not a lot of error
    checking for things that you just shouldn't do. If you happen to pass a
    string where the function expects a number, I don't know what will
    happen.

  Diagnostics and Warnings

    Additionally, there aren't many useful diagnostics which use standard
    Perl channels. Most of the error messages are printed to STDOUT. So,
    until I can get to this, please don't make any mistakes. ;-)

  Missing Values

    Missing Values in FameLand can take one of 3 different values and,
    therefore, don't quite work like an `undef' in PerlLand. Because of
    this, I am implementing Missing Values in the following manner:

    *   Missing Values are implemented as references to the strings 'NA',
        'NC' and 'ND'. [Done]

    *   Upon requesting a scalar which has a missing value, the variable
        will contain a reference to the anonymous scalar "ND" (for example).
        [Done]

    *   Upon requesting a series which has missing values, each element
        which represents a missing value will contain a reference pointing
        to the single anonymous scalar string created for that array for
        that type of missing value.

        In this way, strings, numbers and dates will all have either valid
        values or references.

            for (my $i=1; $i<$#@{$data}; $i++) {
                if (ref($data->[$i])) {
                    printf("<%s>\n", ${$data->[$i]});
                } else {
                    printf("Value is '%s'\n", $data->[$i]);
                }
            }

        in this way, you can actually see the "NA", "NC" or "ND" string and
        _know_ it is a missing value. [Done]

    *   cfmis[bdnps]m functions will need to look at the value, see that it
        is a reference, check the value pointed to and see if it is any of
        "NA", "NC" or "ND". I considered using a single 'static' value for
        each missing value and having everybody point to that one but that
        seems too restrictive. [Not done]

    *   cfms[bdnps]m functions would each contain a simple array of
        references to the scalars provided when calling them. No muss, no
        fuss, no casting. [Not done]

RESTRICTIONS
    You will need to already have FAME installed on your system. This module
    was developed using FAME 8.032 and 8.213(beta).

    Just as the C-HLI is not thread-safe, neither is this library since it
    is based entirely on libchli. You have been warned.

SEE ALSO
    the perl(1) manpage the FameHLI::API::HLI(3) manpage the FameHLI::EXT(3)
    manpage.

AUTHOR
    Dave Oberholtzer (daveo@obernet.com)

HISTORY
    The FameHLI::API module is a direct successor of the FameLayer written
    using SWIG. While SWIG is a powerful and somewhat easier package to use
    to create a set of wrapper functions, I was unable to achieve some of
    the transparency that Perl programmers require.

    This follow up is much closer to the actual C-HLI and to the way Perl
    programmers are used to working.

    Both FameLayer and FameHLI::API were developed because I wanted to get
    at the FAME 8.0 HDMODE functionality and because I didn't want to be
    tied to any given MCADBS process. The result is a package written
    entirely in XS which may be portable to Windows (although I haven't
    tried it yet).

IF YOU MUST KNOW
    For those of you who want an on-line list of functions and their
    signatures, here it is.

    Please note: Any function which does not have a set of parenthesis after
    it or that has an *x* in front of it is not currently implemented. This
    is mainly limited to the functions dealing with Missing Values and Unit
    of Work stuff.

    The notable exception to this is `Cfmrdfm' which is partly broken in the
    underlying HLI itself.

    Also note: Any function with an *** (asterisk) in front of it has not
    been ported to Perl. In *C* you need to feed a properly sized buffer for
    string variables. In Perl we do that for you. In addition, most `inlen'
    and `outlen' arguments are optional. If you do provide values for these,
    the values are ignored. These cases are noted with square braces around
    the argument.

  01 Using the HLI

      Cfmini()
      Cfmver(ver)
      Cfmfin()

  02 Setting Options in the HLI

      Cfmsopt(optname, optval)

  03 Setting Ranges

      Cfmsrng(freq, syear, sprd, eyear, eprd, range, numobs)
      Cfmsfis(freq, syear, sprd, eyear, eprd, range, numobs, fmonth, flabel)

  04 Handling Connections

      Cfmopcn(connkey, service, hostname, username, password)
      Cfmgcid(dbkey, connkey)
     x Cfmcmmt(connkey)
     x Cfmabrt(connkey)
      Cfmclcn(connkey)
     x Cfmasrt(connkey, assert_type, assertion, perspective, grouping, dblist)

  05 Handling Databases

      Cfmopdb(dbkey, dbname, mode)
      Cfmspos(flag)
      Cfmcldb(key)
      Cfmpodb(dbkey)
      Cfmrsdb(dbkey)
      Cfmpack(dbkey)
      Cfmopdc(dbkey, dbname, mode, connkey)

  06 Handling Database Information and Attributes

      Cfmddes(dbkey, desc)
      Cfmddoc(dbkey, doc)
      Cfmgdba(dbkey, cyear, cmonth, cday, myear, mmonth, mday, desc, doc)
      Cfmgdbd(dbkey, freq, cdate, mdate)
     * Cfmglen

  07 Handling Data Objects

      Cfmnwob(dbkey, objnam, class, freq, type, basis, observ)
      Cfmalob(dbkey, objnam, class, freq, type, basis, observ, 
                numobs, numchr, growth)
      Cfmcpob(srckey, tarkey, srcnam, tarnam)
      Cfmdlob(dbkey, objnam)
      Cfmrnob(dbkey, oldname, newname)

  08 Handling Data Object Information and Attributes

      Cfmosiz(dbkey, objname, class, type, freq, fyear, fprd, lyear, lprd)
      Cfmgdat(dbkey, objnam, freq, cdate, mdate)
      Cfmwhat(dbkey, objnam, class, type, freq, basis, observ, 
                fyear, fprd, lyear, lprd, cyear, cmonth, cday, 
                myear, mmonth, mday, desc, doc)
     * Cfmncnt
     * Cfmdlen
      Cfmsdes(dbkey, objnam, desc)
      Cfmsdoc(dbkey, objnam, doc)
      Cfmsbas(dbkey, objnam, basis)
      Cfmsobs(dbkey, objnam, observ)
      Cfmgtatt(dbkey, objnam, atttype, attnam, value [, inlen [, outlen]])
     * Cfmlatt
      Cfmsatt(dbkey, objnam, atttype, attnam, value)
      Cfmgnam(dbkey, objnam, basnam)
      Cfmgtali(dbkey, objnam, alias [, inlen [, outlen]])
     * Cfmlali
      Cfmsali(dbkey, objnam, aliass)
     * Cfmlsts
     * Cfmnlen
      Cfmgsln(dbkey, objnam, length)
      Cfmssln(dbkey, objnam, length)
      Cfmgtaso(dbkey, objnam, assoc)
     * Cfmlaso
      Cfmsaso(dbkey, objnam, assoc)

  09 Handling Dates

      Cfmfdiv(freq1, freq2, flag)
      Cfmtody(freq, date)
      Cfmpind(freq, count)
      Cfmpinm(freq, year, month, count)
      Cfmpiny(freq, year, count)
      Cfmwkdy(freq, date, wkdy)
      Cfmbwdy(freq, date, biwkdy)
      Cfmislp(year, leap)
      Cfmchfr(sfreq, sdate, select, tfreq, tdate, relate)
      Cfmpfrq(freq, base, nunits, year, month)
      Cfmufrq(freq, base, nunits, year, month)

  10 Handling Missing Values

    These are not implemented in such a way as you would want to use them.

     x Cfmsnm(nctran, ndtran, natran, table)
     x Cfmspm(nctran, ndtran, natran, table)
     x Cfmsbm(nctran, ndtran, natran, table)
     x Cfmsdm
     x Cfmisnm(value, ismiss)
     x Cfmispm(value, ismiss)
     x Cfmisbm
     x Cfmisdm
     x Cfmissm

  11 Wildcarding

      Cfminwc(dbkey, wildname)
      Cfmnxwc(dbkey, obj, class, type, freq)

  13 Reading Data

     * Cfmrdfa
      Cfmgtnl(dbkey, objnam, index, str [, inlen [, outlen]])
      Cfmrrng(dbkey, objnam, range, data, miss, table)
      Cfmgtstr(dbkey, objnam, range, str)
      Cfmgtsts(dbkey, objnam, range, data [, misaray])
     x Cfmrdfm(dbkey, objname, source)

  12 Writing Data

      Cfmwrng(dbkey, objnam, range, data, miss, table)
      Cfmwstr(dbkey, objnam, range, val, ismiss, length)
      Cfmwsts(dbkey, objnam, range, data)
      Cfmwtnl(dbkey, objnam, idx, val)
     x Cfmwrmt(dbkey, objnam, objtyp, rng, data, miss, tbl)

  14 Converting Dates

      Cfmtdat(freq, date, hour, minute, second, ddate)
      Cfmdatt(freq, date, hour, minute, second, ddate)
      Cfmddat(freq, date, year, month, day)
      Cfmdatd(freq, date, year, month, day)
      Cfmpdat(freq, date, year, period)
      Cfmdatp(freq, date, year, period)
      Cfmfdat(freq, date, year, period, fmonth, flabel)
      Cfmdatf(freq, date, year, period, fmonth, flabel)
      Cfmldat(freq, date, datestr, month, label, century)
      Cfmdatl(freq, date, datestr, month, label)
      Cfmidat(freq, date, datestr, image, month, label, century)
      Cfmdati(freq, date, datestr, image, month, label)

  15 Using the FAME/Server

      Cfmfame(command)
      Cfmopwk(dbkey)
      Cfmsinp(cmd) 

  16 Using an Analytical Channel

      Cfmoprc(dbkey, connkey)
     * Cfmopre
      Cfmrmev(dbkey, expr, optns, wdbkey, objnam)

  17 Getting FAME Errors

      Cfmferr(errtxt)
     * Cfmlerr

  Extensions

    The extensions all return a character string which represents the
    textual version of what the code indicates. For instance,
    `FreqDesc(HBUSNS)' will return the string "BUSINESS". `FormatDate' is
    simply a convenient wrapper for the `cfmdati' function.

      FormatDate(date, freq, image, fmonth, flabel)

      AccessModeDesc(code)
      BasisDesc(code)
      BiWeekdayDesc(code)
      ClassDesc(code)
      ErrDesc(code)
      FreqDesc(code)
      FYLabelDesc(code)
      MonthsDesc(code)
      ObservedDesc(code)
      OldFYEndDesc(code)
      TypeDesc(code)
      WeekdayDesc(code)

