Example #1
0
int main(void)
{
        init_blocks();

        print_blocks();
        block_quick_sort(start, end+1, SORT_BY_ADDRESS);
        print_blocks();

        return 0;
}
Example #2
0
/* Traverse all block references of an i-node, and print out information about
   the data blocks and indirect blocks. Instead of printing to standard output,
   this appends the output to an array. truncate-test needs this so that it
   can compare the expected and actual output for the test. */
void print_inode_blocks(inode *ino, array *out)
{
  int lblock = 0;
  int i;
  for (i = 0; i < 12; i++)
    print_blocks(ino,ino->in.block[i],0,0,&lblock,out);
  print_blocks(ino,ino->in.block[12],1,0,&lblock,out);
  print_blocks(ino,ino->in.block[13],2,0,&lblock,out);
  print_blocks(ino,ino->in.block[14],3,0,&lblock,out);
}
Example #3
0
void *kmalloc(u32 size)
{
	int i;
	int j;
	struct header *fit = NULL;
	struct alloc_list *l;
	for_each_alloc_list_entry(l, j) {
		struct header *t = l->first;
		for_each_block(t, i) {
			if (t->used)
				continue;
			if (fit == NULL) {
				fit = t;
				continue;
			}
			if (t->size >= size && t->size < fit->size) {
				fit = t;
				continue;
			}
		}
	}
	if (fit == NULL) {
		add_block(GROW_BUFFER_SIZE);
		return kmalloc(size);
		return NULL;
	}
	/* Check if we can break the block down */
	int left = fit->size - size - sizeof(struct header) - sizeof(struct footer);
	if (left > 4)
		break_block(fit, size);
	fit->used = 1;
	print_blocks();
	return fit->mem;
}
Example #4
0
block* function_block(node* body, int print) {
	blockCount = 1;
	currentBlock = bb_newBlock(++functionCount, blockCount, currentBlock);
	block* tmp = currentBlock;
	stmt_list_parse(body);
	if(!currentBlock->bottom || currentBlock->bottom->op != O_RETURN) { //default return
		emit(O_RETURN, NULL, NULL, NULL);
	}
	if(print)
		print_blocks(tmp);
	return tmp;
}
Example #5
0
void kfree(void *ptr)
{
	struct header *header = (struct header *)((u32)ptr - sizeof(struct header));
	if (header->magic != MAGIC_CHECK) {
		printk ("Memory corruption!\n");
		return;
	}
	header->used = 0;
	if (header->next && header->next->used == 0)
		merge_next(header);
	if(header->prev && header->prev->used == 0)
		merge_prev(header);
	print_blocks();
}
Example #6
0
File: wuli.c Project: ZoneMo/backup
int main(int argc, const char *argv[])
{
    int fd;
    if (argc<2) {
        fprintf(stderr,"uage %d file",argv[0]);
        return -1;
    }
    fd = open(argv[1],O_RDONLY);
    if (fd<0) {
        perror("open");
        return 1;
    }
    print_blocks(fd);
    return 0;
}
Example #7
0
/* Helper function used by print_inode_blocks */
static void print_blocks(inode *ino, uint32_t blockno, int level, int indent,
                         int *lblock, array *out)
{
  if (0 == blockno)
    return;
  char str[256];
  str[0] = '\0';
  char *s = str;
  int i;
  for (i = 0; i < indent; i++)
    s += sprintf(s,"    ");
  switch (level) {
  case 0:
    s += sprintf(s,"Direct %d",blockno);
    break;
  case 1:
    s += sprintf(s,"Single indirect %d",blockno);
    break;
  case 2:
    s += sprintf(s,"Double indirect %d",blockno);
    break;
  case 3:
    s += sprintf(s,"Triple indirect %d",blockno);
    break;
  }
  if (level == 0) {
    array_printf(out,"%-40s %d\n",str,*lblock);
    (*lblock)++;
  }
  else {
    array_printf(out,"%s\n",str);
  }
  if (level > 0) {
    buffer *table;
    try(bufcache_get(ino->fs->bc,blockno,&table));
    for (i = 0; i < RPB; i++)
      print_blocks(ino,((uint32_t*)table->data)[i],level-1,indent+1,lblock,out);
  }
}
Example #8
0
int make_ext4fs_internal(int fd, const char *_directory,
						 fs_config_func_t fs_config_func, int gzip,
						 int sparse, int crc, int wipe,
						 int verbose, time_t fixed_time,
						 FILE* block_list_file)
{
	u32 root_inode_num;
	u16 root_mode;
	char *directory = NULL;

	if (setjmp(setjmp_env))
		return EXIT_FAILURE; /* Handle a call to longjmp() */

	if (_directory == NULL) {
		fprintf(stderr, "Need a source directory\n");
		return EXIT_FAILURE;
	}

	directory = canonicalize_rel_slashes(_directory);

	if (info.len <= 0)
		info.len = get_file_size(fd);

	if (info.len <= 0) {
		fprintf(stderr, "Need size of filesystem\n");
		return EXIT_FAILURE;
	}

	if (info.block_size <= 0)
		info.block_size = compute_block_size();

	/* Round down the filesystem length to be a multiple of the block size */
	info.len &= ~((u64)info.block_size - 1);

	if (info.journal_blocks == 0)
		info.journal_blocks = compute_journal_blocks();

	if (info.no_journal == 0)
		info.feat_compat = EXT4_FEATURE_COMPAT_HAS_JOURNAL;
	else
		info.journal_blocks = 0;

	if (info.blocks_per_group <= 0)
		info.blocks_per_group = compute_blocks_per_group();

	if (info.inodes <= 0)
		info.inodes = compute_inodes();

	if (info.inode_size <= 0)
		info.inode_size = 256;

	if (info.label == NULL)
		info.label = "";

	info.inodes_per_group = compute_inodes_per_group();

	info.feat_compat |=
			EXT4_FEATURE_COMPAT_RESIZE_INODE |
			EXT4_FEATURE_COMPAT_EXT_ATTR;

	info.feat_ro_compat |=
			EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER |
			EXT4_FEATURE_RO_COMPAT_LARGE_FILE |
			EXT4_FEATURE_RO_COMPAT_GDT_CSUM;

	info.feat_incompat |=
			EXT4_FEATURE_INCOMPAT_EXTENTS |
			EXT4_FEATURE_INCOMPAT_FILETYPE;


	info.bg_desc_reserve_blocks = compute_bg_desc_reserve_blocks();

	printf("Creating filesystem with parameters:\n");
	printf("    Size: %"PRIu64"\n", info.len);
	printf("    Block size: %d\n", info.block_size);
	printf("    Blocks per group: %d\n", info.blocks_per_group);
	printf("    Inodes per group: %d\n", info.inodes_per_group);
	printf("    Inode size: %d\n", info.inode_size);
	printf("    Journal blocks: %d\n", info.journal_blocks);
	printf("    Label: %s\n", info.label);

	ext4_create_fs_aux_info();

	printf("    Blocks: %"PRIu64"\n", aux_info.len_blocks);
	printf("    Block groups: %d\n", aux_info.groups);
	printf("    Reserved blocks: %"PRIu64"\n",  (aux_info.len_blocks / 100) * info.reserve_pcnt);
	printf("    Reserved block group size: %d\n", info.bg_desc_reserve_blocks);

	ext4_sparse_file = sparse_file_new(info.block_size, info.len);

	block_allocator_init();

	ext4_fill_in_sb();

	if (reserve_inodes(0, 10) == EXT4_ALLOCATE_FAILED)
		error("failed to reserve first 10 inodes");

	if (info.feat_compat & EXT4_FEATURE_COMPAT_HAS_JOURNAL)
		ext4_create_journal_inode();

	if (info.feat_compat & EXT4_FEATURE_COMPAT_RESIZE_INODE)
		ext4_create_resize_inode();

	root_inode_num = build_directory_structure(directory, "", 0,
		fs_config_func, verbose, fixed_time);

	root_mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
	inode_set_permissions(root_inode_num, root_mode, 0, 0, 0);

	ext4_update_free();

	ext4_queue_sb();

	if (block_list_file) {
		size_t dirlen = strlen(directory);
		struct block_allocation* p = get_saved_allocation_chain();
		while (p) {
			if (strncmp(p->filename, directory, dirlen) == 0) {
				fprintf(block_list_file, "%s", p->filename + dirlen);
			} else {
				fprintf(block_list_file, "%s", p->filename);
			}
			print_blocks(block_list_file, p);
			struct block_allocation* pn = p->next;
			free_alloc(p);
			p = pn;
		}
	}

	printf("Created filesystem with %d/%d inodes and %d/%d blocks\n",
			aux_info.sb->s_inodes_count - aux_info.sb->s_free_inodes_count,
			aux_info.sb->s_inodes_count,
			aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo,
			aux_info.sb->s_blocks_count_lo);

	if (wipe && WIPE_IS_SUPPORTED) {
		wipe_block_device(fd, info.len);
	}

	write_ext4_image(fd, gzip, sparse, crc);

	sparse_file_destroy(ext4_sparse_file);
	ext4_sparse_file = NULL;

	free(directory);

	return 0;
}
Example #9
0
File: print.c Project: 2ion/stmd
// Functions to pretty-print inline and node_block lists, for debugging.
// Prettyprint an inline list, for debugging.
static void print_blocks(node_block* b, int indent)
{
	struct ListData *data;

	while(b != NULL) {
		for (int i=0; i < indent; i++) {
			putchar(' ');
		}

		switch(b->tag) {
		case BLOCK_DOCUMENT:
			printf("document\n");
			print_blocks(b->children, indent + 2);
			break;
		case BLOCK_BQUOTE:
			printf("block_quote\n");
			print_blocks(b->children, indent + 2);
			break;
		case BLOCK_LIST_ITEM:
			printf("list_item\n");
			print_blocks(b->children, indent + 2);
			break;
		case BLOCK_LIST:
			data = &(b->as.list);
			if (data->list_type == ordered) {
				printf("list (type=ordered tight=%s start=%d delim=%s)\n",
						(data->tight ? "true" : "false"),
						data->start,
						(data->delimiter == parens ? "parens" : "period"));
			} else {
				printf("list (type=bullet tight=%s bullet_char=%c)\n",
						(data->tight ? "true" : "false"),
						data->bullet_char);
			}
			print_blocks(b->children, indent + 2);
			break;
		case BLOCK_ATX_HEADER:
			printf("atx_header (level=%d)\n", b->as.header.level);
			print_inlines(b->inline_content, indent + 2);
			break;
		case BLOCK_SETEXT_HEADER:
			printf("setext_header (level=%d)\n", b->as.header.level);
			print_inlines(b->inline_content, indent + 2);
			break;
		case BLOCK_PARAGRAPH:
			printf("paragraph\n");
			print_inlines(b->inline_content, indent + 2);
			break;
		case BLOCK_HRULE:
			printf("hrule\n");
			break;
		case BLOCK_INDENTED_CODE:
			printf("indented_code ");
			print_str(b->string_content.ptr, -1);
			putchar('\n');
			break;
		case BLOCK_FENCED_CODE:
			printf("fenced_code length=%d info=",
				b->as.code.fence_length);
			print_str(b->as.code.info.ptr, -1);
			putchar(' ');
			print_str(b->string_content.ptr, -1);
			putchar('\n');
			break;
		case BLOCK_HTML:
			printf("html_block ");
			print_str(b->string_content.ptr, -1);
			putchar('\n');
			break;
		case BLOCK_REFERENCE_DEF:
			printf("reference_def\n");
			break;
		default:
			printf("# NOT IMPLEMENTED (%d)\n", b->tag);
			break;
		}
		b = b->next;
	}
}
Example #10
0
File: print.c Project: 2ion/stmd
void stmd_debug_print(node_block *root)
{
	print_blocks(root, 0);
}
Example #11
0
int main(int argc, char **argv)
{

	int rc;
	char *dev_path;
	size_t block_size;
	char *endptr;
	aoff64_t block_offset = 0;
	aoff64_t block_count = 1;
	aoff64_t dev_nblocks;
	bool toc = false;
	
	if (argc < 2) {
		printf(NAME ": Error, argument missing.\n");
		syntax_print();
		return 1;
	}

	--argc; ++argv;

	if (str_cmp(*argv, "--toc") == 0) {
		--argc; ++argv;
		toc = true;
		goto devname;
	}

	if (str_cmp(*argv, "--relative") == 0) {
		--argc; ++argv;
		relative = true;
	}
	
	if (str_cmp(*argv, "--offset") == 0) {
		--argc; ++argv;
		if (*argv == NULL) {
			printf(NAME ": Error, argument missing (offset).\n");
			syntax_print();
			return 1;
		}

		block_offset = strtol(*argv, &endptr, 10);
		if (*endptr != '\0') {
			printf(NAME ": Error, invalid argument (offset).\n");
			syntax_print();
			return 1;
		}

		--argc; ++argv;
	}
	
	if (str_cmp(*argv, "--count") == 0) {
		--argc; ++argv;
		if (*argv == NULL) {
			printf(NAME ": Error, argument missing (count).\n");
			syntax_print();
			return 1;
		}

		block_count = strtol(*argv, &endptr, 10);
		if (*endptr != '\0') {
			printf(NAME ": Error, invalid argument (count).\n");
			syntax_print();
			return 1;
		}

		--argc; ++argv;
	}

devname:
	if (argc != 1) {
		printf(NAME ": Error, unexpected argument.\n");
		syntax_print();
		return 1;
	}

	dev_path = *argv;

	rc = loc_service_get_id(dev_path, &service_id, 0);
	if (rc != EOK) {
		printf(NAME ": Error resolving device `%s'.\n", dev_path);
		return 2;
	}

	rc = block_init(service_id, 2048);
	if (rc != EOK)  {
		printf(NAME ": Error initializing libblock.\n");
		return 2;
	}

	rc = block_get_bsize(service_id, &block_size);
	if (rc != EOK) {
		printf(NAME ": Error determining device block size.\n");
		return 2;
	}

	rc = block_get_nblocks(service_id, &dev_nblocks);
	if (rc != EOK) {
		printf(NAME ": Warning, failed to obtain block device size.\n");
	}

	printf("Device %s has %" PRIuOFF64 " blocks, %" PRIuOFF64 " bytes each\n", dev_path, dev_nblocks, (aoff64_t) block_size);

	if (toc)
		rc = print_toc();
	else
		rc = print_blocks(block_offset, block_count, block_size);

	block_fini(service_id);

	return rc;
}
Example #12
0
/*void print_block ( int fd, struct ext3_super_block *sb, __u32 block_num )
  {
  print_blocks ( fd, sb, block_num, 0, PLAIN_DATA );
  }
  */
