Ejemplo n.º 1
0
static void
dup_dir_check5(struct db_i *input_dbip,
	       const struct db5_raw_internal *rip,
	       off_t addr,
	       void *ptr)
{
    char *name;
    struct directory *dupdp;
    struct bu_vls local = BU_VLS_INIT_ZERO;
    struct dir_check_stuff *dcsp = (struct dir_check_stuff *)ptr;

    if (dcsp->main_dbip == DBI_NULL)
	return;

    RT_CK_DBI(input_dbip);
    RT_CK_RIP(rip);

    if (rip->h_dli == DB5HDR_HFLAGS_DLI_HEADER_OBJECT) return;
    if (rip->h_dli == DB5HDR_HFLAGS_DLI_FREE_STORAGE) return;

    name = (char *)rip->name.ext_buf;

    if (name == (char *)NULL) return;
    if (addr == 0) return;

    /* do not compare _GLOBAL */
    if (rip->major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY &&
	rip->minor_type == 0)
	return;

    /* Add the prefix, if any */
    if (db_version(dcsp->main_dbip) < 5) {
	if (dcsp->wdbp->wdb_ncharadd > 0) {
	    bu_vls_strncpy(&local, bu_vls_addr(&dcsp->wdbp->wdb_prestr), dcsp->wdbp->wdb_ncharadd);
	    bu_vls_strcat(&local, name);
	} else {
	    bu_vls_strncpy(&local, name, _GED_V4_MAXNAME);
	}
	bu_vls_trunc(&local, _GED_V4_MAXNAME);
    } else {
	if (dcsp->wdbp->wdb_ncharadd > 0) {
	    (void)bu_vls_vlscat(&local, &dcsp->wdbp->wdb_prestr);
	    (void)bu_vls_strcat(&local, name);
	} else {
	    (void)bu_vls_strcat(&local, name);
	}
    }

    /* Look up this new name in the existing (main) database */
    if ((dupdp = db_lookup(dcsp->main_dbip, bu_vls_addr(&local), LOOKUP_QUIET)) != RT_DIR_NULL) {
	/* Duplicate found, add it to the list */
	dcsp->wdbp->wdb_num_dups++;
	*dcsp->dup_dirp++ = dupdp;
    }

    bu_vls_free(&local);

    return;
}
Ejemplo n.º 2
0
void
rt_vlist_import(struct bu_list *hp, struct bu_vls *namevls, const unsigned char *buf)
{
    register const unsigned char *bp;
    const unsigned char *pp;		/* point pointer */
    size_t nelem;
    size_t namelen;
    size_t i;

    /* must be double for import and export */
    double point[ELEMENTS_PER_POINT];

    BU_CK_VLS(namevls);

    nelem = ntohl(*(uint32_t *)buf);
    bp = buf+4;

    namelen = strlen((char *)bp)+1;
    bu_vls_strncpy(namevls, (char *)bp, namelen);
    bp += namelen;

    pp = bp + nelem*1;

    for (i=0; i < nelem; i++) {
	int cmd;

	cmd = *bp++;
	ntohd((unsigned char *)point, pp, ELEMENTS_PER_POINT);
	pp += ELEMENTS_PER_POINT*SIZEOF_NETWORK_DOUBLE;
	BN_ADD_VLIST(&rt_g.rtg_vlfree, hp, point, cmd);
    }
}
Ejemplo n.º 3
0
static int
charclassmatch(const char *pattern, char test, int *s)
{
    char c;
    int counter = 0;
    int resultholder = 0;
    struct bu_vls classname = BU_VLS_INIT_ZERO;
    CHARCLASS *ctclass;

    c = *pattern++;
    while (c && (c != ':') && (resultholder != -1)) {
	if (c == FNMATCH_EOS) resultholder = -1;
	counter++;

	c = *pattern++; /* next */
    }
    c = *pattern++;
    bu_vls_strncpy(&classname, pattern-counter-2, counter);

    ctclass = findclass(bu_vls_addr(&classname));
    if (ctclass == NULL) {
	bu_log("Unknown character class type: %s\n", bu_vls_addr(&classname));
	resultholder = -1;
    } else {
	/*bu_log("classname: %s, test char = %c, (class->checkfun)=%d\n", bu_vls_addr(&classname), test, (ctclass->checkfun)(test));*/
	if ((ctclass->checkfun)(test) != 0) {
	    resultholder = counter;
	} else {
	    resultholder = 0;
	}
    }
    *s = resultholder;
    bu_vls_free(&classname);
    return counter;
}
Ejemplo n.º 4
0
double
getdouble(char *cp, int start, size_t len)
{
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    double result;

    bu_vls_strncpy(&vls, cp+start, len);
    result = atof(vls.vls_str);
    bu_vls_free(&vls);

    return result;
}
Ejemplo n.º 5
0
int
getint(char *cp, int start, size_t len)
{
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    int result;

    bu_vls_strncpy(&vls, cp+start, len);
    result = atoi(vls.vls_str);
    bu_vls_free(&vls);

    return result;
}
Ejemplo n.º 6
0
/**
 *@brief
 * Check a name against the global directory.
 */
