/* -----------------------------------------------------------------------------

  Scan handler looking for AutoDoc nodes. This version understands more autodoc
  files than the "fast" version because it can find autodoc entries even if
  they do not start with a FF.

  Scan handlers are plain functions (loadSeg()'ed): no standard C startup
  code and no library calls permitted. We have to put string constants into
  the code segment (DICE compiler: option -ms1).

  DICE:

  dcc autodocslow.c -// -l0 -md -mRR -o golded:etc/scanner/autodocslow

  ------------------------------------------------------------------------------
*/

#include <exec/types.h>

ULONG
ScanHandlerGuide(__D0 ULONG len, __A0 char **text, __A1 ULONG *line)
{
    const char version[] = "$VER: ADocSlow 1.3 (" __COMMODORE_DATE__ ")";

    static UWORD inbuffer;

    // declaring the following buffer as const puts it into the code chunk

    const UBYTE buffer[255];

    UBYTE *next;
    UWORD  length;

    // buffer length for later use

    length = len;

    // clear "last result" buffer if we start parsing a new document

    if (*line == 0)

        inbuffer = 0;

    // scan the next line and look for an autodoc entry of the form "...<libname>/<funcname>...<libname>/<funcname>...")

    next = *text;

    while (len > 1) {

        // possible entry found ?

        if (*next == '/') {

            UWORD keylen;

            // skip the "/"

            ++next;

            --len;

            // set (possible) result string

            *text = next;

            // determine the function name length (everything between the "/" and the next space)

            for (keylen = 0; len && (*next != ' ') && (*next != 9); ++next, --len)

                ++keylen;

            if (keylen) {

                // search for second occurance of the function name in the same line

                while (len > 1) {

                    if (*next == '/') {

                        // skip the "/"

                        ++next;

                        for (len = 0; len <= keylen; ++len) {

                            if (len == keylen) {

                                // buffer result

                                buffer[len] = 0;

                                while (len--)

                                    buffer[len] = (*text)[len];

                                inbuffer = keylen;

                                // return result (ie. length of function name; function name can be found in *text)

                                return(keylen);

                            }
                            else if (next[len] != (*text)[len])

                                break;
                        }

                        break;
                    }
                    else {

                        ++next;

                        --len;
                    }
                }
            }

            // syntax error

            return(FALSE);
        }
        else {

            ++next;

            --len;
        }
    }

    // did one of the previous lines produce a result ?

    if (inbuffer) {

        next = *text;

        // look for "alternative version" mentioned in the text

        while (length) {

            // skip white space

            while (length && (*next < 'A')) {

                --length;

                ++next;
            }

            // check next word

            if (length) {

                UWORD keylen;

                // set (possible) result string

                *text = next;

                // determine length of next word

                for (keylen = 0; length && (*next >= 'A'); ++next) {

                    ++keylen;

                    --length;
                }

                // close match found ?

                if (**text == *buffer) {

                    // only last letter may differ; eg. DrawBevelBox vs. DrawBevelBoxA

                    if ((keylen == (inbuffer + 1)) || (keylen == (inbuffer - 1))) {

                        UWORD compare = (keylen < inbuffer) ? keylen : inbuffer;

                        while (compare--) {

                            if ((*text)[compare] != buffer[compare])

                                break;

                            else if (compare == 0) {

                                // stop searching for alternative versions

                                *buffer = 0;

                                // return result

                                return(keylen);
                            }
                        }
                    }
                }
            }
        }
    }

    return(FALSE);
}
