Beispiel #1
0
// Copy a line including the terminating \n and returns the length.
static int readline(char *dest, int destsize) {
  static char buffer[BUFSIZE];
  static int pos;
  if (pos < BUFSIZE/2) {
    int n_read = read(0, buffer + pos, BUFSIZE - pos);
    if ((n_read == 0) && (pos == 0)) {
      write(2, "End of file.\n", 13);
      return -1;
    }
    pos += n_read;
  }

  for(const char *p = buffer; p < buffer + pos; p++) {
    if (*p == '\n') {
      p++;
      int linelength = p-buffer;
      copybytes(dest, buffer, linelength);
      copybytes(buffer, p, BUFSIZE - linelength);
      pos -= linelength;
      return linelength;
    }
  }
  write(2, "Buffer capacity exceeded\n", 25);
  return -1;
}
Beispiel #2
0
static void glue_lst2(t_glue *x, t_symbol* UNUSED(s), int argc, t_atom *argv)
{
  x->changed = 1;
  if (x->n2 != argc) {
    freebytes(x->ap2, x->n2 * sizeof(t_atom));
    x->n2 = argc;
    x->ap2 = copybytes(argv, argc * sizeof(t_atom));
  } else memcpy(x->ap2, argv, argc * sizeof(t_atom));
}
Beispiel #3
0
static void join_anything(join_t * x, t_symbol * s, int argc, t_atom* largv)
{
	t_int* argv = getbytes(3*sizeof(t_int*));
	t_atom* copied_argv = copybytes(largv, argc * sizeof(t_atom));

	argv[0] = (t_int)x->x_outlet;
	argv[1] = (t_int)argc;
	argv[2] = (t_int)copied_argv;

	set_callback(join_anything_callback, argv, 3);
}
Beispiel #4
0
static void valve_map(t_valve *x, t_symbol *s, int n, t_atom *map)
{
  if (x->map) {
    freebytes(x->map, x->bufsize * sizeof(t_atom));
    x->map = 0;
    x->bufsize = 0;
  }

  x->map = copybytes(map, n * sizeof(t_atom));
  x->bufsize = n;
}
Beispiel #5
0
static void lpreson_tilde_list(t_lpreson_tilde *x, t_symbol *s, int argc, t_atom *argv)
{
  if (argc) 
  {
    //    x->x_ctl.parc_interp_two = copybytes(x->x_ctl.parc_interp_one, x->x_ctl.parc_ord_one * sizeof(t_atom));
    //    x->x_ctl.parc_ord_two = x->x_ctl.parc_ord_one;
    //    x->x_ctl.parc_interp_one = copybytes(x->x_ctl.parcors, x->x_order * sizeof(t_atom));
    //    x->x_ctl.parc_ord_one = x->x_order;
    freebytes(x->x_ctl.x_parcors, x->x_order * sizeof(t_atom));
  }

  x->x_ctl.x_parcors = copybytes(argv, argc * sizeof(t_atom));
  x->x_order = argc;
}
Beispiel #6
0
void mtx_bin_matrix2(t_mtx_binmtx *x, t_symbol *s, int argc, t_atom *argv)
{
  int row = atom_getfloat(argv);
  int col = atom_getfloat(argv+1);
  if (argc<2){post("mtx_bin2: crippled matrix"); return;}
  if ((col<1)||(row<1)) {post("mtx_bin2: invalid dimensions %dx%d", row,col); return;}
  if (col*row+2>argc){ post("mtx_bin2: sparse matrix not yet supported : use \"mtx_check\""); return;}

  if (row*col!=x->m2.row*x->m2.col) {
    freebytes(x->m2.atombuffer, (x->m2.row*x->m2.col+2)*sizeof(t_atom));
    x->m2.atombuffer=copybytes(argv,(row*col+2)*sizeof(t_atom));
  }else memcpy(x->m2.atombuffer, argv, (row*col+2)*sizeof(t_atom));
  setdimen(&x->m2, row, col);
}
Beispiel #7
0
static void list2int_any(t_mypdlist *x, t_symbol *s, int argc, t_atom *argv)
{
  t_atom *ap;
  if (x->x_n != argc) {
    freebytes(x->x_list, x->x_n * sizeof(t_atom));
    x->x_n = argc;
    x->x_list = copybytes(argv, argc * sizeof(t_atom));
  } else memcpy(x->x_list, argv, argc * sizeof(t_atom));
  ap = x->x_list;
  while(argc--){
    if(ap->a_type == A_FLOAT)ap->a_w.w_float=(int)ap->a_w.w_float;
    ap++;
  }
  outlet_anything(x->x_obj.ob_outlet, s, x->x_n, x->x_list);
}
Beispiel #8
0
/*--------------------------------------------------------------------
 * pd_deque_elt_new()
 *  + create a new deque element
 *  + arg 'sel' currently ignored
 */
