poe

Уређивач .po фајлова
git clone https://git.sr.ht/~strahinja/poe
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

strtonum.c (2072B)


      1 /* This program is licensed under the terms of GNU GPL v3 or (at your option)
      2  * any later version. Copyright (C) 2026  Страхиња Радић.
      3  * See the file LICENSE for exact copyright and license details. */
      4 
      5 #include <errno.h>
      6 #include <limits.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <string.h>
     10 
     11 #include "strtonum.h"
     12 
     13 /* Returns 0 on no error, otherwise returns 1 after outputting error message */
     14 int
     15 stn_handle_error(const char* str, const long long minval,
     16 	const long long maxval, const int errornum)
     17 {
     18 	switch (errornum)
     19 	{
     20 	case STN_NOTNUM:
     21 		fprintf(stderr, "strtonumber: Not a number: %s\n", str);
     22 		return 1;
     23 	case STN_INVLIMITS:
     24 		fprintf(stderr, "strtonumber: Invalid limit specification\n");
     25 		return 1;
     26 	case STN_UNDERFLOW:
     27 		fprintf(stderr, "strtonumber: Underflow: %s < %lld\n", str,
     28 			minval);
     29 		return 1;
     30 	case STN_OVERFLOW:
     31 		fprintf(stderr, "strtonumber: Overflow: %s > %lld\n", str,
     32 			maxval);
     33 		return 1;
     34 	default:;
     35 	}
     36 	return 0;
     37 }
     38 
     39 /* - Returns the converted number or 0 on error (*not* indicative of error; see
     40  *   below)
     41  * - Clears errno (discards any previous value) because of strtoll
     42  * - Instead, returns any errors in errornum (if non-NULL);
     43  *   *errornum == STN_NONE indicates success, any other value indicates error */
     44 long long
     45 strtonumber(const char* str, const long long minval, const long long maxval,
     46 	int* errornum)
     47 {
     48 	long long n;
     49 	char* end = NULL;
     50 
     51 	if (minval > maxval)
     52 	{
     53 		if (errornum)
     54 			*errornum = STN_INVLIMITS;
     55 		return 0;
     56 	}
     57 	errno = 0;
     58 	if (errornum)
     59 		*errornum = STN_NONE;
     60 	n = strtoll(str, &end, 10);
     61 	if (!*str || *end)
     62 	{
     63 		errno = 0;
     64 		if (errornum)
     65 			*errornum = STN_NOTNUM;
     66 		return 0;
     67 	}
     68 	else if (errno == ERANGE)
     69 	{
     70 		errno = 0;
     71 		if (errornum)
     72 			*errornum
     73 				= n == LLONG_MIN ? STN_UNDERFLOW : STN_OVERFLOW;
     74 		return 0;
     75 	}
     76 	else
     77 	{
     78 		errno = 0;
     79 		if (n > maxval)
     80 		{
     81 			if (errornum)
     82 				*errornum = STN_OVERFLOW;
     83 			return 0;
     84 		}
     85 		else if (n < minval)
     86 		{
     87 			if (errornum)
     88 				*errornum = STN_UNDERFLOW;
     89 			return 0;
     90 		}
     91 		else
     92 			return n;
     93 	}
     94 	/* Not reached */
     95 	return n;
     96 }