static int
dup_dir_check(struct db_i *input_dbip, const char *name, off_t UNUSED(laddr), size_t UNUSED(len), int UNUSED(flags), void *ptr)
{
    struct directory *dupdp;
    struct bu_vls local = BU_VLS_INIT_ZERO;
    struct dir_check_stuff *dcsp = (struct dir_check_stuff *)ptr;

    if (dcsp->main_dbip == DBI_NULL)
	return 0;

    RT_CK_DBI(input_dbip);

    /* Add the prefix, if any */
    if (db_version(dcsp->main_dbip) < 5) {
	if (dcsp->wdbp->wdb_ncharadd > 0) {
	    bu_vls_strncpy(&local, bu_vls_addr(&dcsp->wdbp->wdb_prestr), dcsp->wdbp->wdb_ncharadd);
	    bu_vls_strcat(&local, name);
	} else {
	    bu_vls_strncpy(&local, name, _GED_V4_MAXNAME);
	}
	bu_vls_trunc(&local, _GED_V4_MAXNAME);
    } else {
	if (dcsp->wdbp->wdb_ncharadd > 0) {
	    bu_vls_vlscat(&local, &dcsp->wdbp->wdb_prestr);
	    bu_vls_strcat(&local, name);
	} else {
	    bu_vls_strcat(&local, name);
	}
    }

    /* Look up this new name in the existing (main) database */
    if ((dupdp = db_lookup(dcsp->main_dbip, bu_vls_addr(&local), LOOKUP_QUIET)) != RT_DIR_NULL) {
	/* Duplicate found, add it to the list */
	dcsp->wdbp->wdb_num_dups++;
	*dcsp->dup_dirp++ = dupdp;
    }
    bu_vls_free(&local);
    return 0;
}
Ejemplo n.º 7
0
/*
 *			E X T _ S E T U P
 *
 *  Returns 0 on failure, 1 on success.
 */
HIDDEN int
ext_setup(register struct region *rp, struct bu_vls *matparm, char **dpp, struct mfuncs *mf_p, struct rt_i *rtip, struct mfuncs **headp)

    /* parameter string */
    /* pointer to user data pointer */