static t_pd_deque_elt *pd_deque_elt_new(t_symbol *sel, int argc, t_atom *argv)
{
  t_pd_deque_elt *elt = (t_pd_deque_elt *)getbytes(sizeof(t_pd_deque_elt));

#ifdef DEQUE_DEBUG
  post("pd_deque_elt_new: got message with argc=%d", argc);
#endif

  //elt->sel  = sel;
  elt->argc = argc;
  if (argc>0) {
    elt->argv = (t_atom *)copybytes(argv, argc*sizeof(t_atom));
  } else {
    elt->argv = NULL;
  }
  return elt;
}
Beispiel #9
0
static t_int *xtract_perform_vector(t_int *w) {

    t_sample *in = (t_sample *)(w[1]);
    t_sample *out = (t_sample *)(w[2]);
    t_float *tmp_in, *tmp_out;
    t_xtract_tilde *x = (t_xtract_tilde *)(w[3]);
    t_int N = (t_int)(w[4]), n;
    t_int rv = 0;

    if(N != x->init_blocksize && x->done_init){
        error("xtract~ %s: Blocksize mismatch, try specifying the blocksize as a second argument", x->feature_name->s_name);
        return (w+5);
    }

    n = N;

    tmp_in = copybytes(in, N * sizeof(t_float));
    tmp_out = getbytes(N * sizeof(t_float));

    if(x->feature == XTRACT_PEAK_SPECTRUM || x->feature == XTRACT_LPC)
	N >>= 1;
    
    if(x->is_subframe){

        rv = xtract_features_from_subframes(tmp_in, N, x->feature, 
                x->argv, tmp_out);
    }
    else{

        rv = xtract[x->feature](tmp_in, N, x->argv, tmp_out);
    
    }

    if(rv == XTRACT_FEATURE_NOT_IMPLEMENTED)
	pd_error(x, "Feature not implemented");

    while(n--) 
        out[n] = tmp_out[n];
    
    freebytes(tmp_in, N * sizeof(t_float));
    freebytes(tmp_out, N * sizeof(t_float));
    
    return (w+5);
}
Beispiel #10
0
int main() {
  char selected[4096];
  char buffer[4096];
  int lineno = 0;
  int selsize = 0;
  RandGen g = randinit();
  for (;;) {
    int len = readline(buffer, 4096);
    if (len <= 0) break;
    lineno++;
    int64 rnd = randnext(&g);
    if(rnd % lineno == 0) {
      copybytes(selected, buffer, len);
      selsize = len;
    }
  }
  write(1, selected, selsize);
  return 0;
}
/* copy a resource from the input file to the output file */
static void copyres(osfildef *fpin, osfildef *fpout, ulong siz,
                    uint endpos_ofs)
{
    ulong startpos;
    ulong endpos;
    uchar buf[4];

    /* note the starting position */
    startpos = osfpos(fpout);

    /* copy the bytes of the resource */
    copybytes(fpin, fpout, siz);

    /* note the ending position */
    endpos = osfpos(fpout);

    /* write the ending position at the appropriate point */
    osfseek(fpout, (ulong)(startpos + endpos_ofs), OSFSK_SET);
    oswp4(buf, endpos);
    if (osfwb(fpout, buf, 4)) errexit("error writing resource", 1);

    /* seek back to the end of the output file */
    osfseek(fpout, endpos, OSFSK_SET);
}
Beispiel #12
0
/*
 * Main
 */
