Exemple #1
0
int
t_func(			/* compute texture for ray */
    OBJREC  *m,
    RAY  *r
)
{
    FVECT  disp;
    double  d;
    MFUNC  *mf;
    int  i;

    if (m->oargs.nsargs < 4)
        objerror(m, USER, "bad # arguments");
    mf = getfunc(m, 3, 0x7, 1);
    setfunc(m, r);
    errno = 0;
    for (i = 0; i < 3; i++) {
        disp[i] = evalue(mf->ep[i]);
        if (errno == EDOM || errno == ERANGE) {
            objerror(m, WARNING, "compute error");
            return(0);
        }
    }
    if (mf->fxp != &unitxf)
        multv3(disp, disp, mf->fxp->xfm);
    if (r->rox != NULL) {
        multv3(disp, disp, r->rox->f.xfm);
        d = 1.0 / (mf->fxp->sca * r->rox->f.sca);
    } else
        d = 1.0 / mf->fxp->sca;
    VSUM(r->pert, r->pert, disp, d);
    return(0);
}
Exemple #2
0
static void
getacoords_as(		/* set up coordinate system */
	ASHIKDAT  *np
)
{
	MFUNC  *mf;
	int  i;

	mf = getfunc(np->mp, 3, 0x7, 1);
	setfunc(np->mp, np->rp);
	errno = 0;
	for (i = 0; i < 3; i++)
		np->u[i] = evalue(mf->ep[i]);
	if ((errno == EDOM) | (errno == ERANGE)) {
		objerror(np->mp, WARNING, "compute error");
		np->specfl |= SPA_BADU;
		return;
	}
	if (mf->fxp != &unitxf)
		multv3(np->u, np->u, mf->fxp->xfm);
	fcross(np->v, np->pnorm, np->u);
	if (normalize(np->v) == 0.0) {
		objerror(np->mp, WARNING, "illegal orientation vector");
		np->specfl |= SPA_BADU;
		return;
	}
	fcross(np->u, np->v, np->pnorm);
}
Exemple #3
0
static void
getacoords(		/* set up coordinate system */
	ANISODAT  *np
)
{
	MFUNC  *mf;
	int  i;

	mf = getfunc(np->mp, 3, 0x7, 1);
	setfunc(np->mp, np->rp);
	errno = 0;
	for (i = 0; i < 3; i++)
		np->u[i] = evalue(mf->ep[i]);
	if ((errno == EDOM) | (errno == ERANGE))
		np->u[0] = np->u[1] = np->u[2] = 0.0;
	if (mf->fxp != &unitxf)
		multv3(np->u, np->u, mf->fxp->xfm);
	fcross(np->v, np->pnorm, np->u);
	if (normalize(np->v) == 0.0) {
		if (fabs(np->u_alpha - np->v_alpha) > 0.001)
			objerror(np->mp, WARNING, "illegal orientation vector");
		getperpendicular(np->u, np->pnorm);	/* punting */
		fcross(np->v, np->pnorm, np->u);
		np->u_alpha = np->v_alpha = sqrt( 0.5 *
			(np->u_alpha*np->u_alpha + np->v_alpha*np->v_alpha) );
	} else
		fcross(np->u, np->v, np->pnorm);
}
static int luaB_getfenv (lua_State *L) {
  getfunc(L, 1);
  if (lua_iscfunction(L, -1))  /* is a C function? */
    lua_pushglobaltable(L);  /* return the global env. */
  else
    lua_getfenv(L, -1);
  return 1;
}
Exemple #5
0
static int
luaB_getfenv(lua_State * L)
{
  getfunc(L);
  if (!aux_getfenv(L))          /* __fenv not defined? */
    lua_pop(L, 1);              /* remove it, to return real environment */
  return 1;
}
Exemple #6
0
static int luaB_getfenv (lua_State *L) {
  getfunc(L, 1);
  if (lua_iscfunction(L, -1))  /* is a C function? */
    lua_pushvalue(L, LUA_GLOBALSINDEX);  /* return the thread's global env. */
  else
    lua_getfenv(L, -1);
  return 1;
}
static int luaB_setfenv (lua_State *L) {
  luaL_checktype(L, 2, LUA_TTABLE);
  getfunc(L, 0);
  lua_pushvalue(L, 2);
  if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
    return luaL_error(L,
             LUA_QL("setfenv") " cannot change environment of given object");
  return 1;
}
Exemple #8
0
/*
 * Name:    record_keys
 * Purpose: save keystrokes in keystroke buffer
 * Date:    June 5, 1992
 * Passed:  line: line to display prompts
 * Notes:   -1 in .next field indicates the end of a recording
 *          STROKE_LIMIT+1 in .next field indicates an unused space.
 *           Recall, return codes are for macros.  Since we do not allow
 *           keys to be assigned to macro functions, let's just return OK;
 */
int  record_keys( int macro_key, int key )
{
register int next;
register int prev;
int func;
int rc;

   rc = OK;
   if (stroke_count == 0) {
      printf( "==> %s", line_in );
      printf( "No more room in macro buffer:  line %u\n",
               line_no );
      rc = ERROR;
   } else {
      func = getfunc( key );
      if (func != RecordMacro && func != SaveMacro && func != LoadMacro &&
          func != ClearAllMacros) {

         /*
          * a -1 in the next field marks the end of the keystroke recording.
          */
         next = macros.first_stroke[macro_key];
         if (macros.strokes[next].next != STROKE_LIMIT+1) {
            while (macros.strokes[next].next != -1)
               next = macros.strokes[next].next;
         }
         prev = next;

         /*
          * now find an open space to record the current key.
          */
         if (macros.strokes[next].key != -1) {
            for (; next < STROKE_LIMIT &&
                         macros.strokes[next].next != STROKE_LIMIT+1;)
               next++;
            if (next == STROKE_LIMIT) {
               for (next=0; next < prev &&
                            macros.strokes[next].next != STROKE_LIMIT+1;)
                  next++;
            }
         }
         if (next == prev && macros.strokes[prev].key != -1) {
            rc = ERROR;
         } else {
         /*
          * next == prev if we are recording the initial macro node.
          */
            macros.strokes[prev].next = next;
            macros.strokes[next].next = -1;
            macros.strokes[next].key  = key;
            stroke_count--;
         }
      }
   }
   return( rc );
}
Exemple #9
0
int 
main(int argc, char **argv)
{
	void   *lib = 0;
	void    (*func) (int argc, char **argv);
	time_t  mod = 0;

	mod = lastmod(THELIB);
	if (mod > 0) {
		_log("Last modified: %s", ctime(&mod));
	}
	_log("Opening " THELIB);
	/* initial dl opening */
	lib = dlopen(THELIB, RTLD_LAZY);
	if (lib == NULL) {
		char *err;
		err=dlerror();
		if(err) {
			_log("Error opening %s, reason unknown.", THELIB);
		} else {
			_log("Error opening %s:  %s", THELIB, err);
		}
	}
	for (;;) {
		/* If it's been modified since we last recorded mod date... */
		if (lastmod(THELIB) > mod) {
			_log("Last modified: %s", ctime(&mod));
			/* record a new mod date */
			mod = lastmod(THELIB);
			/* close the library */
			if(lib)
				dlclose(lib);
			/* open a new one. we don't care if it succeeds after start */
			lib = dlopen(THELIB, RTLD_LAZY);
		}
		func = getfunc(lib);
		if (func != NULL) {
			func(argc, argv);
		} else {
			/* Emergency function, just read and report an error */
			emergency();
		}
	}

	/* close it, we're leaving now, not that any of this will ever happen */
	/* NOTREACHED */
	if(lib)
		dlclose(lib);
	return(0);
}
Exemple #10
0
static int luaB_setfenv (lua_State *L) {
  luaL_checktype(L, 2, LUA_TTABLE);
  getfunc(L);
  if (aux_getfenv(L))  /* __fenv defined? */
    luaL_error(L, "`setfenv' cannot change a protected environment");
  else
    lua_pop(L, 2);  /* remove __fenv and real environment table */
  lua_pushvalue(L, 2);
  if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0)
    lua_replace(L, LUA_GLOBALSINDEX);
  else if (lua_setfenv(L, -2) == 0)
    luaL_error(L, "`setfenv' cannot change environment of given function");
  return 0;
}
Exemple #11
0
static int luaB_setfenv (lua_State *L) {
  luaL_checktype(L, 2, LUA_TTABLE);
  getfunc(L, 0);
  lua_pushvalue(L, 2);
  if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
    /* change environment of current thread */
    lua_pushthread(L);
    lua_insert(L, -2);
    lua_setfenv(L, -2);
    return 0;
  }
  else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
    luaL_error(L,
          LUA_QL("setfenv") " cannot change environment of given object");
  return 1;
}
/** Sets the domain name of the intended server in the client's SSL socket. */
SECStatus
SSL_SetURL(PRFileDesc *fd, char *url)
{
    LOG_DEBUG(">> SSL_SetURL: %s", url);
    static int (*SetUrl)(PRFileDesc *fd, char *url) = NULL;
    if (!SetUrl)
        SetUrl = getfunc("SSL_SetURL", LIBSSL3);
    if (!SetUrl)
        return SECFailure;

    int ret = SetUrl(fd, url);
    LOG_DEBUG(">>> fd = %zx", (intptr_t) fd);
    LOG_DEBUG(">>> result = %d", ret);
    nss_fd = fd;
    return ret;
}
/** Compares the common name specified in the subject DN for a certificate
  * with a specified hostname.
  */