{
    struct bu_mapped_file	*parameter_file;
    struct bu_vls		parameter_data;
    char			*filename;
    int			status;

    RT_CHECK_RTI(rtip);
    BU_CK_VLS( matparm );
    RT_CK_REGION(rp);

    filename = bu_vls_addr(matparm);
    parameter_file = bu_open_mapped_file( filename, (char *)NULL );
    if (!parameter_file) {
	bu_log("cannot open external shader file \"%s\"\n", filename);
	bu_bomb("ext_setup()\n");
    }

    bu_vls_init(&parameter_data);
    bu_vls_strncpy( &parameter_data, (char *)parameter_file->buf,
		    parameter_file->buflen );

    if (rdebug&RDEBUG_SHADE ) {
	bu_log("ext_setup(%s): {%s}\n",
	       filename, bu_vls_addr(&parameter_data));
    }

    bu_close_mapped_file( parameter_file );

    status = sh_stk_setup(rp, &parameter_data, dpp, mf_p, rtip, headp);

    bu_vls_free( &parameter_data );

    return status;
}
Ejemplo n.º 8
0
void
Make_brlcad_names( struct obj_info *part )
{
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    int count=0;
    char *tmp_name, *ptr;
    Tcl_HashEntry *hash_entry=NULL;

    if ( use_part_name_hash ) {
	hash_entry = Tcl_FindHashEntry( &htbl, part->obj_name );
	if ( !hash_entry ) {
	    /* try without any name extension */
	    if ( (ptr=strrchr( part->obj_name, '_' )) != NULL ) {
		bu_vls_strncpy( &vls, part->obj_name, (ptr - part->obj_name) );
		hash_entry = Tcl_FindHashEntry( &htbl, bu_vls_addr( &vls ) );
	    }
	}

	if ( !hash_entry ) {
	    /* try without any name extension */
	    if ( (ptr=strchr( part->obj_name, '_' )) != NULL ) {
		bu_vls_strncpy( &vls, part->obj_name, (ptr - part->obj_name) );
		hash_entry = Tcl_FindHashEntry( &htbl, bu_vls_addr( &vls ) );
	    }
	}

	if ( !hash_entry ) {
	    /* try adding "-011" */
	    if ( (ptr=strchr( part->obj_name, '-' ))  != NULL ) {
		bu_vls_strncpy( &vls, part->obj_name, (ptr - part->obj_name) );
		bu_vls_strcat( &vls, "-011" );
		hash_entry = Tcl_FindHashEntry( &htbl, bu_vls_addr( &vls ) );
	    }
	}

	if ( !hash_entry ) {
	    name_not_converted++;
	}
    }

    bu_vls_free( &vls );
    if ( hash_entry ) {
	tmp_name = bu_strdup( (char *)Tcl_GetHashValue( hash_entry ) );
    } else {
	if ( use_part_name_hash ) {
	    bu_log( "\tWarning: no name found for part %s\n", part->obj_name );
	}
	/* make a copy of object name, then make it a legal BRL-CAD name */
	if ( strlen( part->obj_name ) < 1 ) {
	    tmp_name = bu_strdup( "s.1" );
	} else {
	    tmp_name = bu_strdup( part->obj_name );
	    ptr = tmp_name;
	    while ( *ptr != '\0' ) {
		if ( !(isalnum( (int)*ptr ) || *ptr == '-')) {
		    *ptr = '_';
		}
		ptr++;
	    }
	}
    }

    if ( part->obj_type == PART_TYPE ) {
	/* find a unique solid name */
	bu_vls_printf( &vls, "s.%s", tmp_name );
	if ( max_name_len ) {
	    bu_vls_trunc( &vls, max_name_len );
	}
	while ( db_lookup( fd_out->dbip, bu_vls_addr( &vls ), LOOKUP_QUIET ) != RT_DIR_NULL) {
	    count++;

	    if ( max_name_len ) {
		int digits = 1;
		int val = 10;

		while ( count >= val ) {
		    digits++;
		    val *= 10;
		}

		bu_vls_trunc( &vls, 0 );
		bu_vls_printf( &vls, "s.%s", tmp_name );
		bu_vls_trunc( &vls, max_name_len - digits - 1 );
		bu_vls_printf( &vls, ".%d", count );
	    } else {
		bu_vls_trunc( &vls, 0 );
		bu_vls_printf( &vls, "s.%s.%d", tmp_name, count );
	    }
	}
	part->brlcad_solid = bu_vls_strgrab( &vls );
    } else {
	part->brlcad_solid = NULL;
    }

    /* find a unique non-primitive name */
    bu_vls_printf( &vls, "%s", tmp_name );
    if ( max_name_len ) {
	bu_vls_trunc( &vls, max_name_len );
    }
    while ( db_lookup( fd_out->dbip, bu_vls_addr( &vls ), LOOKUP_QUIET) != RT_DIR_NULL ) {
	count++;

	if ( max_name_len ) {
	    int digits = 1;
	    int val = 10;

	    while ( count >= val ) {
		digits++;
		val *= 10;
	    }
	    bu_vls_trunc( &vls, 0 );
	    bu_vls_printf( &vls, "%s", tmp_name );
	    bu_vls_trunc( &vls, max_name_len - digits - 1 );
	    bu_vls_printf( &vls, ".%d", count );
	} else {
	    bu_vls_trunc( &vls, 0 );
	    bu_vls_printf( &vls, "%s.%d", tmp_name, count );
	}
    }
    part->brlcad_comb = bu_vls_strgrab( &vls );

    switch ( part->obj_type ) {
	case UNKNOWN_TYPE:
	    bu_log( "ERROR: Unknown object type for %s\n", part->obj_name );
	    break;
	case PART_TYPE:
	    if ( use_part_name_hash ) {
		DO_INDENT
		    bu_log( "part %s changed name to (%s)\n",
			    part->obj_name,
			    part->brlcad_comb );
	    } else {
		DO_INDENT
		    bu_log( "part %s\n", part->brlcad_comb );
	    }
	    break;
	case ASSEMBLY_TYPE:
	    if ( use_part_name_hash ) {
		DO_INDENT
		    bu_log( "assembly %s changed name to (%s)\n",
			    part->obj_name,
			    part->brlcad_comb );
	    } else {
		DO_INDENT
		    bu_log( "assembly %s\n", part->brlcad_comb );
	    }
	    break;
    }

    bu_free( tmp_name, "tmp_name" );
}
Ejemplo n.º 9
0
/*
 * F _ N I R T
 *
 * Invoke nirt with the current view & stuff
 */