int main(int argc, char **argv)
{
    FILE *libfp, *tmpfp, *modfp = NULL;
    struct stat finfo;
    struct rdlm_hdr hdr;
    char buf[MAXMODNAMELEN], *p = NULL;
    char c;
    int i;

    progname = argv[0];
    _argv = argv;

    if (argc < 2) {
        usage();
        exit(1);
    }

    /* Check whether some modifiers were specified */
    for (i = 1; i < strlen(argv[1]); i++) {
        switch (c = argv[1][i]) {
        case 'c':
            options.createok = true;
            break;
        case 'f':
            options.usefname = true;
            break;
        case 'l':
            options.align = true;
            break;
        case 'o':
            options.odate = true;
            break;
        case 'u':
            options.fresh = true;
            break;
        case 'v':
            options.verbose++;
            break;
        case 'V':
            show_version();
            exit(0);
        default:
            if (strchr(commands, c) == NULL)
                error_exit(2, false, "invalid command or modifier '%c'",
                           c);
        }
    }

    if (argc < 3)
        error_exit(2, false, "missing library name");

    /* Process the command */
    if (argv[1][0] == '-')
        argv[1]++;
    switch (c = argv[1][0]) {
    case 'a':                  /* add a module */
        if (argc < 4 || (!options.usefname && argc != 5))
            error_exit(2, false, "invalid number of arguments");

        /* Check if a library already exists. If not - create it */
        if (access(argv[2], F_OK) < 0) {
            if (!options.createok)
                fprintf(stderr, "creating library %s\n", argv[2]);
            create_library(argv[2]);
        }

        libfp = fopen(argv[2], "ab");
        if (!libfp)
            error_exit(1, true, "could not open '%s'", argv[2]);

        if (!options.usefname)
            add_module(libfp, argv[4], argv[3]);
        else
            for (i = 3; i < argc; i++)
                add_module(libfp, argv[i], argv[i]);

        fclose(libfp);
        break;

    case 'n':                  /* create library */
        create_library(argv[2]);
        break;

    case 'x':                  /* extract module(s) */
        if (!options.usefname)
            argc--;
        if (argc < 4)
            error_exit(2, false, "required parameter missing");
        p = options.usefname ? argv[3] : argv[4];
    case 't':                  /* list library contents */
        libfp = fopen(argv[2], "rb");
        if (!libfp)
            error_exit(1, true, "could not open '%s'\n", argv[2]);

        /* Read library header */
        if (fread(&hdr, 1, sizeof(hdr), libfp) != sizeof(hdr) ||
            hdr.magic != RDLAMAG)
            error_exit(1, false, "invalid library format");

        /* Walk through the library looking for requested module */
        while (!feof(libfp)) {
            /* Read module header */
            i = fread(&hdr, 1, sizeof(hdr), libfp);
            if (feof(libfp))
                break;
            if (i != sizeof(hdr) || hdr.magic != RDLMMAG)
                error_exit(1, false, "invalid module header");
            /* Read module name */
            i = hdr.hdrsize - sizeof(hdr);
            if (i > sizeof(buf) || fread(buf, 1, i, libfp) != i)
                error_exit(1, false, "invalid module name");
            if (c == 'x') {
                /* Check against desired name */
                if (!strcmp(buf, argv[3])) {
                    if (options.verbose)
                        fprintf(stderr,
                                "extracting module %s to file %s\n", buf,
                                p);
                    modfp = fopen(p, "wb");
                    if (!modfp)
                        error_exit(1, true, "could not open '%s'", p);
                }
            } else {
                printf("%-40s ", buf);
                if (options.verbose) {
                    printf("%ld bytes", hdr.size);
                }
                putchar('\n');
            }

            copybytes(libfp, modfp, hdr.size);
            if (modfp)
                break;
        }

        fclose(libfp);
        if (modfp)
            fclose(modfp);
        else if (c == 'x')
            error_exit(1, false, "module '%s' not found in '%s'",
                       argv[3], argv[2]);
        break;

    case 'r':                  /* replace module(s) */
        argc--;
        if (stat(argv[4], &finfo) < 0)
            error_exit(1, true, "could not stat '%s'", argv[4]);
    case 'd':                  /* delete module(s) */
        if (argc < 4)
            error_exit(2, false, "required parameter missing");

        libfp = fopen(argv[2], "rb");
        if (!libfp)
            error_exit(1, true, "could not open '%s'", argv[2]);

        /* Copy the library into a temporary file */
        tmpfp = tmpfile();
        if (!tmpfp)
            error_exit(1, true, "could not open temporary file");

        stat(argv[2], &finfo);
        copybytes(libfp, tmpfp, finfo.st_size);
        rewind(tmpfp);
        freopen(argv[2], "wb", libfp);

        /* Read library header and write it to a new file */
        if (fread(&hdr, 1, sizeof(hdr), tmpfp) != sizeof(hdr) ||
            hdr.magic != RDLAMAG)
            error_exit(1, false, "invalid library format");
        put_header(&hdr, libfp, NULL);

        /* Walk through the library looking for requested module */
        while (!feof(tmpfp)) {
            /* Read module header */
            if (fread(&hdr, 1, sizeof(hdr), tmpfp) != sizeof(hdr) ||
                hdr.magic != RDLMMAG)
                error_exit(1, false, "invalid module header");
            /* Read module name */
            i = hdr.hdrsize - sizeof(hdr);
            if (i > sizeof(buf) || fread(buf, 1, i, tmpfp) != i)
                error_exit(1, false, "invalid module name");
            /* Check against desired name */
            if (!strcmp(buf, argv[3]) &&
                (c == 'd' || !options.odate
                 || finfo.st_mtime <= hdr.date)) {
                if (options.verbose)
                    fprintf(stderr, "deleting module %s\n", buf);
                fseek(tmpfp, hdr.size, SEEK_CUR);
                break;
            } else {
                put_header(&hdr, libfp, buf);
                copybytes(tmpfp, libfp, hdr.size);
            }
        }

        if (c == 'r') {
            /* Copy new module into library */
            p = options.usefname ? argv[4] : argv[3];
            add_module(libfp, argv[4], p);
        }

        /* Copy rest of library if any */
        while (!feof(tmpfp)) {
            if ((i = fgetc(tmpfp)) == EOF)
                break;

            if (fputc(i, libfp) == EOF)
                error_exit(1, false, "write error");
        }

        fclose(libfp);
        fclose(tmpfp);
        break;

    default:
        error_exit(2, false, "invalid command '%c'\n", c);
    }

    return 0;
}
Beispiel #13
0
int main(int argc, char **argv)
{
    FILE *fp, *fp2;
    char *p, buf[256];
    int i;

    _argv = argv;

    if (argc < 3 || !strncmp(argv[1],"-h",2) || !strncmp(argv[1],"--h",3))
    {
	printf(usage);
	exit(1);
    }

    switch(argv[1][0])
    {
    case 'c':		/* create library */
	fp = fopen(argv[2],"wb");
	if (! fp) {
	    fprintf(stderr,"ldrdf: could not open '%s'\n",argv[2]);
	    perror("ldrdf");
	    exit(1);
	}
	fclose(fp);
	break;

    case 'a':		/* add module */
	if (argc < 5) {
	    fprintf(stderr,"ldrdf: required parameter missing\n");
	    exit(1);
	}
	fp = fopen(argv[2],"ab");
	if (! fp)
	{
	    fprintf(stderr,"ldrdf: could not open '%s'\n",argv[2]);
	    perror("ldrdf");
	    exit(1);
	}
	
	fp2 = fopen(argv[3],"rb");
	if (! fp)
	{
	    fprintf(stderr,"ldrdf: could not open '%s'\n",argv[3]);
	    perror("ldrdf");
	    exit(1);
	}

	p = argv[4];
	do {
	    if ( fputc(*p,fp) == EOF ) {
		fprintf(stderr,"ldrdf: write error\n");
		exit(1);
	    }
	} while (*p++);

	while (! feof (fp2) ) {
	    i = fgetc (fp2);
	    if (i == EOF) {
		break;
	    }

	    if ( fputc(i, fp) == EOF ) {
		fprintf(stderr,"ldrdf: write error\n");
		exit(1);
	    }
	}
	fclose(fp2);
	fclose(fp);
	break;

    case 'x':
	if (argc < 5) {
	    fprintf(stderr,"ldrdf: required parameter missing\n");
	    exit(1);
	}

	fp = fopen(argv[2],"rb");
	if (! fp)
	{
	    fprintf(stderr,"ldrdf: could not open '%s'\n",argv[2]);
	    perror("ldrdf");
	    exit(1);
	}
	
	fp2 = NULL;
	while (! feof(fp) ) {
	    /* read name */
	    p = buf;
	    while( ( *(p++) = (char) fgetc(fp) ) )  
		if (feof(fp)) break;

	    if (feof(fp)) break;

	    /* check against desired name */
	    if (! strcmp(buf,argv[3]) )
	    {
		fp2 = fopen(argv[4],"wb");
		if (! fp2)
		{
		    fprintf(stderr,"ldrdf: could not open '%s'\n", argv[4]);
		    perror("ldrdf");
		    exit(1);
		}
	    }
	    else
		fp2 = NULL;

	    /* step over the RDOFF file, copying it if fp2 != NULL */
	    copybytes(fp,fp2,6);	/* magic number */
	    copybytes(fp,fp2, copylong(fp,fp2));	/* header */
	    copybytes(fp,fp2, copylong(fp,fp2));	/* text */
	    copybytes(fp,fp2, copylong(fp,fp2));	/* data */

	    if (fp2)
		break;
	}
	fclose(fp);
	if (fp2)
	    fclose(fp2);
	else
	{
	    fprintf(stderr,"ldrdf: module '%s' not found in '%s'\n",
		    argv[3],argv[2]);
	    exit(1);
	}
	break;

    default:
	fprintf(stderr,"ldrdf: command '%c' not recognised\n",
		argv[1][0]);
	exit(1);
    }
    return 0;
}
/*
 *   Process an HTML resource list.  If 'old_htmlres' is true, it
 *   indicates that the input file is pointing to an old resource map;
 *   otherwise, we need to construct a brand new one.  
 */
