Пример #1
0
point set::__ins(point n, value_type const &x, point p = nullptr) {
    if (n == nullptr) {
        return makeptr(Node(x, nullptr, nullptr, p));
    }
    if (n->e) {
        return __end.it->p = makeptr(Node(x, nullptr, __end.it, p));
    }
    if (x < n->i) {
        n->l = __ins(n->l, x, n);
    } else if (x > n->i) {
        n->r = __ins(n->r, x, n);
    }
    return n;
}
Пример #2
0
static TSF32 FarPtr find_user_code( TSF32 FarPtr client )
{
    TSF32 FarPtr curr_tsf = client;

    /*  The first TSF on the chain will always be in the DOS/16M
        passup code, for the hotkey interrupt.  We will break there
        if we couldn't find anywhere else to break, but the preferred
        location is in a user code segment because the passup code
        is not meaningful to the user.

        We start walking the TSF chain immediately after the
        passup TSF; if we find a user code segment on the chain,
        we update the break address accordingly.
    */
    while( curr_tsf->prev_tsf32 != NULL_PTR ) {
        curr_tsf = makeptr( FP_SEG( curr_tsf ), curr_tsf->prev_tsf32 );
#if DEBUGHOTKEY
        outs( "TSF at" ); outi( FP_OFF( curr_tsf ) ); outs( " cs:ip=" );
        outi( curr_tsf->cs ); outi( (int)curr_tsf->eip ); outs( "\n\r" );
        outs( "user sel" ); outi( user_sel ); outs( "\n\r" );
#endif
        /*  Break in any code segment above primary DOS/4G code segment
            (DOS/4G and DOS/16M guts may not all be reentrant).  The
            debug_hook function is conveniently exported from that
            segment.
        */
        if( curr_tsf->cs > FP_SEG( debug_hook ) ) {
            client = curr_tsf;
            break;
        }
    }
    return( client );
}
Пример #3
0
static void set_program_name( char *filename )
/* change name of current program (in environment) */
{
    union {
        char FarPtr cip;
        int FarPtr  ip;
        struct {
            unsigned off;
            unsigned sel;
        } w;
    } ep;
    D16REGS     r;
    char        *p;
    char        temp[70];
    unsigned    maxp;
    int         i;
    int         blocksize;
    MCB FarPtr  blockp;
    unsigned    newenv;
    int         oldstrat;
    descriptor  g;
    ULONG       oldenv;
    SELECTOR    oldenv_sel;

    p = temp;
    abspath( filename, p );

    /* Program name not kept before DOS 3.x
    */
    if( _osmajor < 3 )
        return;

    /* Get a pointer to the MCB (arena header) which is always one
        paragraph below the environment block, even in an OS/2 DOS box.
    */
retry:
    oldenv = rsi_abs_address( makeptr( env_sel, 0 ) );
    blockp = MK_FP( rsi_sel_new_absolute( oldenv - 0x10, 0 ), 0 );
    blocksize = blockp->size;
    rsi_sel_free( FP_SEG( blockp ) );

    /* See if we have room to stuff the new name into the existing MCB;
        if not, we will have to allocate a new, larger environment block.
        maxp is the amount of room we have for a path name after subtracting
        the current contents of the environment, a two-byte field between
        the environment and the path name, and two pairs of null bytes.
    */
    maxp =( blocksize << 4 ) - 6;
    ep.ip = makeptr( env_sel, 0 );
    while( *ep.ip != 0 ) {
        ++ep.w.off;
        --maxp;
    }

    if( (i = maxp - strlen( p )) < 0 ) {
#ifdef  DSSI
        /* Can't allocate low memory
        */
        return;
#else
        /* The file name won't fit in the MCB, so we try to make a new
            one.  The number of additional bytes needed is in i, and we
            round up to a full paragraph.  Allocate using DOS so that we
            can free using DOS; otherwise we can lose low memory.
        */
        oldstrat = rsi_mem_strategy( MForceLow );
        r.ax = 0x4800;
        r.bx = blocksize + ( ( -i + 15 ) >> 4 );
        i = r.bx << 4;  /* i == size in bytes of new block */
        oldenv_sel = NULL_SEL;
        if( rsi_rm_interrupt( 0x21, &r, &r ) == 0 ) {
            newenv = r.ax;
            oldenv_sel = rsi_sel_new_absolute( (long)newenv << 4, i );
        }
        rsi_mem_strategy( oldstrat );
        if( oldenv_sel == NULL_SEL )
            return;     /* Give up */

        /* Copy the data from the old environment block into the new
            memory, and prepare to update the old environment descriptor
            with the new size and address.
        */
        movedata( env_sel, 0, oldenv_sel, 0, blocksize << 4 );
        rsi_get_descriptor( oldenv_sel, &g );
        rsi_sel_free( oldenv_sel );

        /* Update the descriptor.  This call fails in an OS/2 2.0 DOS box.
            Discard whichever one of the environment blocks will not be
            referred to in the descriptor.
        */
        if( rsi_set_descriptor( env_sel, &g ) ) {
            r.es = oldenv >> 4;
        } else {