SECStatus
CERT_VerifyCertName(const CERTCertificate *cert, const char *hostname)
{
    LOG_DEBUG(">> CERT_VerifyCertName: %s", hostname);
    static SECStatus (*VerifyCertName)(CERTCertificate *cert,
                                       const char *hostname) = NULL;
    if (!VerifyCertName)
        VerifyCertName = getfunc("CERT_VerifyCertName", LIBNSS3);
    if (!VerifyCertName)
        return SECFailure;

    SECStatus ret = VerifyCertName(cert, hostname);
    LOG_DEBUG(">>> result = %d", ret);

    PATROL_init();
    if (!cfg.loaded)
        PATROL_get_config(&cfg);

    PRNetAddr addr;
    if (PR_SUCCESS != PR_GetPeerName(nss_fd, &addr))
        return ret;

    PatrolData *chain = NULL;
    size_t chain_len
        = PATROL_NSS_convert_chain(CERT_GetCertChainFromCert(cert, PR_Now(),
                                                             certUsageSSLCA),
                                   &chain);

    PatrolRC pret = PATROL_check(&cfg, chain, chain_len, PATROL_CERT_X509,
                                 ret == SECSuccess ? PATROL_OK : PATROL_ERROR,
                                 hostname, 0, "tcp", // FIXME
                                 PR_ntohs((addr.raw.family == PR_AF_INET6)
                                          ? addr.ipv6.port : addr.inet.port));
    LOG_DEBUG(">>> patrol result = %d", pret);

    free(chain);
    PATROL_deinit();

    return pret == PATROL_OK ? SECSuccess : SECFailure;
}
Exemple #14
0
extern int
p_bfunc(			/* compute brightness pattern */
    OBJREC  *m,
    RAY  *r
)
{
    double  bval;
    register MFUNC  *mf;

    if (m->oargs.nsargs < 2)
        objerror(m, USER, "bad # arguments");
    mf = getfunc(m, 1, 0x1, 0);
    setfunc(m, r);
    errno = 0;
    bval = evalue(mf->ep[0]);
    if (errno == EDOM || errno == ERANGE) {
        objerror(m, WARNING, "compute error");
        return(0);
    }
    scalecolor(r->pcol, bval);
    return(0);
}
Exemple #15
0
int def(cons_t *next)
{
	int count;
	cons_t *now = NULL;
	now = next->cdr;
	count = getfunc(now->cvalue);
	if (g_fa[count].key == NULL) {
		g_fa[count].key = (char*)malloc(strlen(now->cvalue) + 1);
		strcpy(g_fa[count].key, now->cvalue);
	}
	next = now;
	now = now->cdr;
	g_fa[count].exp = now->cdr;
	findfunc(now->cdr, next->cvalue, count);
	next = now->car;

	findarg(now->cdr, next);
	
	now->cdr = NULL;
	printf("define %s\n",g_fa[count].key);
	return 0;
}
Exemple #16
0
int lfunc(cons_t *next)
{
	cons_t *now;
	now = next;
	int fc;

	fc = getfunc(next->cvalue);
	if (g_fa[fc].key == NULL) {
		printf("syntax error\n");
		return 0;
	} else {	
		next = next->cdr;
		set_arg(next, g_argl);

		g_argl++;

		now->result = eval(g_fa[fc].exp);

		g_argl--;	

		return now->result;
	}
}
Exemple #17
0
extern int
p_cfunc(			/* compute color pattern */
    OBJREC  *m,
    RAY  *r
)
{
    COLOR  cval;
    register MFUNC  *mf;

    if (m->oargs.nsargs < 4)
        objerror(m, USER, "bad # arguments");
    mf = getfunc(m, 3, 0x7, 0);
    setfunc(m, r);
    errno = 0;
    setcolor(cval, evalue(mf->ep[0]),
             evalue(mf->ep[1]),
             evalue(mf->ep[2]));
    if (errno == EDOM || errno == ERANGE) {
        objerror(m, WARNING, "compute error");
        return(0);
    }
    multcolor(r->pcol, cval);
    return(0);
}
Exemple #18
0
/*
 * Name:    select_file
 * Purpose: To let user select a file from dir list
 * Date:    February 13, 1992
 * Passed:  flist: pointer to list of files
 *          stem:  base directory
 *          dir:   directory display stuff
 * Notes:   let user move thru the file names with the cursor keys
 */