static opdef *prochtmlres(osfildef *fp, osfildef *fpout, opdef *oplist,
                          int *copyrsc, int *showed_heading, int old_htmlres)
{
    opdef *op;
    opdef *add_list = 0;
    opdef *prev_op;
    opdef *next_op;
    int    found;
    char   buf[512];
    ulong  in_entry_cnt;
    ulong  in_table_siz;
    ulong  out_hdr_siz;
    ulong  out_hdr_pos;
    ulong  i;
    ulong  out_res_cnt;
    ulong  out_total_name_len;
    ulong  rem;
    struct idx_t **in_list = 0, *out_list = 0, **p, *cur;
    ulong  in_res_base, out_res_base;
    ulong  out_endpos;

    /*
     *   Scan the oplist for an HTML resource.  If there aren't any, we
     *   don't need to modify the HTMLRES list, so tell the caller to copy
     *   this resource unchanged.  
     */
    for (op = oplist, found = FALSE ; op != 0 ; op = op->opnxt)
    {
        /* if this is an HTML resource, note it and stop looking */
        if (op->oprestype == RESTYPE_HTML)
        {
            found = TRUE;
            break;
        }
    }

    /* 
     *   If we didn't find any operations on this resource, and we're not
     *   simply listing resources or we don't have an old resource to
     *   list, tell the caller to copy it unchanged.  
     */
    if (!found && (fpout != 0 || !old_htmlres))
    {
        *copyrsc = TRUE;
        return oplist;
    }

    /* we'll be handling the resource - tell the caller not to copy it */
    *copyrsc = FALSE;

    /* if there's an old HTMLRES resource, read it */
    if (old_htmlres)
    {
        /* read the index entry count and size */
        if (osfrb(fp, buf, 8))
            listexit(fp, "unable to read HTMLRES header");
        in_entry_cnt = osrp4(buf);
        in_table_siz = osrp4(buf + 4);

        /* allocate space for pointers to all of the entries */
        if (in_entry_cnt != 0)
        {
            in_list = (struct idx_t **)
                      malloc(in_entry_cnt * sizeof(struct idx_t *));
            if (in_list == 0)
                listexit(fp, "unable to allocate space for HTMLRES entries");
        }

        /* read the index table entries */
        for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p)
        {
            ushort name_siz;
            ulong  res_siz;
            ulong  res_ofs;
            
            /* read the entry information */
            if (osfrb(fp, buf, 10))
                listexit(fp,
                         "unable to read HTMLRES index table entry (prefix)");
            
            /* get the resource size */
            res_ofs = osrp4(buf);
            res_siz = osrp4(buf + 4);
            
            /* read the name */
            name_siz = osrp2(buf + 8);
            if (name_siz > sizeof(buf))
                listexit(fp, "name too large in HTMLRES index table entry");
            if (osfrb(fp, buf, name_siz))
                listexit(fp,
                         "unable to read HTMLRES index table entry (name)");
            
            /* build this entry */
            *p = alloc_idx_entry(res_ofs, res_siz, buf, name_siz, 0, 0);
        }

        /* if we don't have an output file, list the HTMLRES contents */
        if (fpout == 0)
        {
            /* display all of the entries */
            for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p)
                show_list_item(showed_heading, "HTML",
                               (*p)->siz, (*p)->nam, (*p)->namlen);
            
            /* there's no more processing to do */
            goto done;
        }

        /*
         *   The resources start at the end of the index table - note the
         *   location of the end of the input table, since it's the base
         *   address relative to which the resource offsets are stated.  
         */
        in_res_base = osfpos(fp);

        /*
         *   Go through the resource table in the input file.  Find each
         *   one in the op list.  If it's not in the op list, we'll copy
         *   it to the output file.  
         */
        for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p)
        {
            int remove_res = FALSE;
            int add_res = FALSE;
            
            /* see if we can find this entry in the op list */
            for (prev_op = 0, op = oplist ; op != 0 ;
                 prev_op = op, op = op->opnxt)
            {
                /* if this one matches, note it */
                if (op->oprestype == RESTYPE_HTML
                    && strlen(op->opres) == (*p)->namlen
                    && !memicmp(op->opres, (*p)->nam, (*p)->namlen))
                {
                    /* 
                     *   if we're adding this resource (not replacing it),
                     *   warn that it's already in the file, and ignore
                     *   this op; if we're removing it or replacing it,
                     *   simply delete this entry from the input list so
                     *   it doesn't get copied to the output.  
                     */
                    if (!(op->opflag & OPFDEL))
                    {
                        /* warn that the old one will stay */
                        rscptf("warning: HTML resource \"%s\" already "
                               "present\n"
                               "  -- old version will be kept (use -replace "
                               "to replace it)\n", op->opres);
                        
                        /* remove it from the processing list */
                        remove_res = TRUE;
                    }
                    else
                    {
                        /* we are deleting it; see if we're also adding it */
                        if (op->opflag & OPFADD)
                        {
                            /* 
                             *   we're replacing this resource - take this
                             *   op out of the main list and put it into
                             *   the add list 
                             */
                            remove_res = TRUE;
                            add_res = TRUE;

                            /* note the addition */
                            show_op("replacing", op->opres, strlen(op->opres),
                                    op->oprestype);
                        }
                        else
                        {
                            /* note the deletion */
                            show_op("deleting", op->opres, strlen(op->opres),
                                    op->oprestype);

                            /* just remove it */
                            remove_res = TRUE;
                        }

                        /* get rid of this item from the input list */
                        free(*p);
                        *p = 0;
                    }
                    
                    /* no need to look further in the operations list */
                    break;
                }
            }
            
            /*
             *   If desired, remove this resource from the main list, and
             *   add it into the list of resources to add.  
             */
            if (remove_res)
            {
                /* unlink it from the main list */
                if (prev_op == 0)
                    oplist = op->opnxt;
                else
                    prev_op->opnxt = op->opnxt;
                
                /* if desired, add it to the additions list */
                if (add_res)
                {
                    /* we're adding it - put it in the additions list */
                    op->opnxt = add_list;
                    add_list = op;
                }
                else
                {
                    /* this item has been processed - delete it */
                    free(op);
                }
            }
        }
    }
    else
    {
        /* there are no entries in the input file */
        in_entry_cnt = 0;
        in_table_siz = 0;
    }

    /*
     *   Move all of the HTML resources marked as additions in the main
     *   operations list into the additions list. 
     */
    for (prev_op = 0, op = oplist ; op != 0 ; op = next_op)
    {
        /* note the next op, in case we move this one to the other list */
        next_op = op->opnxt;
        
        /* 
         *   if it's an HTML resource to be added, move it to the
         *   additions list 
         */
        if (op->oprestype == RESTYPE_HTML && (op->opflag & OPFADD) != 0)
        {
            /* show what we're doing */
            show_op("adding", op->opres, strlen(op->opres), op->oprestype);
            
            /* unlink it from the main list */
            if (prev_op == 0)
                oplist = op->opnxt;
            else
                prev_op->opnxt = op->opnxt;

            /* add it to the additions list */
            op->opnxt = add_list;
            add_list = op;

            /* 
             *   note that we don't want to advance the 'prev_op' pointer,
             *   since we just removed this item - the previous item is
             *   still the same as it was on the last iteration 
             */
        }
        else
        {
            /* 
             *   we're leaving this op in the original list - it's now the
             *   previous op in the main list 
             */
            prev_op = op;
        }
    }

    /*
     *   Figure out what we'll be putting in the HTMLRES list: we'll add
     *   each surviving entry from the input file, plus all of the items
     *   in the add list, plus all of the HTML items in the main list that
     *   are marked for addition.  
     */
    out_res_cnt = 0;
    out_total_name_len = 0;

    /* count input file entries that we're going to copy */
    for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p)
    {
        if (*p != 0)
            add_idx_entry(&out_list, &out_res_cnt, &out_total_name_len,
                          0, 0, (*p)->nam, (*p)->namlen, 0, *p);
    }

    /* 
     *   Count items in the additions list.  Note that every HTML resource
     *   marked for addition is in the additions list, since we moved all
     *   such resources out of the main list and into the additions list
     *   earlier.  
     */
    for (op = add_list ; op != 0 ; op = op->opnxt)
        add_idx_entry(&out_list, &out_res_cnt, &out_total_name_len,
                      0, 0, op->opres, (ushort)strlen(op->opres), op, 0);

    /* write the resource header */
    if (osfwb(fpout, "\007HTMLRES\0\0\0\0", 12))
        listexit(fp, "unable to write HTMLRES type header");
    out_hdr_pos = osfpos(fpout);

    /*
     *   Reserve space in the output file for the index table.  We need
     *   eight bytes for the index table prefix, then ten bytes per entry
     *   plus the name sizes. 
     */
    out_hdr_siz = 8 + (10 * out_res_cnt) + out_total_name_len;

    /* write the index table prefix */
    oswp4(buf, out_res_cnt);
    oswp4(buf + 4, out_hdr_siz);
    if (osfwb(fpout, buf, 8))
        listexit(fp, "unable to write HTMLRES prefix");

    /* 
     *   Reserve space for the headers.  Don't actually write them yet,
     *   since we don't know the actual locations and sizes of the
     *   entries; for now, simply reserve the space, so that we can come
     *   back here later and write the actual headers.  Note that we
     *   deduct the eight bytes we've already written from the amount of
     *   filler to put in.  
     */
    for (rem = out_hdr_siz - 8 ; rem != 0 ; )
    {
        ulong amt;
        
        /* write out a buffer full */
        amt = (rem > sizeof(buf) ? sizeof(buf) : rem);
        if (osfwb(fpout, buf, amt))
            listexit(fp, "unable to write HTMLRES header");

        /* deduct the amount we wrote from the remainder */
        rem -= amt;
    }

    /* 
     *   note the current position in the output file - this is the base
     *   address of the resources 
     */
    out_res_base = osfpos(fpout);

    /*
     *   Write the resources.  
     */
    for (cur = out_list ; cur != 0 ; cur = cur->nxt)
    {
        /* 
         *   note the current file position as an offset from the resource
         *   base in the output file - this is the offset that we need to
         *   store in the index entry for this object 
         */
        cur->ofs = osfpos(fpout) - out_res_base;
        
        /* 
         *   Copy the resource to the output.  If it comes from the input
         *   file, copy from there, otherwise go out and find the external
         *   file and copy its contents. 
         */
        if (cur->src_op != 0)
        {
            osfildef *fpext;
            ulong fsiz;
            
            /* it comes from an external file - open the file */
            fpext = osfoprb(cur->src_op->opfile, OSFTGAME);
            if (fpext == 0)
            {
                rscptf("%s: ", cur->src_op->opfile);
                errexit("unable to open file", 1);
            }

            /* figure the size of the file */
            osfseek(fpext, 0L, OSFSK_END);
            fsiz = osfpos(fpext);
            osfseek(fpext, 0L, OSFSK_SET);

            /* copy the contents of the external file to the output */
            copybytes(fpext, fpout, fsiz);

            /* the size is the same as the external file's size */
            cur->siz = fsiz;

            /* done with the file */
            osfcls(fpext);
        }
        else
        {
            /* 
             *   it comes from the input resource file - seek to the start
             *   of the resource in the input file, and copy the data to
             *   the output file 
             */
            osfseek(fp, in_res_base + cur->src_idx->ofs, OSFSK_SET);
            copybytes(fp, fpout, cur->src_idx->siz);

            /* the size is the same as in the input file */
            cur->siz = cur->src_idx->siz;
        }
    }

    /* note the current output position - this is the end of the resource */
    out_endpos = osfpos(fpout);

    /*
     *   Now that we've written all of the resources and know their actual
     *   layout in the file, we can go back and write the index table. 
     */
    osfseek(fpout, out_hdr_pos + 8, OSFSK_SET);
    for (cur = out_list ; cur != 0 ; cur = cur->nxt)
    {
        /* build this object's index table entry */
        oswp4(buf, cur->ofs);
        oswp4(buf + 4, cur->siz);
        oswp2(buf + 8, cur->namlen);

        /* write the entry */
        if (osfwb(fpout, buf, 10)
            || osfwb(fpout, cur->nam, cur->namlen))
            listexit(fp, "unable to write HTML index table entry");
    }

    /*
     *   We're done building the resource; now all we need to do is go
     *   back and write the ending position of the resource in the
     *   resource header.  
     */
    osfseek(fpout, out_hdr_pos - 4, OSFSK_SET);
    oswp4(buf, out_endpos);
    if (osfwb(fpout, buf, 4))
        errexit("error writing resource", 1);

    /* seek back to the end of the resource in the output file */
    osfseek(fpout, out_endpos, OSFSK_SET);