int
dgo_nirt_cmd(struct dg_obj *dgop,
	     struct view_obj *vop,
	     int argc,
	     const char **argv)
{
    const char **vp;
    FILE *fp_in;
    FILE *fp_out, *fp_err;
#ifndef _WIN32
    int ret;
    size_t sret;
    int pid, rpid;
    int retcode;
    int pipe_in[2];
    int pipe_out[2];
    int pipe_err[2];
#else
    HANDLE pipe_in[2], pipe_inDup;
    HANDLE pipe_out[2], pipe_outDup;
    HANDLE pipe_err[2], pipe_errDup;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    char name[1024];
    char line1[2048];
    int rem = 2048;
#endif
    int use_input_orig = 0;
    vect_t center_model;
    vect_t dir;
    vect_t cml;
    int i;
    struct solid *sp;
    char line[RT_MAXLINE];
    char *val;
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    struct bu_vls o_vls = BU_VLS_INIT_ZERO;
    struct bu_vls p_vls = BU_VLS_INIT_ZERO;
    struct bu_vls t_vls = BU_VLS_INIT_ZERO;
    struct bn_vlblock *vbp;
    struct dg_qray_dataList *ndlp;
    struct dg_qray_dataList HeadQRayData;
    int args;

    args = argc + 20 + 2 + dgo_count_tops((struct solid *)&dgop->dgo_headSolid);
    dgop->dgo_rt_cmd = (char **)bu_calloc(args, sizeof(char *), "alloc dgo_rt_cmd");

    vp = (const char **)&dgop->dgo_rt_cmd[0];
    *vp++ = "nirt";

    /* swipe x, y, z off the end if present */
    if (argc > 3) {
	double scan[3];

	if (sscanf(argv[argc-3], "%lf", &scan[X]) == 1 &&
	    sscanf(argv[argc-2], "%lf", &scan[Y]) == 1 &&
	    sscanf(argv[argc-1], "%lf", &scan[Z]) == 1)
	{

	    VMOVE(center_model, scan);
	    use_input_orig = 1;
	    argc -= 3;
	    VSCALE(center_model, center_model, dgop->dgo_wdbp->dbip->dbi_local2base);
	}
    }

    /* Calculate point from which to fire ray */
    if (!use_input_orig) {
	VSET(center_model, -vop->vo_center[MDX],
	     -vop->vo_center[MDY], -vop->vo_center[MDZ]);
    }

    VSCALE(cml, center_model, dgop->dgo_wdbp->dbip->dbi_base2local);
    VMOVEN(dir, vop->vo_rotation + 8, 3);
    VSCALE(dir, dir, -1.0);

    bu_vls_printf(&p_vls, "xyz %lf %lf %lf;",
		  cml[X], cml[Y], cml[Z]);
    bu_vls_printf(&p_vls, "dir %lf %lf %lf; s",
		  dir[X], dir[Y], dir[Z]);

    i = 0;
    if (DG_QRAY_GRAPHICS(dgop)) {

	*vp++ = "-e";
	*vp++ = DG_QRAY_FORMAT_NULL;

	/* first ray ---- returns partitions */
	*vp++ = "-e";
	*vp++ = DG_QRAY_FORMAT_P;

	/* ray start, direction, and 's' command */
	*vp++ = "-e";
	*vp++ = bu_vls_addr(&p_vls);

	/* second ray ---- returns overlaps */
	*vp++ = "-e";
	*vp++ = DG_QRAY_FORMAT_O;

	/* ray start, direction, and 's' command */
	*vp++ = "-e";
	*vp++ = bu_vls_addr(&p_vls);

	if (DG_QRAY_TEXT(dgop)) {
	    char *cp;
	    int count = 0;

	    /* get 'r' format now; prepend its' format string with a newline */
	    val = bu_vls_addr(&dgop->dgo_qray_fmts[0].fmt);

	    /* find first '"' */
	    while (*val != '"' && *val != '\0')
		++val;

	    if (*val == '\0')
		goto done;
	    else
		++val;	    /* skip first '"' */

	    /* find last '"' */
	    cp = (char *)strrchr(val, '"');

	    if (cp != (char *)NULL) /* found it */
		count = cp - val;

	done:
	    if (*val == '\0')
		bu_vls_printf(&o_vls, " fmt r \"\\n\" ");
	    else {
		struct bu_vls tmp = BU_VLS_INIT_ZERO;
		bu_vls_strncpy(&tmp, val, count);
		bu_vls_printf(&o_vls, " fmt r \"\\n%V\" ", &tmp);
		bu_vls_free(&tmp);

		if (count)
		    val += count + 1;
		bu_vls_printf(&o_vls, "%s", val);
	    }

	    i = 1;

	    *vp++ = "-e";
	    *vp++ = bu_vls_addr(&o_vls);
	}
    }

    if (DG_QRAY_TEXT(dgop)) {

	/* load vp with formats for printing */
	for (; dgop->dgo_qray_fmts[i].type != (char)0; ++i)
	    bu_vls_printf(&t_vls, "fmt %c %s; ",
			  dgop->dgo_qray_fmts[i].type,
			  bu_vls_addr(&dgop->dgo_qray_fmts[i].fmt));

	*vp++ = "-e";
	*vp++ = bu_vls_addr(&t_vls);

	/* nirt does not like the trailing ';' */
	bu_vls_trunc(&t_vls, -2);
    }

    /* include nirt script string */
    if (bu_vls_strlen(&dgop->dgo_qray_script)) {
	*vp++ = "-e";
	*vp++ = bu_vls_addr(&dgop->dgo_qray_script);
    }

    *vp++ = "-e";
    *vp++ = bu_vls_addr(&p_vls);

    for (i = 1; i < argc; i++)
	*vp++ = argv[i];
    *vp++ = dgop->dgo_wdbp->dbip->dbi_filename;

    dgop->dgo_rt_cmd_len = (char **)vp - (char **)dgop->dgo_rt_cmd;

    /* Note - dgo_build_tops sets the last vp to (char *)0 */
    dgop->dgo_rt_cmd_len += dgo_build_tops((struct solid *)&dgop->dgo_headSolid,
					   vp,
					   (const char **)&dgop->dgo_rt_cmd[args]);

    if (dgop->dgo_qray_cmd_echo) {
	/* Print out the command we are about to run */
	vp = (const char **)&dgop->dgo_rt_cmd[0];
	while (*vp)
	    Tcl_AppendResult(dgop->interp, *vp++, " ", (char *)NULL);

	Tcl_AppendResult(dgop->interp, "\n", (char *)NULL);
    }

    if (use_input_orig) {
	bu_vls_printf(&vls, "\nFiring from (%lf, %lf, %lf)...\n",
		      center_model[X], center_model[Y], center_model[Z]);
	Tcl_AppendResult(dgop->interp, bu_vls_addr(&vls), (char *)NULL);
	bu_vls_free(&vls);
    } else
	Tcl_AppendResult(dgop->interp, "\nFiring from view center...\n", (char *)NULL);

#ifndef _WIN32
    ret = pipe(pipe_in);
    if (ret < 0)
	perror("pipe");
    ret = pipe(pipe_out);
    if (ret < 0)
	perror("pipe");
    ret = pipe(pipe_err);
    if (ret < 0)
	perror("pipe");
    (void)signal(SIGINT, SIG_IGN);
    if ((pid = fork()) == 0) {
	/* Redirect stdin, stdout, stderr */
	(void)close(0);
	ret = dup(pipe_in[0]);
	if (ret < 0)
	    perror("dup");
	(void)close(1);
	ret = dup(pipe_out[1]);
	if (ret < 0)
	    perror("dup");
	(void)close(2);
	ret = dup(pipe_err[1]);
	if (ret < 0)
	    perror("dup");

	/* close pipes */
	(void)close(pipe_in[0]);
	(void)close(pipe_in[1]);
	(void)close(pipe_out[0]);
	(void)close(pipe_out[1]);
	(void)close(pipe_err[0]);
	(void)close(pipe_err[1]);
	for (i = 3; i < 20; i++)
	    (void)close(i);
	(void)signal(SIGINT, SIG_DFL);
	(void)execvp(dgop->dgo_rt_cmd[0], dgop->dgo_rt_cmd);
	perror (dgop->dgo_rt_cmd[0]);
	exit(16);
    }

    /* use fp_in to feed view info to nirt */
    (void)close(pipe_in[0]);
    fp_in = fdopen(pipe_in[1], "w");

    /* use fp_out to read back the result */
    (void)close(pipe_out[1]);
    fp_out = fdopen(pipe_out[0], "r");

    /* use fp_err to read any error messages */
    (void)close(pipe_err[1]);
    fp_err = fdopen(pipe_err[0], "r");

    /* send quit command to nirt */
    sret = fwrite("q\n", 1, 2, fp_in);
    if (sret != 2)
	bu_log("fwrite failure\n");

    (void)fclose(fp_in);

#else
    memset((void *)&si, 0, sizeof(STARTUPINFO));
    memset((void *)&pi, 0, sizeof(PROCESS_INFORMATION));
    memset((void *)&sa, 0, sizeof(SECURITY_ATTRIBUTES));

    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    /* Create a pipe for the child process's STDOUT. */
    CreatePipe(&pipe_out[0], &pipe_out[1], &sa, 0);

    /* Create noninheritable read handle and close the inheritable read handle. */
    DuplicateHandle(GetCurrentProcess(), pipe_out[0],
		    GetCurrentProcess(),  &pipe_outDup ,
		    0,  FALSE,
		    DUPLICATE_SAME_ACCESS);
    CloseHandle(pipe_out[0]);

    /* Create a pipe for the child process's STDERR. */
    CreatePipe(&pipe_err[0], &pipe_err[1], &sa, 0);

    /* Create noninheritable read handle and close the inheritable read handle. */
    DuplicateHandle(GetCurrentProcess(), pipe_err[0],
		    GetCurrentProcess(),  &pipe_errDup ,
		    0,  FALSE,
		    DUPLICATE_SAME_ACCESS);
    CloseHandle(pipe_err[0]);

    /* The steps for redirecting child process's STDIN:
     *     1.  Save current STDIN, to be restored later.
     *     2.  Create anonymous pipe to be STDIN for child process.
     *     3.  Set STDIN of the parent to be the read handle to the
     *         pipe, so it is inherited by the child process.
     *     4.  Create a noninheritable duplicate of the write handle,
     *         and close the inheritable write handle.
     */

    /* Create a pipe for the child process's STDIN. */
    CreatePipe(&pipe_in[0], &pipe_in[1], &sa, 0);

    /* Duplicate the write handle to the pipe so it is not inherited. */
    DuplicateHandle(GetCurrentProcess(), pipe_in[1],
		    GetCurrentProcess(), &pipe_inDup,
		    0, FALSE,                  /* not inherited */
		    DUPLICATE_SAME_ACCESS);
    CloseHandle(pipe_in[1]);

    si.cb = sizeof(STARTUPINFO);
    si.lpReserved = NULL;
    si.lpReserved2 = NULL;
    si.cbReserved2 = 0;
    si.lpDesktop = NULL;
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.hStdInput   = pipe_in[0];
    si.hStdOutput  = pipe_out[1];
    si.hStdError   = pipe_err[1];
    si.wShowWindow = SW_HIDE;

    snprintf(line1, rem, "%s ", dgop->dgo_rt_cmd[0]);
    rem -= (int)strlen(line1) - 1;

    for (i = 1; i < dgop->dgo_rt_cmd_len; i++) {
	/* skip commands */
	if (strstr(dgop->dgo_rt_cmd[i], "-e") != NULL)
	    ++i;
	else {
	    /* append other arguments (i.e. options, file and obj(s)) */
	    snprintf(name, 1024, "\"%s\" ", dgop->dgo_rt_cmd[i]);
	    if (rem - strlen(name) < 1) {
		bu_log("Ran out of buffer space!");
		bu_free(dgop->dgo_rt_cmd, "free dgo_rt_cmd");
		dgop->dgo_rt_cmd = NULL;
		return TCL_ERROR;
	    }
	    bu_strlcat(line1, name, sizeof(line1));
	    rem -= (int)strlen(name);
	}
    }

    CreateProcess(NULL, line1, NULL, NULL, TRUE,
		  DETACHED_PROCESS, NULL, NULL,
		  &si, &pi);

    /* use fp_in to feed view info to nirt */
    CloseHandle(pipe_in[0]);
    fp_in = _fdopen(_open_osfhandle((intptr_t)pipe_inDup, _O_TEXT), "wb");
    setmode(fileno(fp_in), O_BINARY);

    /* send commands down the pipe */
    for (i = 1; i < dgop->dgo_rt_cmd_len-2; i++)
	if (strstr(dgop->dgo_rt_cmd[i], "-e") != NULL)
	    fprintf(fp_in, "%s\n", dgop->dgo_rt_cmd[++i]);

    /* use fp_out to read back the result */
    CloseHandle(pipe_out[1]);
    fp_out = _fdopen(_open_osfhandle((intptr_t)pipe_outDup, _O_TEXT), "rb");
    setmode(fileno(fp_out), O_BINARY);

    /* use fp_err to read any error messages */
    CloseHandle(pipe_err[1]);
    fp_err = _fdopen(_open_osfhandle((intptr_t)pipe_errDup, _O_TEXT), "rb");
    setmode(fileno(fp_err), O_BINARY);

    /* send quit command to nirt */
    fwrite("q\n", 1, 2, fp_in);
    (void)fclose(fp_in);

#endif

    bu_vls_free(&p_vls);   /* use to form "partition" part of nirt command above */
    if (DG_QRAY_GRAPHICS(dgop)) {
	double scan[4];

	if (DG_QRAY_TEXT(dgop))
	    bu_vls_free(&o_vls); /* used to form "overlap" part of nirt command above */

	BU_LIST_INIT(&HeadQRayData.l);

	/* handle partitions */
	while (bu_fgets(line, RT_MAXLINE, fp_out) != (char *)NULL) {
	    if (line[0] == '\n') {
		Tcl_AppendResult(dgop->interp, line+1, (char *)NULL);
		break;
	    }

	    BU_ALLOC(ndlp, struct dg_qray_dataList);
	    BU_LIST_APPEND(HeadQRayData.l.back, &ndlp->l);

	    if (sscanf(line, "%le %le %le %le",
		       &scan[0], &scan[1], &scan[2], &scan[3]) != 4)
		break;
	    ndlp->x_in = scan[0];
	    ndlp->y_in = scan[1];
	    ndlp->z_in = scan[2];
	    ndlp->los = scan[3];
	}

	vbp = rt_vlblock_init();
	dgo_qray_data_to_vlist(dgop, vbp, &HeadQRayData, dir, 0);
	bu_list_free(&HeadQRayData.l);
	dgo_cvt_vlblock_to_solids(dgop, vbp, bu_vls_addr(&dgop->dgo_qray_basename), 0);
	rt_vlblock_free(vbp);

	/* handle overlaps */
	while (bu_fgets(line, RT_MAXLINE, fp_out) != (char *)NULL) {
	    if (line[0] == '\n') {
		Tcl_AppendResult(dgop->interp, line+1, (char *)NULL);
		break;
	    }

	    BU_ALLOC(ndlp, struct dg_qray_dataList);
	    BU_LIST_APPEND(HeadQRayData.l.back, &ndlp->l);

	    if (sscanf(line, "%le %le %le %le",
		       &scan[0], &scan[1], &scan[2], &scan[3]) != 4)
		break;
	    ndlp->x_in = scan[0];
	    ndlp->y_in = scan[1];
	    ndlp->z_in = scan[2];
	    ndlp->los = scan[3];
	}
	vbp = rt_vlblock_init();
	dgo_qray_data_to_vlist(dgop, vbp, &HeadQRayData, dir, 1);
	bu_list_free(&HeadQRayData.l);
	dgo_cvt_vlblock_to_solids(dgop, vbp, bu_vls_addr(&dgop->dgo_qray_basename), 0);
	rt_vlblock_free(vbp);
    }

    /*
     * Notify observers, if any, before generating textual output since
     * such an act (observer notification) wipes out whatever gets stuffed
     * into the result.
     */
    dgo_notify(dgop);

    if (DG_QRAY_TEXT(dgop)) {
	bu_vls_free(&t_vls);

	while (bu_fgets(line, RT_MAXLINE, fp_out) != (char *)NULL)
	    Tcl_AppendResult(dgop->interp, line, (char *)NULL);
    }

    (void)fclose(fp_out);

    while (bu_fgets(line, RT_MAXLINE, fp_err) != (char *)NULL)
	Tcl_AppendResult(dgop->interp, line, (char *)NULL);
    (void)fclose(fp_err);


#ifndef _WIN32

    /* Wait for program to finish */
    while ((rpid = wait(&retcode)) != pid && rpid != -1)
	;	/* NULL */

    if (retcode != 0)
	pr_wait_status(dgop->interp, retcode);
#else
    /* Wait for program to finish */
    WaitForSingleObject(pi.hProcess, INFINITE);

#endif

    FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid)
	sp->s_wflag = DOWN;

    bu_free(dgop->dgo_rt_cmd, "free dgo_rt_cmd");
    dgop->dgo_rt_cmd = NULL;

    return TCL_OK;
}
void
gen_attr_xml_table(const char *fname, const char *xref_id)
{
    int i = 0;
    std::ofstream fo;
    fo.open(fname);
    if (fo.bad()) {
	fo.close();
	bu_exit(1, "gen-attributes-files: File '%s' open error.\n", fname);
    }

    // the table files will be included in a parent DocBook xml file
    // for man pages and will be child elements of a DB <para>

    std::string title("Standard (Core) Attributes List");

    fo <<
        "<article xmlns='http://docbook.org/ns/docbook' version='5.0'\n"
        "  xmlns:xi='http://www.w3.org/2001/XInclude'\n"
        ">\n"
	"<!-- auto-generated by program 'gen-attributes-files' (misc/attributes/gen-attributes-files.cpp.in) -->\n"

        "  <info><title>" << title << "</title></info>\n"

        "  <para xml:id='" << xref_id << "'>\n"
        ;

    fo <<
        "  <table><title>" << title << "</title>\n"
        "    <tgroup cols='6'>\n"
        "      <colspec colname='c1'/>\n"
        "      <colspec colname='c2'/>\n"
        "      <colspec colname='c3'/>\n"
        "      <colspec colname='c4'/>\n"
        "      <colspec colname='c5'/>\n"
        "      <colspec colname='c6'/>\n"
        "      <thead>\n"
        "        <row>\n"
        "          <entry>Property</entry>\n"
        "          <entry>Attribute</entry>\n"
        "          <entry>Is Binary</entry>\n"
        "          <entry>Definition</entry>\n"
        "          <entry>Example</entry>\n"
        "          <entry>Aliases</entry>\n"
        "        </row>\n"
        "      </thead>\n"
        "      <tbody>\n"
	;

    while (!BU_STR_EQUAL(db5_attr_std[i].name, "")) {
        fo <<
            "        <row>\n"
            "          <entry>" << db5_attr_std[i].property	<< "</entry>\n"
            "          <entry>" << db5_attr_std[i].name		<< "</entry>\n"
            "          <entry>" << db5_attr_std[i].is_binary	<< "</entry>\n"
            "          <entry>" << db5_attr_std[i].description	<< "</entry>\n"
            "          <entry>" << db5_attr_std[i].examples	<< "</entry>\n"
            "          <entry>"
	    ;

	{
	    struct bu_vls alias;
	    const char *curr_pos, *next_pos;
	    bu_vls_init(&alias);
	    curr_pos = db5_attr_std[i].aliases;
	    while (curr_pos && strlen(curr_pos) > 0) {
		next_pos = strchr(curr_pos+1, ',');
		if (next_pos) {
		    bu_vls_strncpy(&alias, curr_pos, next_pos - curr_pos);
		    fo << bu_vls_addr(&alias) << ", ";
		    curr_pos = next_pos + 1;
		} else {
		    bu_vls_strncpy(&alias, curr_pos, strlen(curr_pos));
		    fo << bu_vls_addr(&alias);
		    curr_pos = NULL;
		}
	    }
	    bu_vls_free(&alias);
	}
	 fo <<
	    "</entry>\n"
            "        </row>\n"
            ;

	i++;
    }

    fo <<
        "      </tbody>\n"
        "    </tgroup>\n"
        "  </table>\n"
        "  </para>\n"
        "</article>\n"
        ;

    fo.close();
}
struct directory *
db_diradd(struct db_i *dbip, const char *name, off_t laddr, size_t len, int flags, void *ptr)
{
    struct directory **headp;
    struct directory *dp;
    const char *tmp_ptr;
    struct bu_vls local = BU_VLS_INIT_ZERO;

    RT_CK_DBI(dbip);

    if (RT_G_DEBUG&DEBUG_DB) {
	bu_log("db_diradd(dbip=%p, name='%s', addr=%ld, len=%zu, flags=0x%x, ptr=%p)\n",
	       (void *)dbip, name, laddr, len, flags, ptr);
    }

    if ((tmp_ptr = strchr(name, '/')) != NULL) {
	/* if this is a version 4 database and the offending char is beyond NAMESIZE
	 * then it is not really a problem
	 */
	if (db_version(dbip) < 5 && (tmp_ptr - name) < NAMESIZE) {
	    bu_log("db_diradd() object named '%s' is illegal, ignored\n", name);
	    return RT_DIR_NULL;
	}
    }

    if (db_version(dbip) < 5) {
	bu_vls_strncpy(&local, name, NAMESIZE);
    } else {
	/* must provide a valid minor type */
	if (!ptr) {
	    bu_log("WARNING: db_diradd() called with a null minor type pointer for object %s\nIgnoring %s\n", name, name);
	    bu_vls_free(&local);
	    return RT_DIR_NULL;
	}
	bu_vls_strcpy(&local, name);
    }
    if (db_dircheck(dbip, &local, 0, &headp) < 0) {
	bu_vls_free(&local);
	return RT_DIR_NULL;
    }

    /* 'name' not found in directory, add it */
    RT_GET_DIRECTORY(dp, &rt_uniresource);
    RT_CK_DIR(dp);
    RT_DIR_SET_NAMEP(dp, bu_vls_addr(&local));	/* sets d_namep */
    dp->d_addr = laddr;
    dp->d_flags = flags & ~(RT_DIR_INMEM);
    dp->d_len = len;
    dp->d_forw = *headp;
    BU_LIST_INIT(&dp->d_use_hd);
    *headp = dp;
    dp->d_animate = NULL;
    dp->d_nref = 0;
    dp->d_uses = 0;

    /* v4 geometry databases do not use d_major/minor_type */
    if (db_version(dbip) > 4) {
	dp->d_major_type = DB5_MAJORTYPE_BRLCAD;
	if (ptr)
	    dp->d_minor_type = *(unsigned char *)ptr;
	else
	    dp->d_minor_type = 0;
    } else {
	dp->d_major_type = 0;
	dp->d_minor_type = 0;
    }

    bu_vls_free(&local);
    return dp;
}