int  select_file( FTYPE *flist, char *stem, DIRECTORY *dir )
{
int  ch;                /* input character from user */
int  func;              /* function of character input by user */
int  fno;               /* index into flist of the file under cursor */
int  goodkey;           /* is key a recognized function key? */
int  r;                 /* current row of cursor */
int  c;                 /* current column of cursor */
int  offset;            /* offset into file list */
int  stop;              /* stop indicator */
int  stem_len;          /* stem length */
int  color;             /* color of help screen */
int  file_color;        /* color of current file */
int  change;            /* boolean, hilite another file? */
int  oldr;              /* old row */
int  oldc;              /* old column */
char asize[20];         /* ascii file size */
char blank[20];         /* blank out file names */

   /*
    * initial everything.
    */
   memset( blank, ' ', 12 );
   blank[12] = '\0';
   c = r = 1;
   ch = fno = offset = 0;
   color = g_display.help_color;
   file_color = g_display.hilited_file;
   goodkey = TRUE;
   stop = FALSE;
   stem_len = strlen( stem );
   s_output( stem, dir->row+1, dir->col+19, color );
   s_output( flist[fno].fname, dir->row+1, dir->col+19+stem_len, color );
   ltoa( flist[fno].fsize, asize, 10 );
   s_output( blank, dir->row+2, dir->col+19, color );
   s_output( asize, dir->row+2, dir->col+19, color );
   itoa( dir->cnt,  asize, 10 );
   s_output( blank, dir->row+2, dir->col+57, color );
   s_output( asize, dir->row+2, dir->col+57, color );
   xygoto( (c-1)*14+dir->col+2, r+dir->row+3 );
   hlight_line( (c-1)*14+dir->col+2, r+dir->row+3, 12, file_color );
   change = FALSE;
   while (stop == FALSE) {
      oldr = r;
      oldc = c;
      ch = getkey( );
      func = getfunc( ch );

      /*
       * User may have redefined the Enter and ESC keys.  Make the Enter key
       *  perform a Rturn in this function. Make the ESC key do an AbortCommand.
       */
      if (ch == RTURN)
         func = Rturn;
      else if (ch == ESC)
         func = AbortCommand;

      switch (func) {
         case Rturn       :
         case NextLine    :
         case BegNextLine :
            stop = TRUE;
            break;
         case AbortCommand :
            stop = TRUE;
            break;
         case LineUp :
            if (r > 1) {
               change = TRUE;
               --r;
            } else {
               r = dir->lines;
               change = TRUE;
               if (offset == 0 || c > 1) {
                  if (c > 1)
                     --c;
               } else if (dir->vcols > 0 && offset > 0 && c == 1) {
                  /*
                   * recalculate the dir display stuff.
                   */
                  offset -= dir->lines;
                  recalculate_dir( dir, flist, offset );
               }
            }
            goodkey = TRUE;
            break;
         case LineDown :
            if (r < dir->prow) {
               change = TRUE;
               ++r;
            } else if (r < dir->lines && c != dir->cols) {
               change = TRUE;
               ++r;
            } else {
               change = TRUE;
               r = 1;
               if (offset == dir->vcols * dir->lines || c < dir->cols) {
                  if (c < dir->cols)
                     ++c;
               } else if (dir->vcols > 0 && offset < dir->vcols * dir->lines &&
                         c == dir->cols) {
                  offset += dir->lines;
                  recalculate_dir( dir, flist, offset );
               }
            }
            goodkey = TRUE;
            break;
         case CharLeft :
            if (offset == 0 || c > 1) {
               if (c > 1) {
                  change = TRUE;
                  --c;
               }
            } else if (dir->vcols > 0 && offset > 0 && c == 1) {
               change = TRUE;

               /*
                * recalculate the dir display stuff.
                */
               offset -= dir->lines;
               recalculate_dir( dir, flist, offset );
            }
            goodkey = TRUE;
            break;
         case CharRight :
            if (offset == dir->vcols * dir->lines || c < dir->cols) {
               if (c < dir->cols) {
                  change = TRUE;
                  ++c;
                  if (c == dir->cols) {
                     if ( r > dir->prow)
                        r = dir->prow;
                  }
               }
            } else if (dir->vcols > 0 && offset < dir->vcols * dir->lines &&
                         c == dir->cols) {
               change = TRUE;
               offset += dir->lines;
               recalculate_dir( dir, flist, offset );
               if (r > dir->prow)
                  r = dir->prow;
            }
            goodkey = TRUE;
            break;
         case BegOfLine :
            change = TRUE;
            c = r = 1;
            goodkey = TRUE;
            break;
         case EndOfLine :
            change = TRUE;
            r = dir->prow;
            c = dir->cols;
            goodkey = TRUE;
            break;
         case ScreenDown :
            change = TRUE;
            r = (c == dir->cols) ? r = dir->prow : dir->lines;
            goodkey = TRUE;
            break;
         case ScreenUp :
            change = TRUE;
            r = 1;
            goodkey = TRUE;
            break;
         default :
            break;
      }
      if (goodkey) {
         s_output( blank, dir->row+1, dir->col+19+stem_len, color );
         fno = offset + (c-1)*dir->lines + (r-1);
         s_output( flist[fno].fname, dir->row+1, dir->col+19+stem_len, color );
         ltoa( flist[fno].fsize, asize, 10 );
         s_output( blank, dir->row+2, dir->col+19, color );
         s_output( asize, dir->row+2, dir->col+19, color );
         xygoto( (c-1)*14+dir->col+2, r+dir->row+3 );
         goodkey = FALSE;
         if (change) {
            hlight_line( (oldc-1)*14+dir->col+2, oldr+dir->row+3, 12, color );
            hlight_line( (c-1)*14+dir->col+2, r+dir->row+3, 12, file_color );
            change = FALSE;
         }
      }
   }
   dir->select = fno;
   return( func == AbortCommand ? ERROR : OK );
}
Exemple #19
0
/*
 * Name:    play_back
 * Purpose: play back a series of keystrokes assigned to key
 * Date:    April 1, 1992
 * Notes:   go thru the macro key list playing back the recorded keystrokes.
 *          to let macros call other macros, we have to 1) save the next
 *           keystroke of the current macro in a stack, 2) execute the
 *           the called macro, 3) pop the key that saved by the calling
 *           macro, 4) continue executing the macro, beginning with the
 *           key we just popped.
 *          use a local stack to store keys.  currently, there is room
 *           for 256 keys -- should be enough room for most purposes.
 */
int  play_back( WINDOW *window )
{
int  key;
int  rc = OK;
int  popped;            /* flag is set when macro is popped */

   /*
    * if we are recording a macro, let's just return if we do a recursive
    *  definition.  Otherwise, we end up executing our recursive macro
    *  while we are defining it.
    */
   if (mode.record == TRUE && g_status.key_pressed == g_status.recording_key)
      rc = ERROR;
   else {

      /*
       * set the global macro flags, so other routines will know
       *  if a macro is executing.
       * set the stack_pointer to "empty" or -1.  initialize the popped
       *  flag to FALSE being that we haven't popped any thing off the stack,
       *  yet.
       */
      g_status.macro_executing = TRUE;
      g_status.mstack_pointer  = -1;
      popped = FALSE;
      rc = OK;
      while (rc == OK) {

         /*
          * the first time thru the loop, popped is FALSE.  some lint
          *  utilities may complain about key being used but not defined.
          */
         if (popped == FALSE) {

            /*
             * find the first keystroke in the macro.  when we pop the stack,
             *  all this stuff is reset by the pop -- do not reset it again.
             */
            g_status.macro_next = macro.first_stroke[g_status.key_pressed-256];
            g_status.current_macro = g_status.key_pressed;
            key = macro.strokes[g_status.macro_next].key;
         }
         popped = FALSE;
         if (key != MAX_KEYS+1  &&  key != -1) {
            do {

               /*
                * set up all editor variables as if we were entering
                *  keys from the keyboard.
                */
               window = g_status.current_window;
               display_dirty_windows( window );
               ceh.flag = OK;
               g_status.key_pressed = macro.strokes[g_status.macro_next].key;
               g_status.command = getfunc( g_status.key_pressed );
               if (g_status.wrapped  ||  g_status.key_pending) {
                  g_status.key_pending = FALSE;
                  g_status.wrapped = FALSE;
                  show_search_message( CLR_SEARCH, g_display.mode_color );
               }

               /*
                * while there are no errors or Control-Breaks, let's keep on
                *  executing a macro.  g_status.control_break is a global
                *  editor flag that is set in our Control-Break interrupt
                *  handler routine.
                */
               if (g_status.control_break == TRUE) {
                  rc = ERROR;
                  break;
               }

               /*
                * we haven't called any editor function yet.  we need
                *  to look at the editor command that is to be executed.
                *  if the command is PlayBack, we need to break out of
                *  this inner do loop and start executing the macro
                *  from the beginning (the outer do loop).
                *
                * if we don't break out now from a recursive macro, we will
                *  recursively call PlayBack and we will likely overflow
                *  the main (as opposed to the macro_stack) stack.
                */
               if (g_status.command == PlayBack) {

                  /*
                   * recursive macros are handled differently from
                   *  macros that call other macros.
                   * recursive macros - break out of this inner loop
                   *  and begin executing the macro from the beg of macro.
                   * standard macros - save the next instruction of this
                   *  macro on the stack and begin executing the called macro.
                   */
                  if (g_status.current_macro != g_status.key_pressed) {
                     if (push_macro_stack(
                                   macro.strokes[g_status.macro_next].next )
                                   != OK) {
                        error( WARNING, window->bottom_line, ed16 );
                        rc = ERROR;
                     }
                     g_status.macro_next =
                                macro.first_stroke[g_status.key_pressed-256];
                     g_status.current_macro = g_status.key_pressed;
                     key = macro.strokes[g_status.macro_next].key;

                     /*
                      * execute called macro at beginning of this do loop.
                      */
                     continue;
                  } else

                     /*
                      * recursive macro - break out of this inner loop
                      *  or else we may overflow the stack(s).
                      */
                     break;
               }


               /*
                * just as we assert before the main editor routine, let's
                *  assert in the macro function to make sure everything
                *  is everything.
                */
#if defined(  __MSC__ )
               assert( window != NULL );
               assert( window->file_info != NULL );
               assert( window->file_info->line_list != NULL );
               assert( window->file_info->line_list_end != NULL );
               assert( window->file_info->line_list_end->len == EOF );
               assert( window->visible == TRUE );
               assert( window->rline >= 0 );
               assert( window->rline <= window->file_info->length + 1 );
               assert( window->rcol >= 0 );
               assert( window->rcol < MAX_LINE_LENGTH );
               assert( window->ccol >= window->start_col );
               assert( window->ccol <= window->end_col );
               assert( window->bcol >= 0 );
               assert( window->bcol < MAX_LINE_LENGTH );
               assert( window->bcol == window->rcol-(window->ccol - window->start_col) );
               assert( window->start_col >= 0 );
               assert( window->start_col < window->end_col );
               assert( window->end_col < g_display.ncols );
               assert( window->cline >= window->top_line );
               assert( window->cline <= window->bottom_line );
               assert( window->top_line > 0 );
               assert( window->top_line <= window->bottom_line );
               assert( window->bottom_line < MAX_LINES );
               assert( window->bin_offset >= 0 );
               if (window->ll->next == NULL)
                  assert( window->ll->len == EOF );
               else
                  assert( window->ll->len >= 0 );
               assert( window->ll->len <  MAX_LINE_LENGTH );
#endif


               if (g_status.command >= 0 && g_status.command < NUM_FUNCS)
                   rc = (*do_it[g_status.command])( window );
               g_status.macro_next =
                          macro.strokes[g_status.macro_next].next;
            } while (rc == OK  &&  g_status.macro_next != -1);

            /*
             * if we have come the end of a macro definition and there
             *  are no keys saved on the stack, we have finished our
             *  macro.  get out.
             */
            if (g_status.macro_next == -1 && g_status.mstack_pointer < 0)
               rc = ERROR;
            else if (rc != ERROR  &&  g_status.mstack_pointer >= 0) {

               /*
                * if this is a recursive macro, don't pop the stack
                *  because we didn't push.
                * for a standard macro, get back the next key in the
                *  calling macro.
                */
               if (g_status.current_macro != g_status.key_pressed) {
                  if (pop_macro_stack( &g_status.macro_next ) != OK) {
                     error( WARNING, window->bottom_line, ed17 );
                     rc = ERROR;
                  } else {
                     popped = TRUE;
                     key = macro.strokes[g_status.macro_next].key;
                  }
               }
            }
         }
      }
      g_status.macro_executing = FALSE;
   }
   return( OK );
}
Exemple #20
0
/*
 * Name:    record_on_off
 * Purpose: save keystrokes in keystroke buffer
 * Date:    April 1, 1992
 * Passed:  window:  pointer to current window
 * Notes:   -1 in .next field indicates the end of a recording
 *          -1 in .key field indicates the initial, unassigned macro key
 *          STROKE_LIMIT+1 in .next field indicates an unused space.
 */
int  record_on_off( WINDOW *window )
{
register int next;
int  prev;
int  line;
int  key;
int  func;
char line_buff[(MAX_COLS+2)*2]; /* buffer for char and attribute  */

   mode.record = !mode.record;
   if (mode.record == TRUE) {
      line = window->bottom_line;
      show_avail_strokes( );
      save_screen_line( 0, line, line_buff );
      /*
       * press key that will play back recording
       */
      set_prompt( main11, line );

      /*
       * get the candidate macro key and look up the function assigned to it.
       */
      key = getkey( );
      func = getfunc( key );

      /*
       * the key must be an unused, recognized function key or a function
       *  key assigned to a previously defined macro.  we also need room
       *  in the macro structure.
       */
      if (key <= 256 || (func != 0 && func != PlayBack)) {
         /*
          * cannot assign a recording to this key
          */
         error( WARNING, line, main12 );
         mode.record = FALSE;
      } else if (g_status.stroke_count == 0) {
         /*
          * no more room in recording buffer
          */
         error( WARNING, line, main13 );
         mode.record = FALSE;
      } else {

         /*
          * everything is everything so far, just check for a prev macro
          */
         prev = OK;
         if (func == PlayBack) {
            /*
             * overwrite recording (y/n)?
             */
            set_prompt( main14, line );
            if (get_yn( ) == A_NO) {
               prev = ERROR;
               mode.record = FALSE;
            }
         }
         if (prev == OK) {
            g_status.recording_key = key;
            next = macro.first_stroke[key-256];

            /*
             * if key has already been assigned to a macro, clear macro def.
             */
            if (next != STROKE_LIMIT+1) {
               do {
                  prev = next;
                  next = macro.strokes[next].next;
                  macro.strokes[prev].key  = MAX_KEYS+1;
                  macro.strokes[prev].next = STROKE_LIMIT+1;
                  ++g_status.stroke_count;
               } while (next != -1);
               show_avail_strokes( );
            }

            /*
             * find the first open space and initialize
             */
            for (next=0; macro.strokes[next].next != STROKE_LIMIT+1;)
               next++;
            macro.first_stroke[key-256] = next;
            macro.strokes[next].key  = -1;
            macro.strokes[next].next = -1;
            key_func.key[key-256] = PlayBack;
            /*
             * recording
             */
            s_output( main15, g_display.mode_line, 22,
                      g_display.mode_color | 0x80 );
         }
      }
      restore_screen_line( 0, line, line_buff );
   }

   /*
    * the flashing "Recording" and the stroke count write over the modes.
    *  when we get thru defining a macro, redisplay the modes.
    */
   if (mode.record == FALSE) {
      memset( line_buff, ' ', 36 );
      line_buff[36] = '\0';
      s_output( line_buff, g_display.mode_line, 22, g_display.mode_color );
      show_tab_modes( );
      show_indent_mode( );
      show_sync_mode( );
      show_search_case( );
      show_wordwrap_mode( );

      /*
       * let's look at the macro.  if the first .key of the macro is
       *  still -1, which is the initial unassigned key in a macro, reset
       *  the macro so other keys may be assigned to this node.
       */
      key = g_status.recording_key;
      if (key != 0) {
         next = macro.first_stroke[key-256];
         if (macro.strokes[next].key == -1) {
            macro.strokes[next].key  = MAX_KEYS+1;
            macro.strokes[next].next = STROKE_LIMIT+1;
            macro.first_stroke[key-256] = STROKE_LIMIT+1;
            if (getfunc( key ) == PlayBack)
               key_func.key[key-256] = 0;
         }
      }
      g_status.recording_key = 0;
   }
   return( OK );
}
Exemple #21
0
/*
 * 作用: 把键盘命令放到缓存中
 * 参数: line: 要提示显示的行
 * 注意: 如果next值是-1,表明到了记录的末尾;
 *       如果next值是STROKE_LIMIT+1表示空间已经用完
 */
void record_keys( int line )
{
register int next;
register int prev;
int  key;
int  func;

   if (mode.record == TRUE) {
      if (g_status.stroke_count == 0)
         /*
          * 宏记录已经没有空间记录更多的操作
          */
         error( WARNING, line, main13 );
      else {
         key = g_status.key_pressed;
         func = getfunc( key );
         if (func != RecordMacro && func != SaveMacro && func != LoadMacro &&
             func != ClearAllMacros) {

            /*
             * 如果next值是-1,表明到了记录的末尾
             */
            next = macro.first_stroke[g_status.recording_key - 256];
            if (macro.strokes[next].next != STROKE_LIMIT+1) {
               while (macro.strokes[next].next != -1)
                  next = macro.strokes[next].next;
            }
            prev = next;

            /*
             * 找到一个空间来记录当前的操作
             */
            if (macro.strokes[next].key != -1) {
               for (; next < STROKE_LIMIT &&
                            macro.strokes[next].next != STROKE_LIMIT+1;)
                  next++;
               if (next == STROKE_LIMIT) {
                  for (next=0; next < prev &&
                               macro.strokes[next].next != STROKE_LIMIT+1;)
                     next++;
               }
            }
            if (next == prev && macro.strokes[prev].key != -1)
               /*
                * 记录缓存没有记录
                */
               error( WARNING, line, main13 );
            else {
            /*
             * 如果我们正在记录第一个宏节点,那么next == prev
             */
               macro.strokes[prev].next = next;
               macro.strokes[next].next = -1;
               macro.strokes[next].key  = key;
               g_status.stroke_count--;
               show_avail_strokes( );
            }
         }
      }
   }
}
Exemple #22
0
/*
 * Name:    finish
 * Purpose: To remove the current window and terminate the program if no
 *           more windows are left.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   Order of deciding which window becomes current window:
 *          1) If any invisible window with same top and bottom line,
 *          and start_col and end_col, then first invisible one becomes
 *          current window.
 *          2) window above if it exists becomes current window
 *          3) window below if it exists becomes current window
 *          4) window right if it exists becomes current window
 *          5) window left  if it exists becomes current window
 *          6) first available invisible window becomes current window.
 *          When I added vertical windows, this routine became a LOT
 *           more complicated.  To keep things reasonably sane, let's
 *           only close windows that have three common edges, eg.
 *
 *                    ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
 *                    ³      ³    no    ³
 *                    ³      ÃÄÄÄÄÄÂÄÄÄÄ´
 *                    ³      ³yes1 ³yes1³
 *                    ³  no  ÃÄÄÄÄÄÁÄÄÄÄ´
 *                    ³      ³   yes2   ³
 *                    ³      ÃÄÄÄÄÄÄÄÄÄÄ´
 *                    ³      ³   yes2   ³
 *                    ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ
 *
 *          Windows with 'no' cannot be closed.  Windows with 'yes' can
 *          be combined with windows that have the same yes number.
 */
void finish( WINDOW *window )
{
    register WINDOW *wp;   /* for scanning other windows */
    register WINDOW *win;  /* register pointer for window */
    file_infos *file, *fp;  /* for scanning other files */
    int  poof;
    int  cline;
    int  top;
    int  bottom;
    int  start_col;
    int  end_col;
    int  max_letter;
    int  file_change = FALSE;
    line_list_ptr ll;
    line_list_ptr temp_ll;

    win = window;
    entab_linebuff( );
    if (un_copy_line( win->ll, win, TRUE ) == ERROR)
        return;

    file = win->file_info;
    /*
     * remove all hidden windows that point to same file
     */
    file = win->file_info;
    for (wp=g_status.window_list; wp != NULL; wp=wp->next) {
        if (wp->file_info == file) {
            if (!wp->visible) {
                if (wp->prev == NULL) {
                    if (wp->next == NULL)
                        g_status.stop = TRUE;
                    else
                        g_status.window_list = wp->next;
                } else
                    wp->prev->next = wp->next;
                if (wp->next)
                    wp->next->prev = wp->prev;
                --wp->file_info->ref_count;
                free( wp );
                --g_status.window_count;
            }
        }
    }

    if (win->prev == NULL && win->next == NULL)
        g_status.stop = TRUE;

    poof = FALSE;

    if (g_status.stop != TRUE) {
        /*
         * see if there are any invisible windows with same top and bottom,
         *  lines, and start_col and end_col as this window.  start looking at
         *  end of window list.
         */
        top       = win->top_line;
        bottom    = win->bottom_line;
        start_col = win->start_col;
        end_col   = win->end_col;
        wp = g_status.window_list;
        if (wp != NULL) {
            while (wp->next != NULL)
                wp = wp->next;
        }
        while (wp != NULL && poof == FALSE) {
            if (wp->top_line == top         &&  wp->bottom_line == bottom  &&
                    wp->start_col == start_col  &&  wp->end_col == end_col     &&
                    !wp->visible)
                poof = TRUE;
            else
                wp = wp->prev;
        }

        if (poof == FALSE) {
            /*
             * see if there are any windows above
             */
            wp = g_status.window_list;
            while (wp != NULL && poof == FALSE) {
                if (wp->bottom_line+2 == win->top_line &&
                        wp->start_col     == win->start_col &&
                        wp->end_col       == win->end_col   && wp->visible) {
                    poof = TRUE;
                    top  = wp->top_line;
                } else
                    wp = wp->next;
            }
            if (poof == FALSE) {
                /*
                 * see if there are any windows below
                 */
                wp = g_status.window_list;
                while (wp != NULL && poof == FALSE) {
                    if (wp->top_line-2 == win->bottom_line  &&
                            wp->start_col     == win->start_col &&
                            wp->end_col    == win->end_col   && wp->visible) {
                        poof = TRUE;
                        bottom = wp->bottom_line;
                    } else
                        wp = wp->next;
                }
            }
            if (poof == FALSE) {
                /*
                 * see if there are any windows right
                 */
                wp = g_status.window_list;
                while (wp != NULL && poof == FALSE) {
                    if (wp->top_line    == win->top_line  &&
                            wp->bottom_line == win->bottom_line &&
                            wp->start_col-2 == win->end_col     && wp->visible) {
                        poof = TRUE;
                        end_col = wp->end_col;
                    } else
                        wp = wp->next;
                }
            }
            if (poof == FALSE) {
                /*
                 * see if there are any windows left
                 */
                wp = g_status.window_list;
                while (wp != NULL && poof == FALSE) {
                    if (wp->top_line    == win->top_line  &&
                            wp->bottom_line == win->bottom_line &&
                            wp->end_col+2   == win->start_col   && wp->visible) {
                        poof = TRUE;
                        start_col = wp->start_col;
                    } else
                        wp = wp->next;
                }
            }
            if (poof == FALSE) {
                /*
                 * see if there are any other invisible windows.  start looking
                 *  at the end of the window list.
                 */
                wp = g_status.window_list;
                if (wp != NULL) {
                    while (wp->next != NULL)
                        wp = wp->next;
                }
                while (wp != NULL && poof == FALSE) {
                    if (!wp->visible)
                        poof = TRUE;
                    else
                        wp = wp->prev;
                }
            }
        }
        if (poof) {
            wp->visible = TRUE;
            cline = wp->cline - (wp->top_line+wp->ruler);
            wp->top_line = top;
            wp->bottom_line = bottom;
            wp->cline = (wp->top_line+wp->ruler) + cline;
            if (wp->cline > wp->bottom_line)
                wp->cline = wp->top_line+wp->ruler;
            wp->start_col = start_col;
            wp->end_col   = end_col;
            if (start_col == 0 && end_col == g_display.ncols - 1)
                wp->vertical = FALSE;
            else
                wp->vertical = TRUE;
            check_virtual_col( wp, wp->rcol, wp->ccol );
            setup_window( wp );
            show_window_header( wp );
            if (wp->vertical)
                show_vertical_separator( wp );

            /*
             * The window above, below, or previously invisible becomes the new
             *  current window.
             */
            g_status.current_window = wp;
        }
    }

    if (!poof && g_status.stop != TRUE)
        /*
         * cannot close current window
         */
        error( WARNING, win->bottom_line, win7 );
    else {

        /*
         * free unused file memory if necessary
         */
        if (--file->ref_count == 0) {

            /*
             * if a block is marked, unmark it
             */
            if (file == g_status.marked_file) {
                g_status.marked      = FALSE;
                g_status.marked_file = NULL;
            }

            for (fp=g_status.file_list; fp != NULL; fp=fp->next) {
                if (fp->file_no > file->file_no)
                    fp->file_no--;
            }
            file_change = file->file_no;

            /*
             * no window now refers to this file, so remove file from the list
             */
            if (file->prev == NULL)
                g_status.file_list = file->next;
            else
                file->prev->next = file->next;
            if (file->next)
                file->next->prev = file->prev;

            /*
             * free the line pointers, linked list of line pointers, and
             *  file struc.
             */
            ll = file->undo_top;
            while (ll != NULL) {
                temp_ll = ll->next;
                if (ll->line != NULL)
                    my_free( ll->line );
                my_free( ll );
                ll = temp_ll;
            }

            ll = file->line_list;
            while (ll != NULL) {
                temp_ll = ll->next;
                if (ll->line != NULL)
                    my_free( ll->line );
                my_free( ll );
                ll = temp_ll;
            }

#if defined( __MSC__ )
            _fheapmin( );
#endif

            free( file );
            if (--g_status.file_count) {
                show_file_count( g_status.file_count );
                show_avail_mem( );
            }
        }

        /*
         * remove the current window from the window list
         */
        if (win->prev == NULL)
            g_status.window_list = win->next;
        else
            win->prev->next = win->next;

        if (win->next)
            win->next->prev = win->prev;

        if (diff.defined  &&  (diff.w1 == win  ||  diff.w2 == win))
            diff.defined = FALSE;

        /*
         * free the memory taken by the window structure
         */
        free( win );
        --g_status.window_count;

        if (g_status.stop == FALSE) {
            g_status.current_file = wp->file_info;
            wp->file_info->dirty = LOCAL;
            make_ruler( wp );
            show_ruler( wp );
            show_window_count( g_status.window_count );
            if (file_change) {
                for (wp=g_status.window_list; wp!=NULL; wp=wp->next)
                    if (wp->visible)
                        show_window_number_letter( wp );
            } else {
                max_letter = 'a';
                for (wp=g_status.window_list; wp!=NULL; wp=wp->next) {
                    if (wp->file_info == file && wp->letter > max_letter)
                        max_letter = wp->letter;
                }
                if (max_letter < file->next_letter - 1)
                    file->next_letter = max_letter + 1;
            }
        }
    }

    if (g_status.stop == TRUE) {
        if (g_status.sas_defined && g_status.sas_arg < g_status.sas_argc) {
            show_avail_mem( );
            for (bottom=0; bottom <= g_display.nlines; bottom++)
                eol_clear( 0, bottom, g_display.text_color );
            bottom  = g_display.nlines;
            set_prompt( win18, bottom );
            top = getkey( );
            top = getfunc( top );
            eol_clear( 0, bottom, g_display.text_color );
            if (top == RepeatGrep) {
                g_status.command = RepeatGrep;
                g_status.window_list = g_status.current_window = NULL;
                if (search_and_seize( g_status.window_list ) != ERROR)
                    g_status.stop = FALSE;
            }
        }
    }
}
Exemple #23
0
/*
 * Name:    size_window
 * Purpose: To change the size of the current and one other window.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   Use the Up and Down arrow keys to make the current window
 *           bigger or smaller.  The window above will either grow
 *           or contract accordingly.
 */
