⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libdm-report.c

📁 Linux Device Mapper Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
	const char *we = format;	/* Word end */	while (*we) {		/* Allow consecutive commas */		while (*we && *we == ',')			we++;		/* start of the field name */		ws = we;		while (*we && *we != ',')			we++;		if (!_field_match(rh, ws, (size_t) (we - ws))) {			_display_fields(rh);			log_print(" ");			if (strcasecmp(ws, "help") && strcmp(ws, "?"))				log_error("Unrecognised field: %.*s",					  (int) (we - ws), ws);			return 0;		}	}	return 1;}static int _parse_keys(struct dm_report *rh, const char *keys){	const char *ws;		/* Word start */	const char *we = keys;	/* Word end */	while (*we) {		/* Allow consecutive commas */		while (*we && *we == ',')			we++;		ws = we;		while (*we && *we != ',')			we++;		if (!_key_match(rh, ws, (size_t) (we - ws))) {			log_error("dm_report: Unrecognised field: %.*s",				  (int) (we - ws), ws);			return 0;		}	}	return 1;}struct dm_report *dm_report_init(uint32_t *report_types,				 const struct dm_report_object_type *types,				 const struct dm_report_field_type *fields,				 const char *output_fields,				 const char *output_separator,				 uint32_t output_flags,				 const char *sort_keys,				 void *private){	struct dm_report *rh;	const struct dm_report_object_type *type;	if (!(rh = dm_malloc(sizeof(*rh)))) {		log_error("dm_report_init: dm_malloc failed");		return 0;	}	memset(rh, 0, sizeof(*rh));	/*	 * rh->report_types is updated in _parse_options() and _parse_keys()	 * to contain all types corresponding to the fields specified by	 * options or keys.	 */	if (report_types)		rh->report_types = *report_types;	rh->separator = output_separator;	rh->fields = fields;	rh->types = types;	rh->private = private;	rh->flags |= output_flags & DM_REPORT_OUTPUT_MASK;	if (output_flags & DM_REPORT_OUTPUT_BUFFERED)		rh->flags |= RH_SORT_REQUIRED;	list_init(&rh->field_props);	list_init(&rh->rows);	if ((type = _find_type(rh, rh->report_types)) && type->prefix)		rh->field_prefix = type->prefix;	else		rh->field_prefix = "";	if (!(rh->mem = dm_pool_create("report", 10 * 1024))) {		log_error("dm_report_init: allocation of memory pool failed");		dm_free(rh);		return NULL;	}	/* Generate list of fields for output based on format string & flags */	if (!_parse_options(rh, output_fields)) {		dm_report_free(rh);		return NULL;	}	if (!_parse_keys(rh, sort_keys)) {		dm_report_free(rh);		return NULL;	}	/* Return updated types value for further compatility check by caller */	if (report_types)		*report_types = rh->report_types;	return rh;}void dm_report_free(struct dm_report *rh){	dm_pool_destroy(rh->mem);	dm_free(rh);}/* * Create a row of data for an object */static void * _report_get_field_data(struct dm_report *rh,			      struct field_properties *fp, void *object){	void *ret = fp->type->data_fn(object);	if (!ret)		return NULL;	return ret + rh->fields[fp->field_num].offset;}int dm_report_object(struct dm_report *rh, void *object){	struct field_properties *fp;	struct row *row;	struct dm_report_field *field;	void *data = NULL;	if (!(row = dm_pool_zalloc(rh->mem, sizeof(*row)))) {		log_error("dm_report_object: struct row allocation failed");		return 0;	}	row->rh = rh;	if ((rh->flags & RH_SORT_REQUIRED) &&	    !(row->sort_fields =		dm_pool_zalloc(rh->mem, sizeof(struct dm_report_field *) *			       rh->keys_count))) {		log_error("dm_report_object: "			  "row sort value structure allocation failed");		return 0;	}	list_init(&row->fields);	list_add(&rh->rows, &row->list);	/* For each field to be displayed, call its report_fn */	list_iterate_items(fp, &rh->field_props) {		if (!(field = dm_pool_zalloc(rh->mem, sizeof(*field)))) {			log_error("dm_report_object: "				  "struct dm_report_field allocation failed");			return 0;		}		field->props = fp;		data = _report_get_field_data(rh, fp, object);		if (!data)			return 0;		if (!rh->fields[fp->field_num].report_fn(rh, rh->mem,							 field, data,							 rh->private)) {			log_error("dm_report_object: "				  "report function failed for field %s",				  rh->fields[fp->field_num].id);			return 0;		}		if ((strlen(field->report_string) > field->props->width))			field->props->width = strlen(field->report_string);		if ((rh->flags & RH_SORT_REQUIRED) &&		    (field->props->flags & FLD_SORT_KEY)) {			(*row->sort_fields)[field->props->sort_posn] = field;		}		list_add(&row->fields, &field->list);	}	if (!(rh->flags & DM_REPORT_OUTPUT_BUFFERED))		return dm_report_output(rh);	return 1;}/* * Print row of headings */static int _report_headings(struct dm_report *rh){	struct field_properties *fp;	const char *heading;	char buf[1024];	if (rh->flags & RH_HEADINGS_PRINTED)		return 1;	rh->flags |= RH_HEADINGS_PRINTED;	if (!(rh->flags & DM_REPORT_OUTPUT_HEADINGS))		return 1;	if (!dm_pool_begin_object(rh->mem, 128)) {		log_error("dm_report: "			  "dm_pool_begin_object failed for headings");		return 0;	}	/* First heading line */	list_iterate_items(fp, &rh->field_props) {		if (fp->flags & FLD_HIDDEN)			continue;		heading = rh->fields[fp->field_num].heading;		if (rh->flags & DM_REPORT_OUTPUT_ALIGNED) {			if (dm_snprintf(buf, sizeof(buf), "%-*.*s",					 fp->width, fp->width, heading) < 0) {				log_error("dm_report: snprintf heading failed");				goto bad;			}			if (!dm_pool_grow_object(rh->mem, buf, fp->width)) {				log_error("dm_report: Failed to generate report headings for printing");				goto bad;			}		} else if (!dm_pool_grow_object(rh->mem, heading,						strlen(heading))) {			log_error("dm_report: Failed to generate report headings for printing");			goto bad;		}		if (!list_end(&rh->field_props, &fp->list))			if (!dm_pool_grow_object(rh->mem, rh->separator,					      strlen(rh->separator))) {				log_error("dm_report: Failed to generate report headings for printing");				goto bad;			}	}	if (!dm_pool_grow_object(rh->mem, "\0", 1)) {		log_error("dm_report: Failed to generate report headings for printing");		goto bad;	}	log_print("%s", (char *) dm_pool_end_object(rh->mem));	return 1;      bad:	dm_pool_abandon_object(rh->mem);	return 0;}/* * Sort rows of data */static int _row_compare(const void *a, const void *b){	const struct row *rowa = *(const struct row **) a;	const struct row *rowb = *(const struct row **) b;	const struct dm_report_field *sfa, *sfb;	uint32_t cnt;	for (cnt = 0; cnt < rowa->rh->keys_count; cnt++) {		sfa = (*rowa->sort_fields)[cnt];		sfb = (*rowb->sort_fields)[cnt];		if (sfa->props->flags & DM_REPORT_FIELD_TYPE_NUMBER) {			const uint64_t numa =			    *(const uint64_t *) sfa->sort_value;			const uint64_t numb =			    *(const uint64_t *) sfb->sort_value;			if (numa == numb)				continue;			if (sfa->props->flags & FLD_ASCENDING) {				return (numa > numb) ? 1 : -1;			} else {	/* FLD_DESCENDING */				return (numa < numb) ? 1 : -1;			}		} else {	/* DM_REPORT_FIELD_TYPE_STRING */			const char *stra = (const char *) sfa->sort_value;			const char *strb = (const char *) sfb->sort_value;			int cmp = strcmp(stra, strb);			if (!cmp)				continue;			if (sfa->props->flags & FLD_ASCENDING) {				return (cmp > 0) ? 1 : -1;			} else {	/* FLD_DESCENDING */				return (cmp < 0) ? 1 : -1;			}		}	}	return 0;		/* Identical */}static int _sort_rows(struct dm_report *rh){	struct row *(*rows)[];	uint32_t count = 0;	struct row *row;	if (!(rows = dm_pool_alloc(rh->mem, sizeof(**rows) *				list_size(&rh->rows)))) {		log_error("dm_report: sort array allocation failed");		return 0;	}	list_iterate_items(row, &rh->rows)		(*rows)[count++] = row;	qsort(rows, count, sizeof(**rows), _row_compare);	list_init(&rh->rows);	while (count--)		list_add_h(&rh->rows, &(*rows)[count]->list);	return 1;}/* * Produce report output */int dm_report_output(struct dm_report *rh){	struct list *fh, *rowh, *ftmp, *rtmp;	struct row *row = NULL;	struct dm_report_field *field;	const char *repstr;	char buf[4096];	int32_t width;	uint32_t align;	if (list_empty(&rh->rows))		return 1;	/* Sort rows */	if ((rh->flags & RH_SORT_REQUIRED))		_sort_rows(rh);	/* If headings not printed yet, calculate field widths and print them */	if (!(rh->flags & RH_HEADINGS_PRINTED))		_report_headings(rh);	/* Print and clear buffer */	list_iterate_safe(rowh, rtmp, &rh->rows) {		if (!dm_pool_begin_object(rh->mem, 512)) {			log_error("dm_report: Unable to allocate output line");			return 0;		}		row = list_item(rowh, struct row);		list_iterate_safe(fh, ftmp, &row->fields) {			field = list_item(fh, struct dm_report_field);			if (field->props->flags & FLD_HIDDEN)				continue;			repstr = field->report_string;			width = field->props->width;			if (!(rh->flags & DM_REPORT_OUTPUT_ALIGNED)) {				if (!dm_pool_grow_object(rh->mem, repstr,						      strlen(repstr))) {					log_error("dm_report: Unable to extend output line");					goto bad;				}			} else {				if (!(align = field->props->flags & DM_REPORT_FIELD_ALIGN_MASK))					align = (field->props->flags & DM_REPORT_FIELD_TYPE_NUMBER) ? 						DM_REPORT_FIELD_ALIGN_RIGHT : DM_REPORT_FIELD_ALIGN_LEFT;				if (align & DM_REPORT_FIELD_ALIGN_LEFT) {					if (dm_snprintf(buf, sizeof(buf), "%-*.*s",							 width, width, repstr) < 0) {						log_error("dm_report: left-aligned snprintf() failed");						goto bad;					}					if (!dm_pool_grow_object(rh->mem, buf, width)) {						log_error("dm_report: Unable to extend output line");						goto bad;					}				} else if (align & DM_REPORT_FIELD_ALIGN_RIGHT) {					if (dm_snprintf(buf, sizeof(buf), "%*.*s",							 width, width, repstr) < 0) {						log_error("dm_report: right-aligned snprintf() failed");						goto bad;					}					if (!dm_pool_grow_object(rh->mem, buf, width)) {						log_error("dm_report: Unable to extend output line");						goto bad;					}				}			}			if (!list_end(&row->fields, fh))				if (!dm_pool_grow_object(rh->mem, rh->separator,						      strlen(rh->separator))) {					log_error("dm_report: Unable to extend output line");					goto bad;				}			list_del(&field->list);		}		if (!dm_pool_grow_object(rh->mem, "\0", 1)) {			log_error("dm_report: Unable to terminate output line");			goto bad;		}		log_print("%s", (char *) dm_pool_end_object(rh->mem));		list_del(&row->list);	}	if (row)		dm_pool_free(rh->mem, row);	return 1;      bad:	dm_pool_abandon_object(rh->mem);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -