parse_num.c revision 9e20cf223ad6e44536f7e3116413cc8a445618c7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * parse_num.c		- Parse the number of blocks
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2004,2005  Theodore Ts'o <tytso@mit.edu>
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %Begin-Header%
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This file may be redistributed under the terms of the GNU Library
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * General Public License, version 2.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %End-Header%
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "config.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "e2p.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned long long parse_num_blocks2(const char *arg, int log_block_size)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char *p;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned long long num;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	num = strtoull(arg, &p, 0);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (p[0] && p[1])
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 0;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (*p) {		/* Using fall-through logic */
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case 'T': case 't':
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)		num <<= 10;
30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)		/* fallthrough */
31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)	case 'G': case 'g':
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)		num <<= 10;
330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)		/* fallthrough */
340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)	case 'M': case 'm':
350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)		num <<= 10;
360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)		/* fallthrough */
370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)	case 'K': case 'k':
380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)		if (log_block_size < 0)
390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)			num <<= 10;
400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)		else
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)			num >>= log_block_size;
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)		break;
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)	case 's':
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)		if (log_block_size < 0)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			num <<= 9;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			num >>= (1+log_block_size);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case '\0':
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 0;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return num;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned long parse_num_blocks(const char *arg, int log_block_size)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return parse_num_blocks2(arg, log_block_size);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#ifdef DEBUG
630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include <unistd.h>
640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include <stdio.h>
650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)main(int argc, char **argv)
670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles){
680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)	unsigned long num;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int log_block_size = 0;
70
71	if (argc != 2 && argc != 3) {
72		fprintf(stderr, "Usage: %s arg [log_block_size]\n", argv[0]);
73		exit(1);
74	}
75
76	if (argc == 3) {
77		char *p;
78
79		log_block_size = strtol(argv[2], &p, 0);
80		if (*p) {
81			fprintf(stderr, "Bad log_block_size: %s\n", argv[2]);
82			exit(1);
83		}
84	}
85
86	num = parse_num_blocks(argv[1], log_block_size);
87
88	printf("Parsed number: %lu\n", num);
89	exit(0);
90}
91#endif
92