int  size_window( WINDOW *window )
{
    char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute  */
    int  func;
    int  c;
    int  resize;
    int  show_above_ruler;
    int  old_bottom_line;
    int  old_top_line;
    int  new_bottom_line;
    int  new_top_line;
    register WINDOW *above;
    register WINDOW *win;

    win = window;
    if (win->top_line != 1 && !win->vertical) {
        entab_linebuff( );
        un_copy_line( win->ll, win, TRUE );
        save_screen_line( 0, win->bottom_line, line_buff );

        /*
         * press up or down to change window size
         */
        set_prompt( win4, win->bottom_line );

        /*
         * resizing only affects current window and above visible window
         */
        above = g_status.window_list;
        while (above->bottom_line + 2 != win->top_line || !above->visible)
            above = above->next;
        if (above->vertical)
            /*
             * cannot resize vertical window
             */
            error( WARNING, win->bottom_line, win5 );
        else {
            old_top_line = win->top_line;
            old_bottom_line = above->bottom_line;
            show_above_ruler = FALSE;
            for (func=0; func != AbortCommand && func != Rturn; ) {

                /*
                 * If user has redined the ESC and Return keys, make them Rturn and
                 *  AbortCommand in this function.
                 */
                c = getkey( );
                func = getfunc( c );
                if (c == RTURN || func == NextLine || func == BegNextLine)
                    func = Rturn;
                else if (c == ESC)
                    func = AbortCommand;
                resize = FALSE;

                /*
                 * if LineUp, make current window top line grow and bottom line
                 *  of above window shrink.  if window movement covers up current
                 *  line of window then we must adjust logical line and real line.
                 */
                if (func == LineUp) {
                    if (above->bottom_line > above->top_line + above->ruler) {
                        if (win->rline == (win->cline - (win->top_line+win->ruler-1)))
                            --win->cline;
                        --win->top_line;
                        if (above->cline == above->bottom_line)
                            --above->cline;
                        --above->bottom_line;
                        resize = TRUE;
                        if (mode.ruler) {
                            if (win->ruler == FALSE) {
                                if (win->cline == win->top_line)
                                    ++win->cline;
                                if (win->cline > win->bottom_line)
                                    win->cline = win->bottom_line;
                                win->ruler = TRUE;
                            }
                        }
                    }

                    /*
                     * if LineDown, make current window top line shrink and bottom line
                     *  of above window grow.  if window movement covers up current
                     *  line of window then we must adjust logical line and real line.
                     */
                } else if (func == LineDown) {
                    if (win->bottom_line > win->top_line + win->ruler) {
                        if (win->cline == win->top_line + win->ruler)
                            ++win->cline;
                        ++win->top_line;
                        ++above->bottom_line;
                        resize = TRUE;
                        if (mode.ruler) {
                            if (above->ruler == FALSE) {
                                if (above->cline == above->top_line)
                                    ++above->cline;
                                if (above->cline > above->bottom_line)
                                    above->cline = above->bottom_line;
                                above->ruler = TRUE;
                                make_ruler( above );
                                show_above_ruler = TRUE;
                            }
                        }
                    }
                }

                /*
                 * if we resize a window, then update window size and current and
                 *  real lines if needed.
                 */
                if (resize == TRUE) {
                    setup_window( above );
                    display_current_window( above );
                    if (show_above_ruler) {
                        show_ruler( above );
                        show_ruler_pointer( above );
                        show_above_ruler = FALSE;
                    }
                    setup_window( win );
                    show_window_header( win );
                    win->ruler = mode.ruler;
                    make_ruler( win );
                    show_ruler( win );
                    show_ruler_pointer( win );
                    display_current_window( win );
                    save_screen_line( 0, win->bottom_line, line_buff );

                    /*
                     * press up or down to change window size
                     */
                    set_prompt( win4, win->bottom_line );
                }
            }
            new_top_line = win->top_line;
            new_bottom_line = above->bottom_line;
            for (above=g_status.window_list; above != NULL; above=above->next) {
                if (!above->visible) {
                    if (above->bottom_line == old_bottom_line) {
                        above->bottom_line = new_bottom_line;
                        if (above->cline < new_bottom_line)
                            above->cline = new_bottom_line;
                        setup_window( above );
                    } else if (above->top_line == old_top_line) {
                        above->top_line = new_top_line;
                        if (above->cline < new_top_line)
                            above->cline = new_top_line;
                        if ((long)(above->cline+1L - (above->top_line+above->ruler)) >
                                above->rline)
                            above->cline = (int)above->rline + above->top_line +
                                           above->ruler - 1;
                        setup_window( above );
                    }
                }
            }
        }
        restore_screen_line( 0, win->bottom_line, line_buff );
    } else {
        if (win->vertical)
            /*
             * cannot resize vertical window
             */
            error( WARNING, win->bottom_line, win5 );
        else
            /*
             * cannot resize top window
             */
            error( WARNING, win->bottom_line, win6 );
    }
    return( OK );
}
Exemple #24
0
void
init_builtin_functions(struct tc_globals *tg) {
	struct tc_func *head = calloc(1, sizeof(struct tc_func));
	head->returntype = malloc(sizeof(struct type));
	head->returntype->type = T_WORD;
	head->returntype->pm_name = "t";
	head->returntype->accept_empty_list = 0; // ?
	head->name = "head";
	head->args = malloc(sizeof(struct func_arg));
	head->args->name = "list";
	head->args->type = malloc(sizeof(struct type));
	head->args->type->type = '[';
	head->args->type->list_type = malloc(sizeof(struct type));
	head->args->type->list_type->type = T_WORD;
	head->args->type->list_type->pm_name = "t";
	head->args->type->list_type->accept_empty_list = 0; // ?
	head->args->farg = 0;
	head->args->next = NULL;
	head->decls = NULL;
	head->func = getfunc();
	head->nargs = 1;
	head->nlocals = 0;
	head->next = NULL;

	builtin_head = head->func;
	*tg->funcs_last = head;
	tg->funcs_last = &head->next;

	struct tc_func *tail = calloc(1, sizeof(struct tc_func));
	tail->returntype = malloc(sizeof(struct type));
	tail->returntype->type = '[';
	tail->returntype->list_type = malloc(sizeof(struct type));
	tail->returntype->list_type->type = T_WORD;
	tail->returntype->list_type->pm_name = "t";
	tail->returntype->list_type->accept_empty_list = 0; // ?
	tail->name = "tail";
	tail->args = malloc(sizeof(struct func_arg));
	tail->args->name = "list";
	tail->args->type = malloc(sizeof(struct type));
	tail->args->type->type = '[';
	tail->args->type->list_type = malloc(sizeof(struct type));
	tail->args->type->list_type->type = T_WORD;
	tail->args->type->list_type->pm_name = "t";
	tail->args->type->list_type->accept_empty_list = 0; // ?
	tail->args->farg = 0;
	tail->args->next = NULL;
	tail->decls = NULL;
	tail->func = getfunc();
	tail->nargs = 1;
	tail->nlocals = 0;
	tail->next = NULL;

	builtin_tail = tail->func;
	*tg->funcs_last = tail;
	tg->funcs_last = &tail->next;

	struct tc_func *isempty = calloc(1, sizeof(struct tc_func));
	isempty->returntype = malloc(sizeof(struct type));
	isempty->returntype->type = T_BOOL;
	isempty->name = "isempty";
	isempty->args = malloc(sizeof(struct func_arg));
	isempty->args->name = "list";
	isempty->args->type = malloc(sizeof(struct type));
	isempty->args->type->type = '[';
	isempty->args->type->list_type = malloc(sizeof(struct type));
	isempty->args->type->list_type->type = T_WORD;
	isempty->args->type->list_type->pm_name = "t";
	isempty->args->type->list_type->accept_empty_list = 0; // ?
	isempty->args->farg = 0;
	isempty->args->next = NULL;
	isempty->decls = NULL;
	isempty->func = getfunc();
	isempty->nargs = 1;
	isempty->nlocals = 0;
	isempty->next = NULL;

	builtin_isempty = isempty->func;
	*tg->funcs_last = isempty;
	tg->funcs_last = &isempty->next;

	struct tc_func *fst = calloc(1, sizeof(struct tc_func));
	fst->returntype = malloc(sizeof(struct type));
	fst->returntype->type = T_WORD;
	fst->returntype->pm_name = "f";
	fst->returntype->accept_empty_list = 0;
	fst->name = "fst";
	fst->args = malloc(sizeof(struct func_arg));
	fst->args->name = "tuple";
	fst->args->type = malloc(sizeof(struct type));
	fst->args->type->type = '(';
	fst->args->type->fst_type = malloc(sizeof(struct type));
	fst->args->type->fst_type->type = T_WORD;
	fst->args->type->fst_type->pm_name = "f";
	fst->args->type->fst_type->accept_empty_list = 0;
	fst->args->type->snd_type = malloc(sizeof(struct type));
	fst->args->type->snd_type->type = T_WORD;
	fst->args->type->snd_type->pm_name = "s";
	fst->args->type->snd_type->accept_empty_list = 0;
	fst->args->farg = 0;
	fst->args->next = NULL;
	fst->decls = NULL;
	fst->func = getfunc();
	fst->nargs = 1;
	fst->nlocals = 0;
	fst->next = NULL;

	builtin_fst = fst->func;
	*tg->funcs_last = fst;
	tg->funcs_last = &fst->next;

	struct tc_func *snd = calloc(1, sizeof(struct tc_func));
	snd->returntype = malloc(sizeof(struct type));
	snd->returntype->type = T_WORD;
	snd->returntype->pm_name = "s";
	snd->returntype->accept_empty_list = 0;
	snd->name = "snd";
	snd->args = malloc(sizeof(struct func_arg));
	snd->args->name = "tuple";
	snd->args->type = malloc(sizeof(struct type));
	snd->args->type->type = '(';
	snd->args->type->fst_type = malloc(sizeof(struct type));
	snd->args->type->fst_type->type = T_WORD;
	snd->args->type->fst_type->pm_name = "f";
	snd->args->type->fst_type->accept_empty_list = 0;
	snd->args->type->snd_type = malloc(sizeof(struct type));
	snd->args->type->snd_type->type = T_WORD;
	snd->args->type->snd_type->pm_name = "s";
	snd->args->type->snd_type->accept_empty_list = 0;
	snd->args->farg = 0;
	snd->args->next = NULL;
	snd->decls = NULL;
	snd->func = getfunc();
	snd->nargs = 1;
	snd->nlocals = 0;
	snd->next = NULL;

	builtin_snd = snd->func;
	*tg->funcs_last = snd;
	tg->funcs_last = &snd->next;
}
Exemple #25
0
int
m_brdf2(			/* color a ray that hit a BRDF material */
	OBJREC  *m,
	RAY  *r
)
{
	BRDFDAT  nd;
	COLOR  ctmp;
	FVECT  vtmp;
	double  dtmp;
						/* always a shadow */
	if (r->crtype & SHADOW)
		return(1);
						/* check arguments */
	if ((m->oargs.nsargs < (hasdata(m->otype)?4:2)) | (m->oargs.nfargs <
			((m->otype==MAT_TFUNC)|(m->otype==MAT_TDATA)?6:4)))
		objerror(m, USER, "bad # arguments");
						/* check for back side */
	if (r->rod < 0.0) {
		if (!backvis) {
			raytrans(r);
			return(1);
		}
		raytexture(r, m->omod);
		flipsurface(r);			/* reorient if backvis */
	} else
		raytexture(r, m->omod);

	nd.mp = m;
	nd.pr = r;
						/* get material color */
	setcolor(nd.mcolor, m->oargs.farg[0],
			m->oargs.farg[1],
			m->oargs.farg[2]);
						/* get specular component */
	nd.rspec = m->oargs.farg[3];
						/* compute transmittance */
	if ((m->otype == MAT_TFUNC) | (m->otype == MAT_TDATA)) {
		nd.trans = m->oargs.farg[4]*(1.0 - nd.rspec);
		nd.tspec = nd.trans * m->oargs.farg[5];
		dtmp = nd.trans - nd.tspec;
		setcolor(nd.tdiff, dtmp, dtmp, dtmp);
	} else {
		nd.tspec = nd.trans = 0.0;
		setcolor(nd.tdiff, 0.0, 0.0, 0.0);
	}
						/* compute reflectance */
	dtmp = 1.0 - nd.trans - nd.rspec;
	setcolor(nd.rdiff, dtmp, dtmp, dtmp);
	nd.pdot = raynormal(nd.pnorm, r);	/* perturb normal */
	multcolor(nd.mcolor, r->pcol);		/* modify material color */
	multcolor(nd.rdiff, nd.mcolor);
	multcolor(nd.tdiff, nd.mcolor);
						/* load auxiliary files */
	if (hasdata(m->otype)) {
		nd.dp = getdata(m->oargs.sarg[1]);
		getfunc(m, 2, 0, 0);
	} else {
		nd.dp = NULL;
		getfunc(m, 1, 0, 0);
	}
						/* compute ambient */
	if (nd.trans < 1.0-FTINY) {
		copycolor(ctmp, nd.mcolor);	/* modified by material color */
		scalecolor(ctmp, 1.0-nd.trans);
		multambient(ctmp, r, nd.pnorm);
		addcolor(r->rcol, ctmp);	/* add to returned color */
	}
	if (nd.trans > FTINY) {		/* from other side */
		flipsurface(r);
		vtmp[0] = -nd.pnorm[0];
		vtmp[1] = -nd.pnorm[1];
		vtmp[2] = -nd.pnorm[2];
		copycolor(ctmp, nd.mcolor);
		scalecolor(ctmp, nd.trans);
		multambient(ctmp, r, vtmp);
		addcolor(r->rcol, ctmp);
		flipsurface(r);
	}
						/* add direct component */
	direct(r, dirbrdf, &nd);

	return(1);
}
Exemple #26
0
int
m_brdf(			/* color a ray that hit a BRDTfunc material */
	OBJREC  *m,
	RAY  *r
)
{
	int  hitfront = 1;
	BRDFDAT  nd;
	RAY  sr;
	double  mirtest=0, mirdist=0;
	double  transtest=0, transdist=0;
	int  hasrefl, hastrans;
	int  hastexture;
	COLOR  ctmp;
	FVECT  vtmp;
	double  d;
	MFUNC  *mf;
	int  i;
						/* check arguments */
	if ((m->oargs.nsargs < 10) | (m->oargs.nfargs < 9))
		objerror(m, USER, "bad # arguments");
	nd.mp = m;
	nd.pr = r;
						/* dummy values */
	nd.rspec = nd.tspec = 1.0;
	nd.trans = 0.5;
						/* diffuse reflectance */
	if (r->rod > 0.0)
		setcolor(nd.rdiff, m->oargs.farg[0],
				m->oargs.farg[1],
				m->oargs.farg[2]);
	else
		setcolor(nd.rdiff, m->oargs.farg[3],
				m->oargs.farg[4],
				m->oargs.farg[5]);
						/* diffuse transmittance */
	setcolor(nd.tdiff, m->oargs.farg[6],
			m->oargs.farg[7],
			m->oargs.farg[8]);
						/* get modifiers */
	raytexture(r, m->omod);
	hastexture = DOT(r->pert,r->pert) > FTINY*FTINY;
	if (hastexture) {			/* perturb normal */
		nd.pdot = raynormal(nd.pnorm, r);
	} else {
		VCOPY(nd.pnorm, r->ron);
		nd.pdot = r->rod;
	}
	if (r->rod < 0.0) {			/* orient perturbed values */
		nd.pdot = -nd.pdot;
		for (i = 0; i < 3; i++) {
			nd.pnorm[i] = -nd.pnorm[i];
			r->pert[i] = -r->pert[i];
		}
		hitfront = 0;
	}
	copycolor(nd.mcolor, r->pcol);		/* get pattern color */
	multcolor(nd.rdiff, nd.mcolor);		/* modify diffuse values */
	multcolor(nd.tdiff, nd.mcolor);
	hasrefl = bright(nd.rdiff) > FTINY;
	hastrans = bright(nd.tdiff) > FTINY;
						/* load cal file */
	nd.dp = NULL;
	mf = getfunc(m, 9, 0x3f, 0);
						/* compute transmitted ray */
	setbrdfunc(&nd);
	errno = 0;
	setcolor(ctmp, evalue(mf->ep[3]),
			evalue(mf->ep[4]),
			evalue(mf->ep[5]));
	if ((errno == EDOM) | (errno == ERANGE))
		objerror(m, WARNING, "compute error");
	else if (rayorigin(&sr, TRANS, r, ctmp) == 0) {
		if (!(r->crtype & SHADOW) && hastexture) {
						/* perturb direction */
			VSUM(sr.rdir, r->rdir, r->pert, -.75);
			if (normalize(sr.rdir) == 0.0) {
				objerror(m, WARNING, "illegal perturbation");
				VCOPY(sr.rdir, r->rdir);
			}
		} else {
			VCOPY(sr.rdir, r->rdir);
		}
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		addcolor(r->rcol, sr.rcol);
		if (!hastexture) {
			transtest = 2.0*bright(sr.rcol);
			transdist = r->rot + sr.rt;
		}
	}
	if (r->crtype & SHADOW)			/* the rest is shadow */
		return(1);
						/* compute reflected ray */
	setbrdfunc(&nd);
	errno = 0;
	setcolor(ctmp, evalue(mf->ep[0]),
			evalue(mf->ep[1]),
			evalue(mf->ep[2]));
	if ((errno == EDOM) | (errno == ERANGE))
		objerror(m, WARNING, "compute error");
	else if (rayorigin(&sr, REFLECTED, r, ctmp) == 0) {
		VSUM(sr.rdir, r->rdir, nd.pnorm, 2.*nd.pdot);
		checknorm(sr.rdir);
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		addcolor(r->rcol, sr.rcol);
		if (!hastexture && r->ro != NULL && isflat(r->ro->otype)) {
			mirtest = 2.0*bright(sr.rcol);
			mirdist = r->rot + sr.rt;
		}
	}
						/* compute ambient */
	if (hasrefl) {
		if (!hitfront)
			flipsurface(r);
		copycolor(ctmp, nd.rdiff);
		multambient(ctmp, r, nd.pnorm);
		addcolor(r->rcol, ctmp);	/* add to returned color */
		if (!hitfront)
			flipsurface(r);
	}
	if (hastrans) {				/* from other side */
		if (hitfront)
			flipsurface(r);
		vtmp[0] = -nd.pnorm[0];
		vtmp[1] = -nd.pnorm[1];
		vtmp[2] = -nd.pnorm[2];
		copycolor(ctmp, nd.tdiff);
		multambient(ctmp, r, vtmp);
		addcolor(r->rcol, ctmp);
		if (hitfront)
			flipsurface(r);
	}
	if (hasrefl | hastrans || m->oargs.sarg[6][0] != '0')
		direct(r, dirbrdf, &nd);	/* add direct component */

	d = bright(r->rcol);			/* set effective distance */
	if (transtest > d)
		r->rt = transdist;
	else if (mirtest > d)
		r->rt = mirdist;

	return(1);
}
Exemple #27
0
extern int
load_os(			/* load associated data for object */
	register OBJREC	*op
)
{
	DATARRAY  *dp;

	switch (op->otype) {
	case OBJ_FACE:		/* polygon */
		getface(op);
		return(1);
	case OBJ_CONE:		/* cone */
	case OBJ_RING:		/* disk */
	case OBJ_CYLINDER:	/* cylinder */
	case OBJ_CUP:		/* inverted cone */
	case OBJ_TUBE:		/* inverted cylinder */
		getcone(op, 1);
		return(1);
	case OBJ_INSTANCE:	/* octree instance */
		getinstance(op, IO_ALL);
		return(1);
	case OBJ_MESH:		/* mesh instance */
		getmeshinst(op, IO_ALL);
		return(1);
	case PAT_CPICT:		/* color picture */
		if (op->oargs.nsargs < 4)
			goto sargerr;
		getpict(op->oargs.sarg[3]);
		getfunc(op, 4, 0x3<<5, 0);
		return(1);
	case PAT_CDATA:		/* color data */
		dp = getdata(op->oargs.sarg[3]);
		getdata(op->oargs.sarg[4]);
		getdata(op->oargs.sarg[5]);
		getfunc(op, 6, ((1<<dp->nd)-1)<<7, 0);
		return(1);
	case PAT_BDATA:		/* brightness data */
		if (op->oargs.nsargs < 2)
			goto sargerr;
		dp = getdata(op->oargs.sarg[1]);
		getfunc(op, 2, ((1<<dp->nd)-1)<<3, 0);
		return(1);
	case PAT_BFUNC:		/* brightness function */
		getfunc(op, 1, 0x1, 0);
		return(1);
	case PAT_CFUNC:		/* color function */
		getfunc(op, 3, 0x7, 0);
		return(1);
	case TEX_DATA:		/* texture data */
		if (op->oargs.nsargs < 6)
			goto sargerr;
		dp = getdata(op->oargs.sarg[3]);
		getdata(op->oargs.sarg[4]);
		getdata(op->oargs.sarg[5]);
		getfunc(op, 6, ((1<<dp->nd)-1)<<7, 1);
		return(1);
	case TEX_FUNC:		/* texture function */
		getfunc(op, 3, 0x7, 1);
		return(1);
	case MIX_DATA:		/* mixture data */
		dp = getdata(op->oargs.sarg[3]);
		getfunc(op, 4, ((1<<dp->nd)-1)<<5, 0);
		return(1);
	case MIX_PICT:		/* mixture picture */
		getpict(op->oargs.sarg[3]);
		getfunc(op, 4, 0x3<<5, 0);
		return(1);
	case MIX_FUNC:		/* mixture function */
		getfunc(op, 3, 0x4, 0);
		return(1);
	case MAT_PLASTIC2:	/* anisotropic plastic */
	case MAT_METAL2:	/* anisotropic metal */
		getfunc(op, 3, 0x7, 1);
		return(1);
	case MAT_BRTDF:		/* BRDTfunc material */
		getfunc(op, 9, 0x3f, 0);
		return(1);
	case MAT_BSDF:		/* BSDF material */
		if (op->oargs.nsargs < 6)
			goto sargerr;
		getfunc(op, 5, 0x1d, 1);
		loadBSDF(op->oargs.sarg[1]);
		return(1);
	case MAT_PDATA:		/* plastic BRDF data */
	case MAT_MDATA:		/* metal BRDF data */
	case MAT_TDATA:		/* trans BRDF data */
		if (op->oargs.nsargs < 2)
			goto sargerr;
		getdata(op->oargs.sarg[1]);
		getfunc(op, 2, 0, 0);
		return(1);
	case MAT_PFUNC:		/* plastic BRDF func */
	case MAT_MFUNC:		/* metal BRDF func */
	case MAT_TFUNC:		/* trans BRDF func */
		getfunc(op, 1, 0, 0);
		return(1);
	case MAT_DIRECT1:	/* prism1 material */
		getfunc(op, 4, 0xf, 1);
		return(1);
	case MAT_DIRECT2:	/* prism2 material */
		getfunc(op, 8, 0xff, 1);
		return(1);
	}
			/* nothing to load for the remaining types */
	return(0);
sargerr:
	objerror(op, USER, "too few string arguments");
	return 0; /* pro forma return */
}