Пример #1
0
static int
addunit(struct unittype * theunit, const char *toadd, int flip)
{
	char *scratch, *savescr;
	char *item;
	char *divider, *slash;
	int doingtop;

	savescr = scratch = dupstr(toadd);
	for (slash = scratch + 1; *slash; slash++)
		if (*slash == '-' &&
		    (tolower((unsigned char)*(slash - 1)) != 'e' ||
		    !strchr(".0123456789", *(slash + 1))))
			*slash = ' ';
	slash = strchr(scratch, '/');
	if (slash)
		*slash = 0;
	doingtop = 1;
	do {
		item = strtok(scratch, " *\t\n/");
		while (item) {
			if (strchr("0123456789.", *item)) {
				/* item starts with a number */
				char *endptr;
				double num;

				divider = strchr(item, '|');
				if (divider) {
					*divider = 0;
					num = strtod(item, &endptr);
					if (!num) {
						zeroerror();
						return 1;
					}
					if (endptr != divider) {
						/* "6foo|2" is an error */
						mywarnx("Junk before '|'");
						return 1;
					}
					if (doingtop ^ flip)
						theunit->factor *= num;
					else
						theunit->factor /= num;
					num = strtod(divider + 1, &endptr);
					if (!num) {
						zeroerror();
						return 1;
					}
					if (doingtop ^ flip)
						theunit->factor /= num;
					else
						theunit->factor *= num;
					if (*endptr) {
						/* "6|2foo" is like "6|2 foo" */
						item = endptr;
						continue;
					}
				}
				else {
					num = strtod(item, &endptr);
					if (!num) {
						zeroerror();
						return 1;
					}
					if (doingtop ^ flip)
						theunit->factor *= num;
					else
						theunit->factor /= num;
					if (*endptr) {
						/* "3foo" is like "3 foo" */
						item = endptr;
						continue;
					}
				}
			}
			else {	/* item is not a number */
				int repeat = 1;

				if (strchr("23456789",
				    item[strlen(item) - 1])) {
					repeat = item[strlen(item) - 1] - '0';
					item[strlen(item) - 1] = 0;
				}
				for (; repeat; repeat--)
					if (addsubunit(doingtop ^ flip ? theunit->numerator : theunit->denominator, item))
						return 1;
			}
			item = strtok(NULL, " *\t/\n");
		}
		doingtop--;
		if (slash) {
			scratch = slash + 1;
		}
		else
			doingtop--;
	} while (doingtop >= 0);
	free(savescr);
	return 0;
}
Пример #2
0
int 
addunit(struct unittype * theunit, char *toadd, int flip, int quantity)
{
	char *scratch, *savescr;
	char *item;
	char *divider, *slash, *offset;
	int doingtop;

	if (!strlen(toadd))
		return 1;
	
	savescr = scratch = dupstr(toadd);
	for (slash = scratch + 1; *slash; slash++)
		if (*slash == '-' &&
		    (tolower(*(slash - 1)) != 'e' ||
		    !strchr(".0123456789", *(slash + 1))))
			*slash = ' ';
	slash = strchr(scratch, '/');
	if (slash)
		*slash = 0;
	doingtop = 1;
	do {
		item = strtok(scratch, " *\t\n/");
		while (item) {
			if (strchr("0123456789.", *item)) { /* item is a number */
				double num, offsetnum;

				if (quantity)
					theunit->quantity = 1;

				offset = strchr(item, '&');
				if (offset) {
					*offset = 0;
					offsetnum = atof(offset+1);
				} else
					offsetnum = 0.0;

				divider = strchr(item, '|');
				if (divider) {
					*divider = 0;
					num = atof(item);
					if (!num) {
						zeroerror();
						return 1;
					}
					if (doingtop ^ flip) {
						theunit->factor *= num;
						theunit->offset *= num;
					} else {
						theunit->factor /= num;
						theunit->offset /= num;
					}
					num = atof(divider + 1);
					if (!num) {
						zeroerror();
						return 1;
					}
					if (doingtop ^ flip) {
						theunit->factor /= num;
						theunit->offset /= num;
					} else {
						theunit->factor *= num;
						theunit->offset *= num;
					}
				}
				else {
					num = atof(item);
					if (!num) {
						zeroerror();
						return 1;
					}
					if (doingtop ^ flip) {
						theunit->factor *= num;
						theunit->offset *= num;
					} else {
						theunit->factor /= num;
						theunit->offset /= num;
					}
				}
				if (doingtop ^ flip)
					theunit->offset += offsetnum;
			}
			else {	/* item is not a number */
				int repeat = 1;

				if (strchr("23456789",
				    item[strlen(item) - 1])) {
					repeat = item[strlen(item) - 1] - '0';
					item[strlen(item) - 1] = 0;
				}
				for (; repeat; repeat--)
					if (addsubunit(doingtop ^ flip ? theunit->numerator : theunit->denominator, item))
						return 1;
			}
			item = strtok(NULL, " *\t/\n");
		}
		doingtop--;
		if (slash) {
			scratch = slash + 1;
		}
		else
			doingtop--;
	} while (doingtop >= 0);
	free(savescr);
	return 0;
}