Esempio n. 1
0
TokenTypes Scanner::handleSlash( Token * tok )
{
    TokenTypes  result;
    int         current = nextch();

    if( current == S_ENDC ) {
        HCWarning( RTF_BADEOF, _source->name() );
        result = TOK_END;
    } else if( current == '*' ) {

        // Certain RTF commands begin with "\*\", not "\".

        current = nextch();
        if( current != '\\' ) {
            HCWarning( RTF_BADCOMMAND, _lineNum, _source->name() );
            if( current != S_ENDC ) {
                putback( current );
            }
            result = TOK_NONE;
        } else {
            result = handleSlash( tok );
        }
    } else if( current == '\n' ) {

        // A "\" just before a new-line is the same as "\par".

        memcpy( tok->_text, "par", 4 );
        result = TOK_COMMAND;
        ++_lineNum;
    } else if( isSpecial( current ) ) {

        // Some characters are escaped, like "\{".

        result = TOK_SPEC_CHAR;
        tok->_value = current;
    } else if( current == '\'' ) {

        // "\'nnn" signifies the byte with value nnn.

        result = TOK_SPEC_CHAR;
        pullHex( tok );
    } else if( islower( current ) ) {

        // All RTF commands are in lower case.

        putback( current );
        result = TOK_COMMAND;
        pullCommand( tok );
    } else {
        HCWarning( RTF_BADCOMMAND, _lineNum, _source->name() );
        result = TOK_NONE;
    }
    return( result );
}
Esempio n. 2
0
void HFBitmaps::note( char const name[] )
{
    Image   *current;
    StrNode *curdir = _root;
    uint_16 magic;

    InFile  *bmp = new InFile( name, 1 );

    while( bmp->bad() && curdir != NULL ){
    chdir( curdir->_name );
    curdir = curdir->_next;
    bmp->open( name );
    chdir( _startDir );
    }
    if( bmp->bad() ){
    HCWarning( FILE_ERR, name );
    delete bmp;
    return;
    }
    bmp->reset();
    bmp->readbuf( &magic, 1, 2 );
    switch( magic ){
    case BITMAP_MAGIC:
    case SHG1_MAGIC:
    case SHG2_MAGIC:
    break;

    default:
    throw ImageNotSupported();  // EXCEPTION
    }
    bmp->reset();

    current = new Image;
    current->_name = new char[strlen(name)+1];
    strcpy( current->_name, name );
    current->_next = _files;
    _files = current;
    if( magic == BITMAP_MAGIC ){
    current->_image = new Bitmap(bmp);
    } else {
    current->_image = new SegGraph(bmp);
    }
    if( !current->_image->validImage() ){
    // Keep the bad image in the list for reference,
    // but warn the user.
    HCWarning( HLP_BADIMAGE, current->_name );
    }

    return;
}
Esempio n. 3
0
int HPJReader::handleMap()
{
    int     result;
    char    *token;
    uint_32 hash_value;
    int     con_num;
    int     is_good_string, i;
    for( ;; ){
    result = _scanner.getLine();
    if( !result || _scanner[0] == '[' ) break;
    token = _scanner.tokLine();
    if( token == NULL ) continue;

    // "#include" means go to another file.
    if( stricmp( token, Sinclude ) == 0 ){
        includeMapFile( _scanner.endTok() );
        continue;
    }

    // "#define" is an optional header, ignore it.
    if( stricmp( token, Sdefine ) == 0 ){
        token = _scanner.tokLine();
    }
    if( token == NULL ) continue;

    // verify that the current token at this point is a context string.
    is_good_string = 1;
    for( i=0; token[i] != '\0'; ++i ){
        if( !isalnum( token[i] ) && token[i] != '.' && token[i] != '_' ){
        is_good_string = 0;
        }
    }
    if( !is_good_string ){
        HCWarning( CON_BAD, token, _scanner.lineNum(), _scanner.name() );
    } else {
        // Associate the context string with a context number.
        hash_value = Hash(token);
        token = _scanner.tokLine();
        if( token == NULL ){
        HCWarning( CON_NONUM, token, _scanner.lineNum(),
                   _scanner.name() );
        } else {
        con_num = atol( token );
        _theFiles->_mapFile->addMapRec( con_num, hash_value );
        }
    }
    }
    return result;
}
Esempio n. 4
0
int HFContext::dump( OutFile * dest )
{
    FutureHash  *current = _head;
    while( current != NULL ){
    HCWarning( HLP_NOTOPIC,  (const char *)current->_string );
    current = current->_next;
    }
    return _data->dump( dest );
}
Esempio n. 5
0
void HFBitmaps::addToPath( char const path[] )
{
    char const  *arg = path;
    if( arg == NULL )
        return;

    StrNode *current, *temp;

    // Update the search paths.
    current = _root;
    if( current != NULL ) {
        while( current->_next != NULL ) {
            current = current->_next;
        }
    }

    // There may be many directories specified on each line.
    int j;
    while( arg[0] != '\0' ) {
        j = 0;
        while( arg[j] != '\0' && arg[j] != ',' && arg[j] != ';' ) {
            ++j;
        }
        temp = new StrNode;
        temp->_name = new char[j + 1];
        memcpy( temp->_name, arg, j );
        temp->_name[j] = '\0';
        temp->_next = NULL;
        if( chdir( temp->_name ) == 0 ) {
            chdir( _startDir );
            if( current == NULL ) {
                _root = temp;
                current = _root;
            } else {
                current->_next = temp;
                current = current->_next;
            }
        } else {
            HCWarning( HPJ_BADDIR, temp->_name );
            delete[] temp->_name;
            delete temp;
        }
        arg += j;
        if( arg[0] != '\0' ) {
            ++arg;
        }
    }
}
Esempio n. 6
0
int HPJReader::handleBitmaps()
{
    int result;
    int i;
    for( ;; ){
    result = _scanner.getLine();
    if( !result || _scanner[0] == '[' ) break;
    for( i=0; _scanner[i] != '\0'; i++ ){
        if( !isspace( _scanner[i] ) ) break;
    }
    if( _scanner[i] == '\0' ) continue;
    try{
        _theFiles->_bitFiles->note( &_scanner[i] );
    } catch( HFBitmaps::ImageNotSupported ) {
        HCWarning( UNKNOWN_IMAGE, &_scanner[0], _scanner.lineNum(), _scanner.name() );
    }
    }
    return result;
}
Esempio n. 7
0
uint_32 HFCtxomap::size()
{
    CmapRec *current = _firstRec;
    uint_32 true_offset;
    if( !_resolved ){
    while( current != NULL ){
        true_offset = _offsetFile->getOffset( current->_offset );
        if( true_offset == HFContext::_badValue ){
        char str[16] = "MAP number ";
        ltoa( current->_mapnum, str+11, 10 );
        HCWarning( HLP_NOTOPIC, (const char *) str );
        } else {
        current->_offset = true_offset;
        }
        current = current->_nextRec;
    }
    _resolved = 1;
    }
    return _size;
}
Esempio n. 8
0
char *HPJScanner::getArg( int start_pos )
{
    int     i;

    // Eat whitespace.
    for( i = start_pos; isspace( _curLine[i] ) ; i++ ){
    if( _curLine[i] == '\0' ) break;
    }

    // The next character had better be an '='.
    if( _curLine[i] != '=' ){
    HCWarning( HPJ_NOARG, _lineNum, name() );
    return NULL;
    }
    i++;

    // Eat whitespace again.
    while( isspace( _curLine[i] ) && _curLine[i] != '\0' ){
    i++;
    }

    return _curLine+i;
}
Esempio n. 9
0
int main( int argc, char *[] )
{
    if( argc < 2 || argc > 3 ) {
        HCWarning( USAGE );
        return( -1 );
    }

    // Parse the command line.
    char    cmdline[80];
    char    *pfilename, *temp;
    int     quiet = 0;

    getcmd( cmdline );
    temp = cmdline;
    pfilename = NULL;
    while( *temp != '\0' && isspace( *temp ) ) {
        temp++;
    }
    if( *temp == '-' || *temp == '/' ) {
        temp++;
        if( (*temp != 'q' && *temp != 'Q') || !isspace( *(temp+1) ) ) {
            HCWarning( USAGE );
            return( -1 );
        } else {
            quiet = 1;
            temp++;
            while( *temp != '\0' && isspace( *temp ) ) {
                temp++;
            }
            if( *temp == '\0' ) {
                HCWarning( USAGE );
                return( -1 );
            } else {
                pfilename = temp;
            }
        }
    } else if( *temp != '\0' ) {
        pfilename = temp++;
        while( *temp != '\0' && *temp != '/' && *temp != '-' ) {
            temp++;
        }
        if( *temp != '\0' ) {
            *temp = '\0';
            temp++;
            if( *temp != 'q' && *temp != 'Q' ) {
                HCWarning( USAGE );
                return( -1 );
            } else {
                temp++;
                while( *temp != '\0' && isspace( *temp ) ) {
                    temp++;
                }
                if( *temp != '\0' ){
                    HCWarning( USAGE );
                    return( -1 );
                } else {
                    quiet = 1;
                }
            }
        }
    }

    SetQuiet( quiet );


    //  Parse the given filename.

    char    path[_MAX_PATH];
    char    drive[_MAX_DRIVE];
    char    dir[_MAX_DIR];
    char    fname[_MAX_FNAME];
    char    ext[_MAX_EXT];

    _fullpath( path, pfilename, _MAX_PATH );
    _splitpath( path, drive, dir, fname, ext );

    if( stricmp( ext, PhExt ) == 0 || stricmp( ext, HlpExt ) == 0 ) {
        HCWarning( BAD_EXT );
        return( -1 );
    }
    if( ext[0] == '\0' ){
        _makepath( path, drive, dir, fname, HpjExt );
    }

    char    destpath[_MAX_PATH];
    _makepath( destpath, drive, dir, fname, HlpExt );

    InFile  input( path );
    if( input.bad() ) {
        HCWarning( FILE_ERR, pfilename );
        return( -1 );
    }


    //  Set up and start the help compiler.

    try {
        HFSDirectory    helpfile( destpath );
        HFFont          fontfile( &helpfile );
        HFContext       contfile( &helpfile );
        HFSystem        sysfile( &helpfile, &contfile );
        HFCtxomap       ctxfile( &helpfile, &contfile );
        HFTtlbtree      ttlfile( &helpfile );
        HFKwbtree       keyfile( &helpfile );
        HFBitmaps       bitfiles( &helpfile );

        Pointers        my_files = {
                            NULL,
                            NULL,
                            &sysfile,
                            &fontfile,
                            &contfile,
                            &ctxfile,
                            &keyfile,
                            &ttlfile,
                            &bitfiles,
        };

        if( stricmp( ext, RtfExt ) == 0 ) {
            my_files._topFile = new HFTopic( &helpfile );
            RTFparser   rtfhandler( &my_files, &input );
            rtfhandler.Go();
        } else {
            HPJReader   projfile( &helpfile, &my_files, &input );
            projfile.parseFile();
        }

        helpfile.dump();
        if( my_files._topFile != NULL ) {
            delete my_files._topFile;
        }
        if( my_files._phrFile != NULL ) {
            delete my_files._phrFile;
        }
    }
    catch( HCException ) {
        HCWarning( PROGRAM_STOPPED );
        return( -1 );
    }
    return( 0 );
}
Esempio n. 10
0
void HPJReader::includeMapFile( char i_str[] )
{
    int i = 0;
    char seek_char;

    // Get the filename.
    while( i_str[i] != '\0' && isspace( i_str[i] ) ){
    ++i;
    }
    switch( i_str[i] ){
    case '"':
    seek_char = '"';
    break;
    case '<':
    seek_char = '>';
    break;
    default:
    HCWarning( HPJ_BADINCLUDE, _scanner.lineNum(), _scanner.name() );
    return;
    }

    ++i;
    int j = i;
    while( i_str[j] != '\0' && i_str[j] != seek_char ){
    ++j;
    }
    if( j == '\0' ){
    HCWarning( HPJ_BADINCLUDE, _scanner.lineNum(), _scanner.name() );
    return;
    }

    // Now try to find it in the ROOT path and/or current directory.
    i_str[j] = '\0';
    StrNode *current = _root;
    InFile  source;
    if( current == NULL ){
    source.open( i_str+i );
    } else while( current != NULL ){
    chdir( current->_name );
    source.open( i_str+i );
    chdir( _homeDir );
    if( !source.bad() ) break;
    current = current->_next;
    }

    if( source.bad() ){
    HCWarning(INCLUDE_ERR, (const char *) (i_str+i),
              _scanner.lineNum(), _scanner.name() );
    return;
    }

    HCStartFile( i_str+i );

    // Now parse the secondary file.
    HPJScanner  input( &source );
    int     not_done;
    char    *token;
    int     is_good_str, con_num;
    uint_32 hash_value;
    for( ;; ){
    not_done = input.getLine();
    if( !not_done ) break;

    token = input.tokLine();

    if( stricmp( token, Sinclude ) == 0 ){

        // "#include" directives may be nested.
        includeMapFile( input.endTok() );
        continue;
    } else if( stricmp( token, Sdefine ) == 0 ){

        // "#define" directives specify a context string.
        token = input.tokLine();
        if( token == NULL ) continue;
        is_good_str = 1;
        for( i=0; token[i] != '\0'; ++i ){
        if( !isalnum( token[i] ) && token[i] != '.' && token[i] != '_' ){
            is_good_str = 0;
        }
        }
        if( !is_good_str ){
        HCWarning( CON_BAD, token, input.lineNum(), input.name() );
        } else {
        hash_value = Hash(token);
        token = input.tokLine();
        if( token == NULL ){
            HCWarning( CON_NONUM, token, input.lineNum(),
                       input.name() );
        } else {
            con_num = atol( token );
            _theFiles->_mapFile->addMapRec( con_num, hash_value );
        }
        }
    } else if( strncmp( token, SstartComment, 2 ) == 0 ){

        // #include-d files may contain comments.
        int startcomment = input.lineNum();
        while( token != NULL && strstr( token, SendComment ) == NULL ){
        do{
            token = input.tokLine();
            if( token != NULL ) break;
            not_done = input.getLine();
        } while( not_done );
        }

        if( token == NULL ){
        HCWarning( HPJ_RUNONCOMMENT, startcomment, input.name() );
        break;
        }
    } else {
        HCWarning( HPJ_INC_JUNK, input.lineNum(), input.name() );
        continue;
    }
    }
    HCDoneTick();
    return;
}
Esempio n. 11
0
int HPJReader::handleWindows()
{
    int     result;
    int     i, limit;
    char    *arg;
    int     bad_param;
    int     red, green, blue;
    uint_16 wflags;
    char    name[HLP_SYS_NAME];
    char    caption[HLP_SYS_CAP];
    uint_16 x = 0;
    uint_16 y = 0;
    uint_16 width = 0;
    uint_16 height = 0;
    uint_16 use_max_flag = 0;
    uint_32 rgb_main, rgb_nonscroll;

    for( ; (result = _scanner.getLine()) != 0; ) {
        if( _scanner[0] == '[' ) break;

        limit = HLP_SYS_NAME-1;
        if( limit > result-1 ){
            limit = result-1;
        }
        for( i=0; i<limit && !isspace(_scanner[i]) && _scanner[i] != '=' ; i++ ) {
            name[i] = _scanner[i];
        }
        if( i == result-1 ){
            HCWarning( HPJ_INCOMPLETEWIN, _scanner.lineNum(), _scanner.name() );
            continue;
        } else if( i == HLP_SYS_NAME ){
            HCWarning( HPJ_LONGWINNAME, _scanner.lineNum(), _scanner.name() );
        }
        name[i] = '\0';
        while( i<result-1 && !isspace(_scanner[i]) ){
            i++;
        }

        arg = _scanner.getArg(i);
        if( arg == NULL || *arg == '\0' ){
            HCWarning( HPJ_INCOMPLETEWIN, _scanner.lineNum(), _scanner.name() );
            continue;
        }

        wflags = VALID_TYPE | VALID_NAME;
        _winParamBuf = arg;

        arg = nextWinParam();
        if( *arg != '\0' ){
            i = 0;
            if( *arg == '"' ){
                arg++;
            }
            while( i<HLP_SYS_CAP-1 && *arg != '\0' && *arg != '"' ){
                caption[i++] = *arg++;
            }
            caption[i] = '\0';
            wflags |= VALID_CAPTION;
        }

        bad_param = 0;
        arg = nextWinParam();
        if( *arg != '\0' ){
            x = (uint_16) strtol( arg, NULL, 0 );
            if( x > PARAM_MAX ){
                bad_param = 1;
            } else {
                wflags |= VALID_X;
            }
        }
        arg = nextWinParam();
        if( *arg != '\0' ){
            y = (uint_16) strtol( arg, NULL, 0 );
            if( y > PARAM_MAX ){
                bad_param = 1;
            } else {
                wflags |= VALID_Y;
            }
        }
        arg = nextWinParam();
        if( *arg != '\0' ){
            width = (uint_16) strtol( arg, NULL, 0 );
            if( width > PARAM_MAX ){
                bad_param = 1;
            } else {
                wflags |= VALID_WIDTH;
            }
        }
        arg = nextWinParam();
        if( *arg != '\0' ){
            height = (uint_16) strtol( arg, NULL, 0 );
            if( height > PARAM_MAX ){
                bad_param = 1;
            } else {
                wflags |= VALID_HEIGHT;
            }
        }
        if( bad_param ){
            HCWarning( HPJ_WINBADPARAM, _scanner.lineNum(), _scanner.name() );
            continue;
        }

        arg = nextWinParam();
        if( *arg != '\0' ){
            use_max_flag = (uint_16) strtol( arg, NULL, 0 );
            wflags |= VALID_MAX;
        }

        red = green = blue = 0;
        bad_param = 0;

        arg = nextWinParam();
        if( *arg != '\0' ){
            red = strtol( arg, NULL, 0 );
            if( red < 0 || red > 255 ){
                bad_param = 1;
            }
            wflags |= VALID_RGB1;
        }
        arg = nextWinParam();
        if( *arg != '\0' ){
            green = strtol( arg, NULL, 0 );
            if( green < 0 || green > 255 ){
                bad_param = 1;
            }
            wflags |= VALID_RGB1;
        }
        arg = nextWinParam();
        if( *arg != '\0' ){
            blue = strtol( arg, NULL, 0 );
            if( blue < 0 || blue > 255 ){
                bad_param = 1;
            }
            wflags |= VALID_RGB1;
        }

        if( bad_param ){
            HCWarning( HPJ_WINBADCOLOR, _scanner.lineNum(), _scanner.name() );
            continue;
        } else {
            rgb_main = (uint_32) (red + (green<<8) + (blue<<16));
        }

        red = green = blue = 0;
        bad_param = 0;

        arg = nextWinParam();
        if( *arg != '\0' ){
            red = strtol( arg, NULL, 0 );
            if( red < 0 || red > 255 ){
                bad_param = 1;
            }
            wflags |= VALID_RGB2;
        }
        arg = nextWinParam();
        if( *arg != '\0' ){
            green = strtol( arg, NULL, 0 );
            if( green < 0 || green > 255 ){
                bad_param = 1;
            }
            wflags |= VALID_RGB2;
        }
        arg = nextWinParam();
        if( *arg != '\0' ){
            blue = strtol( arg, NULL, 0 );
            if( blue < 0 || blue > 255 ){
                bad_param = 1;
            }
            wflags |= VALID_RGB2;
        }

        if( bad_param ){
            HCWarning( HPJ_WINBADCOLOR, _scanner.lineNum(), _scanner.name() );
            continue;
        } else {
            rgb_nonscroll = (uint_32) (red + (green<<8) + (blue<<16));
        }

        arg = nextWinParam();
        if( *arg != 0 || strtol( arg, NULL, 0 ) != 0 ){
            wflags |= VALID_ONTOP;
        }

        if( strcmp( name, Smain ) == 0 ){
            _sysFile->addRecord( new SystemWin( wflags, Smain, name, caption,
                            x, y, width, height, use_max_flag,
                        rgb_main, rgb_nonscroll ) );
        } else {
            _sysFile->addRecord( new SystemWin( wflags, Ssecondary, name, caption,
                            x, y, width, height, use_max_flag,
                        rgb_main, rgb_nonscroll ) );
        }
    }
    return result;
}
Esempio n. 12
0
int HPJReader::handleOptions()
{
    int result;
    char    option[MAX_OPTION_LEN+1];
    char    *arg;
    int     i;
    for( ;; ){
    result = _scanner.getLine();
    if( !result || _scanner[0] == '[' ) break;

    // Read in the name of the option.
    for( i=0; i<MAX_OPTION_LEN; i++ ){
        if( isspace( _scanner[i] ) || _scanner[i] == '=' ) break;
        option[i] = (char) toupper( _scanner[i] );
    }
    option[i] = '\0';

    // At present, I only support a few options.
    // Most of these involve passing information to
    // the HFSystem object "_sysFile".
    if( strcmp( option, STitle ) == 0 ){
        arg = _scanner.getArg( i );
        if( arg != NULL ){
        _sysFile->addRecord( new SystemText( HFSystem::SYS_TITLE, arg ) );
        }
    } else if( strcmp( option, SCopyright ) == 0 ){
        arg = _scanner.getArg( i );
        if( arg != NULL ){
        _sysFile->addRecord( new SystemText( HFSystem::SYS_COPYRIGHT, arg ) );
        }
    } else if( strcmp( option, SCompress ) == 0 ){
        arg = _scanner.getArg( i );
        if( arg != NULL ){
        if( stricmp( arg, STrue ) == 0 ||
            stricmp( arg, SHigh ) == 0 ||
            stricmp( arg, SMedium ) == 0 ||
            stricmp( arg, SYes  ) == 0 ){
            _sysFile->setCompress( 1 );
        } else if( stricmp( arg, SFalse ) == 0 ||
                   stricmp( arg, SLow   ) == 0 ||
               stricmp( arg, SNo    ) == 0 ){
            _sysFile->setCompress( 0 );
        }
        }
    } else if( strcmp( option, SOldKeyPhrase ) == 0 ){
        arg = _scanner.getArg( i );
        if( arg != NULL ){
        if( stricmp( arg, STrue ) == 0 ||
            stricmp( arg, SYes  ) == 0 ){
            _oldPhrases = 1;
        } else {
            _oldPhrases = 0;
        }
        }
    } else if( strcmp( option, SContents ) == 0 ||
               strcmp( option, SIndex    ) == 0 ){
        arg = _scanner.getArg( i );
        if( arg != NULL ){
        _sysFile->setContents( Hash( arg ) );
        }
    } else if( strcmp( option, SBmRoot ) == 0 ){
        arg = _scanner.getArg( i );
        _theFiles->_bitFiles->addToPath( arg );
    } else if( strcmp( option, SRoot ) == 0 ){

        // Update the search paths.
        arg = _scanner.getArg( i );
        StrNode *current;
        current = _root;
        if( current != NULL ){
        while( current->_next != NULL ){
            current = current->_next;
        }
        }

        // There may be many directories specified on each line.
        if( arg != NULL ){
        int j;
        StrNode *temp;
        while( arg[0] != '\0' ){
            j = 0;
            while( arg[j] != '\0' && arg[j] != ',' && arg[j] != ';' ){
            ++j;
            }
            temp = new StrNode;
            temp->_name = new char[ j+1 ];
            strncpy( temp->_name, arg, j );
            temp->_name[j] = '\0';
            temp->_next = NULL;
            if( chdir( temp->_name ) == 0 ){
            chdir( _homeDir );
            if( current == NULL ){
                _root = temp;
                current = _root;
            } else {
                current->_next = temp;
                current = current->_next;
            }
            } else {
            HCWarning( HPJ_BADDIR, temp->_name );
            delete[] temp->_name;
            delete temp;
            }
            arg += j;
            if( arg[0] != '\0' ) ++arg;
        }
        }
    }
    }
    return result;
}
Esempio n. 13
0
void HPJReader::parseFile()
{
    HCStartFile( _scanner.name() );

    int     length = _scanner.getLine();    // Get the first line.
    char    section[15];
    int     i;
    while( length != 0 ){

    // The first line had better be the beginning of a section.
    if( _scanner[0] != '[' ){
        HCWarning( HPJ_NOTSECTION, _scanner.lineNum(), _scanner.name() );
        length = skipSection();
        continue;
    }

    // Read in the name of the section.
    for( i=1; i < length ; i++ ){
        if( _scanner[i] == ']' ) break;
        section[i-1] = (char) toupper( _scanner[i] );
    }

    // If the section name wasn't terminated properly, skip the section.
    if( i == length ){
        HCWarning( HPJ_BADSECTION, _scanner.lineNum(), _scanner.name() );
        length = skipSection();
        continue;
    }
    section[i-1] = '\0';

    // Pass control to the appropriate "section handler".
    if( strcmp( section, SBaggage ) == 0 ){
        length = handleBaggage();
    } else if( strcmp( section, SOptions ) == 0 ){
        length = handleOptions();
    } else if( strcmp( section, SConfig ) == 0 ){
        length = handleConfig();
    } else if( strcmp( section, SFiles ) == 0 ){
        length = handleFiles();
    } else if( strcmp( section, SMap ) == 0 ){
        length = handleMap();
    } else if( strcmp( section, SBitmaps ) == 0 ){
        length = handleBitmaps();
    } else if( strcmp( section, SWindows ) == 0 ){
        length = handleWindows();
    } else {
        HCWarning( HPJ_BADSECTION, _scanner.lineNum(), _scanner.name() );
        length = skipSection();
    }
    }

    if( _rtfFiles == NULL ){
    HCError( HPJ_NOFILES );
    }

    // Now parse individual RTF files.
    StrNode *curfile = _rtfFiles;
    StrNode *curdir;
    InFile  source;

    // First, implement phrase replacement if desired.
    if( _theFiles->_sysFile->isCompressed() ){
    _topFile = _rtfFiles;
    _firstDir = _root;
    _startDir = _homeDir;

    _theFiles->_phrFile = new HFPhrases( _dir, &firstFile, &nextFile );

    char    full_path[_MAX_PATH];
    char    drive[_MAX_DRIVE];
    char    dir[_MAX_DIR];
    char    fname[_MAX_FNAME];
    char    ext[_MAX_EXT];

    _fullpath( full_path, _scanner.name(), _MAX_PATH );
    _splitpath( full_path, drive, dir, fname, ext );
    _makepath( full_path, drive, dir, fname, PhExt );

    if( !_oldPhrases || !_theFiles->_phrFile->oldTable(full_path) ){
        _theFiles->_phrFile->readPhrases();
        _theFiles->_phrFile->createQueue( full_path );
    }
    }

    _theFiles->_topFile = new HFTopic( _dir, _theFiles->_phrFile );

    // For each file, search the ROOT path, and create a RTFparser
    // to deal with it.
    curfile = _rtfFiles;
    while( curfile != NULL ){
    curdir = _root;
    if( curdir == NULL ){
        source.open( curfile->_name );
    } else while( curdir != NULL ){
        chdir( curdir->_name );
        source.open( curfile->_name );
        chdir( _homeDir );
        if( !source.bad() ) break;
        curdir = curdir->_next;
    }
    if( source.bad() ){
        HCWarning( FILE_ERR, curfile->_name );
    } else {
        RTFparser rtfhandler( _theFiles, &source );
        rtfhandler.Go();
        source.close();
    }
    curfile = curfile->_next;
    }
}