seq.c (1865B)
- // Collection of Unix tools, comparable to coreutils
- // SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include <errno.h> // errno
- #include <stdbool.h> // bool, true, false
- #include <stdio.h> // puts, fprintf
- #include <stdlib.h> // atoi, exit
- #include <unistd.h> // getopt, optarg, optind
- char *separator = "\n";
- bool zero_pad = false;
- void
- seq(long i, long step, long last)
- {
- if(i == last)
- {
- printf("%li%s", i, separator);
- }
- else if(i < last)
- {
- for(; i <= last; i += step)
- printf("%li%s", i, separator);
- }
- else if(i > last)
- {
- for(; i >= last; i -= step)
- printf("%li%s", i, separator);
- }
- }
- static long unsigned int
- safe_labs(long int a)
- {
- if(a >= 0)
- {
- return (long unsigned int)a;
- }
- else
- {
- return (long unsigned int)-a;
- }
- }
- long
- get_num(char *str)
- {
- errno = 0;
- long num = strtol(str, NULL, 10);
- if(errno != 0)
- {
- perror("seq: strtol:");
- exit(1);
- }
- return num;
- }
- void
- usage(void)
- {
- fprintf(stderr, "usage: seq [-w] [-s separator] [first [step]] last\n");
- }
- int
- main(int argc, char *argv[])
- {
- int c;
- /* flawfinder: ignore. Old implementations of getopt should fix themselves */
- while((c = getopt(argc, argv, ":ws:")) != -1)
- {
- switch(c)
- {
- case 'w':
- zero_pad = true;
- break;
- case 's':
- separator = optarg;
- break;
- case '?':
- usage();
- return 1;
- }
- }
- argc -= optind;
- argv += optind;
- long first = 1;
- long step = 1;
- long last = 1;
- switch(argc)
- {
- case 1:
- last = get_num(argv[0]);
- break;
- case 2:
- first = get_num(argv[0]);
- last = get_num(argv[1]);
- break;
- case 3:
- first = get_num(argv[0]);
- step = (long)safe_labs(get_num(argv[1]));
- last = get_num(argv[2]);
- break;
- default:
- usage();
- return 1;
- }
- seq(first, step, last);
- return 0;
- }