void print_blocks ( int fd, struct ext3_super_block *sb,
    __u32 block_num, short rec_level, int mode ) {

  /*
     This function reads and print recursively the indexed blocks :

     a rec_level of 1 means to consider block_num as an index of blocks
     2                   block_num as an index of index of blocks
     and so on ...
     */

  unsigned int c = 0;
  char octet;
  __u32 iblock_num;
  off_t lret;
  size_t sret;

  if ( rec_level == 0 ) {

    DEBUG_PRINT("Reading block %u", block_num);

    lret = lseek( fd, ((off_t) block_num)*EXT3_BLOCK_SIZE(sb), SEEK_SET);

    if ( lret <= 0 ) {
      perror("ext3Viewer error - lseek block print_blocks");
      exit (-1);
    }

    if ( mode == HEXA_DATA ) {

      print_block_hexa_noline ( fd, sb, block_num );

    }
    else if ( mode == PLAIN_DATA ) {

      for ( c = 0 ; c < EXT3_BLOCK_SIZE(sb) ; c++ )
      {
        sret = read ( fd, &octet, sizeof(char) );
        if ( sret <= 0 ) {
          perror("ext3Viewer error - read octet print_blocks");
          exit (-1);
        }
        putchar(octet);
      }

    }

  }
  else {

    if ( block_num > 0 ) {
      DEBUG_PRINT("Reading block index %u", block_num);

      lret = lseek( fd, ((off_t) block_num)*EXT3_BLOCK_SIZE(sb), SEEK_SET);
      if ( lret <= 0 ) {
        perror("ext3Viewer error - lseek 2 print_blocks");
        exit (-1);
      }

      sret = read ( fd, &iblock_num, 4 ); /*we read the block number of the
                                            indexed block */
      if ( sret <= 0 ) {
        perror("ext3Viewer error - read 2 print_blocks");
        exit (-1);
      }

      while ( iblock_num != 0 && c < (EXT3_BLOCK_SIZE(sb)/4) )
      {
        // Go through the block table

        // For each block, display it or go through it if it's a table
        print_blocks ( fd, sb, iblock_num, rec_level-1, mode );

        c++;
        lret = lseek( fd, ((off_t) block_num)*EXT3_BLOCK_SIZE(sb)+(c*4),
            SEEK_SET);
        if ( lret <= 0 ) {
          perror("ext3Viewer error - lseek 3 print_blocks");
          exit (-1);
        }
        // Move 4 by 4 octets because it's the size of u_32 on which the block
        // number are stored
        sret = read ( fd, &iblock_num, 4 );
        if ( sret <= 0 ) {
          perror("ext3Viewer error - read 3 print_blocks");
          exit (-1);
        }

      }

    }

  }


}
int make_ext4fs_internal(int fd, const char *_directory, const char *_target_out_directory,
						 const char *_mountpoint, fs_config_func_t fs_config_func, int gzip,
						 int sparse, int crc, int wipe, int real_uuid,
						 struct selabel_handle *sehnd, int verbose, time_t fixed_time,
						 FILE* block_list_file)
{
	u32 root_inode_num;
	u16 root_mode;
	char *mountpoint;
	char *directory = NULL;
	char *target_out_directory = NULL;

	if (setjmp(setjmp_env))
		return EXIT_FAILURE; /* Handle a call to longjmp() */

	info.block_device = is_block_device_fd(fd);

	if (info.block_device && (sparse || gzip || crc)) {
		fprintf(stderr, "No sparse/gzip/crc allowed for block device\n");
		return EXIT_FAILURE;
	}

	if (_mountpoint == NULL) {
		mountpoint = strdup("");
	} else {
		mountpoint = canonicalize_abs_slashes(_mountpoint);
	}

	if (_directory) {
		directory = canonicalize_rel_slashes(_directory);
	}

	if (_target_out_directory) {
		target_out_directory = canonicalize_rel_slashes(_target_out_directory);
	}

	if (info.len <= 0)
		info.len = get_file_size(fd);

	if (info.len <= 0) {
		fprintf(stderr, "Need size of filesystem\n");
		return EXIT_FAILURE;
	}

	if (info.block_size <= 0)
		info.block_size = compute_block_size();

	/* Round down the filesystem length to be a multiple of the block size */
	info.len &= ~((u64)info.block_size - 1);

	if (info.journal_blocks == 0)
		info.journal_blocks = compute_journal_blocks();

	if (info.no_journal == 0)
		info.feat_compat = EXT4_FEATURE_COMPAT_HAS_JOURNAL;
	else
		info.journal_blocks = 0;

	if (info.blocks_per_group <= 0)
		info.blocks_per_group = compute_blocks_per_group();

	if (info.inodes <= 0)
		info.inodes = compute_inodes();

	if (info.inode_size <= 0)
		info.inode_size = 256;

	if (info.label == NULL)
		info.label = "";

	info.inodes_per_group = compute_inodes_per_group();

	info.feat_compat |=
			EXT4_FEATURE_COMPAT_RESIZE_INODE |
			EXT4_FEATURE_COMPAT_EXT_ATTR;

	info.feat_ro_compat |=
			EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER |
			EXT4_FEATURE_RO_COMPAT_LARGE_FILE |
			EXT4_FEATURE_RO_COMPAT_GDT_CSUM;

	info.feat_incompat |=
			EXT4_FEATURE_INCOMPAT_EXTENTS |
			EXT4_FEATURE_INCOMPAT_FILETYPE;


	info.bg_desc_reserve_blocks = compute_bg_desc_reserve_blocks();

	printf("Creating filesystem with parameters:\n");
	printf("    Size: %"PRIu64"\n", info.len);
	printf("    Block size: %d\n", info.block_size);
	printf("    Blocks per group: %d\n", info.blocks_per_group);
	printf("    Inodes per group: %d\n", info.inodes_per_group);
	printf("    Inode size: %d\n", info.inode_size);
	printf("    Journal blocks: %d\n", info.journal_blocks);
	printf("    Label: %s\n", info.label);

	ext4_create_fs_aux_info();

	printf("    Blocks: %"PRIu64"\n", aux_info.len_blocks);
	printf("    Block groups: %d\n", aux_info.groups);
	printf("    Reserved block group size: %d\n", info.bg_desc_reserve_blocks);

	ext4_sparse_file = sparse_file_new(info.block_size, info.len);

	block_allocator_init();

	ext4_fill_in_sb(real_uuid);

	if (reserve_inodes(0, 10) == EXT4_ALLOCATE_FAILED)
		error("failed to reserve first 10 inodes");

	if (info.feat_compat & EXT4_FEATURE_COMPAT_HAS_JOURNAL)
		ext4_create_journal_inode();

	if (info.feat_compat & EXT4_FEATURE_COMPAT_RESIZE_INODE)
		ext4_create_resize_inode();

#ifdef USE_MINGW
	// Windows needs only 'create an empty fs image' functionality
	assert(!directory);
	root_inode_num = build_default_directory_structure(mountpoint, sehnd);
#else
	if (directory)
		root_inode_num = build_directory_structure(directory, mountpoint, target_out_directory, 0,
			fs_config_func, sehnd, verbose, fixed_time);
	else
		root_inode_num = build_default_directory_structure(mountpoint, sehnd);
#endif

	root_mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
	inode_set_permissions(root_inode_num, root_mode, 0, 0, 0);

#ifndef USE_MINGW
	if (sehnd) {
		char *secontext = NULL;

		if (selabel_lookup(sehnd, &secontext, mountpoint, S_IFDIR) < 0) {
			error("cannot lookup security context for %s", mountpoint);
		}
		if (secontext) {
			if (verbose) {
				printf("Labeling %s as %s\n", mountpoint, secontext);
			}
			inode_set_selinux(root_inode_num, secontext);
		}
		freecon(secontext);
	}
#endif

	ext4_update_free();

	if (block_list_file) {
		size_t dirlen = directory ? strlen(directory) : 0;
		struct block_allocation* p = get_saved_allocation_chain();
		while (p) {
			if (directory && strncmp(p->filename, directory, dirlen) == 0) {
				// substitute mountpoint for the leading directory in the filename, in the output file
				fprintf(block_list_file, "%s%s", mountpoint, p->filename + dirlen);
			} else {
				fprintf(block_list_file, "%s", p->filename);
			}
			print_blocks(block_list_file, p);
			struct block_allocation* pn = p->next;
			free_alloc(p);
			p = pn;
		}
	}

	printf("Created filesystem with %d/%d inodes and %d/%d blocks\n",
			aux_info.sb->s_inodes_count - aux_info.sb->s_free_inodes_count,
			aux_info.sb->s_inodes_count,
			aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo,
			aux_info.sb->s_blocks_count_lo);

	if (wipe && WIPE_IS_SUPPORTED) {
		wipe_block_device(fd, info.len);
	}

	write_ext4_image(fd, gzip, sparse, crc);

	sparse_file_destroy(ext4_sparse_file);
	ext4_sparse_file = NULL;

	free(mountpoint);
	free(directory);

	return 0;
}
Example #14
0
int main(int argc, char *argv[]) {
  int i;
  bool ast = false;
  int g = 0;
  int numfps = 0;
  int files[argc];

  for (i=1; i < argc; i++) {
    if (strcmp(argv[i], "--version") == 0) {
      printf("stmd %s", VERSION);
      printf(" - standard markdown converter (c) 2014 John MacFarlane\n");
      exit(0);
    } else if ((strcmp(argv[i], "--help") == 0) ||
               (strcmp(argv[i], "-h") == 0)) {
      print_usage();
      exit(0);
    } else if (strcmp(argv[i], "--ast") == 0) {
      ast = true;
    } else if (*argv[i] == '-') {
      print_usage();
      exit(1);
    } else { // treat as file argument
      files[g] = i;
      g++;
    }
  }

  numfps = g;
  bstring s = NULL;
  bstring html;
  g = 0;
  block * cur = make_document();
  int linenum = 1;
  extern int errno;
  FILE * fp = NULL;

  if (numfps == 0) {
    // read from stdin
    while ((s = bgets((bNgetc) fgetc, stdin, '\n'))) {
      check(incorporate_line(s, linenum, &cur) == 0,
          "error incorporating line %d", linenum);
      bdestroy(s);
      linenum++;
    }
  } else {
    // iterate over input file pointers
    for (g=0; g < numfps; g++) {

      fp = fopen(argv[files[g]], "r");
      if (fp == NULL) {
        fprintf(stderr, "Error opening file %s: %s\n",
                argv[files[g]], strerror(errno));
        exit(1);
      }

      while ((s = bgets((bNgetc) fgetc, fp, '\n'))) {
        check(incorporate_line(s, linenum, &cur) == 0,
            "error incorporating line %d", linenum);
        bdestroy(s);
        linenum++;
      }
      fclose(fp);
    }
  }

  while (cur != cur->top) {
    finalize(cur, linenum);
    cur = cur->parent;
  }
  check(cur == cur->top, "problems finalizing open containers");
  finalize(cur, linenum);
  process_inlines(cur, cur->attributes.refmap);
  if (ast) {
    print_blocks(cur, 0);
  } else {
    check(blocks_to_html(cur, &html, false) == 0, "could not format as HTML");
    printf("%s", html->data);
    bdestroy(html);
  }
  free_blocks(cur);
  return 0;
error:
  return -1;
}