done:
    /* if we have an input list, free it */
    if (in_list != 0)
    {
        /* delete all of the entries in the input table */
        for (i = 0, p = in_list ; i < in_entry_cnt ; ++i, ++p)
        {
            /* delete this entry if we haven't already done so */
            if (*p != 0)
                free(*p);
        }

        /* delete the input pointer list itself */
        free(in_list);
    }

    /* 
     *   delete everything in the additions list, since we're done with
     *   them now 
     */
    for (op = add_list ; op != 0 ; op = next_op)
    {
        /* note the next entry in the list */
        next_op = op->opnxt;

        /* delete this entry */
        free(op);
    }

    /* return the op list in its current form */
    return oplist;
}
/* process an operation */
static void procop(osfildef *fpout, opdef *op, ulong *first_xfcn)
{
    osfildef *fpin;
    char      buf[128];
    uint      fsiz;
    ulong     sizpos;
    ulong     endpos;

    /* remember location of first resource if necessary */
    if (fpout && *first_xfcn == 0)
        *first_xfcn = osfpos(fpout);

    fpin = osfoprb(op->opfile, OSFTGAME);
    if (fpin == 0)
    {
        rscptf("%s: ", op->opfile);
        errexit("unable to open file", 1);
    }

    /* get file size */
    osfseek(fpin, 0L, OSFSK_END);
    fsiz = (uint)osfpos(fpin);
    osfseek(fpin, 0L, OSFSK_SET);

    /* set up the resource type part of the header */
    switch(op->oprestype)
    {
    case RESTYPE_XFCN:
        buf[0] = 4;
        memcpy(buf + 1, "XFCN", 4);
        break;

    case RESTYPE_HTML:
        buf[0] = 4;
        memcpy(buf + 1, "HTML", 3);
        break;
    }
    
    /* set up the rest of the header */
    if (osfwb(fpout, buf, buf[0] + 1)) errexit("error writing resource", 1);
    sizpos = osfpos(fpout);               /* remember where size field goes */
    oswp4(buf, 0);
    if (osfwb(fpout, buf, 4)) errexit("error writing resource", 1);
    
    /* set up the header */
    oswp2(buf, fsiz);
    buf[2] = strlen(op->opres);
    strcpy(buf + 3, op->opres);
    if (osfwb(fpout, buf, (uint)(buf[2] + 3)))
        errexit("error writing resource", 1);
    
    /* copy the resource to the output */
    copybytes(fpin, fpout, fsiz);

    /* write end position in the resource header */
    endpos = osfpos(fpout);
    oswp4(buf, endpos);
    osfseek(fpout, sizpos, OSFSK_SET);
    if (osfwb(fpout, buf, 4)) errexit("error writing resource", 1);

    /* seek back to the end of the resource in the output file */
    osfseek(fpout, endpos, OSFSK_SET);

    /* done with the input file */
    osfcls(fpin);
}