NiftyHost Forums (Archive)

Full Version: [C] Little Timer
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
(This program was posted on another forum, that should not be revealed here, too.)
This is a little timer program I wrote, a clone of sleep (in GNU coreutils) but it displays more information. It uses the same argument format as sleep. It's not really a script (but a program), but there's no more suitable places to post it.
It's untested under any environment other than my Gentoo. It uses a nonstandard sleep() function that may or may not exist in your C library. (It exists in glibc.) And a C99-compliant compiler is required.
For any results that it creates, I'm not liable. (For example, if you overcook your dinner because the timing does not work, you won't get a free lunch from me. )
Code:
// timer.c -- sleep clone with more information displayed
// Richard Grenville
// August 30th, 2010
// License: GPLv3 (or a newer version)
// Tested with gcc 4.4.4 under Gentoo amd64
// vim: ts=4
#include    <stdio.h>
#include    <stdlib.h>
#include    <limits.h>

const char *MSG[] = {
    [0] = "Usage: timer <waiting time (s/m/h/d) ...>\n"
};

inline void prttime(const long time, const long totaltime) {
    printf("%2ld:%2ld:%2ld (%4.1f%%) left.\n", time / 3600, time % 3600 / 60
            , time % 60, (double) time / totaltime * 100);
}

long argproc(const char *str);

int main(int argc, char *argv[]) {
    long time, totaltime = 0;
    long i;
    char **argptr, **argend;

    if(1 == argc) {
        fputs(MSG[0], stderr);
        return -1;
    }    
    for(argptr = argv + 1, argend = argv + argc
                ; argptr < argend; argptr++) {
        if((i = argproc(*argptr)) < 0) {
            if(-1 == i)
                fputs(MSG[0], stderr);
            return i;
        }
        totaltime += i;
    }
    time = totaltime;
    while(time-- > 0) {
        // printf("Time: %ld\n", time);
        if(sleep(1))
            return 1;
        prttime(time, totaltime);
    }

    return 0;
}

long argproc(const char *str) {
    char *endptr, **pendptr = &endptr;
    double convval;

    convval = strtod(str, pendptr);
    if('\0' == *endptr) {
        if(convval > LONG_MAX)
            return -2;
        return (long) convval;
    }
    if('\0' != *(endptr + 1))
        return -1;
    switch(*endptr) {
        case 's':    break;
        case 'm':    convval *= 60;
                    break;
        case 'h':    convval *= 3600;
                    break;
        case 'd':    convval *= 3600 * 24;
                    break;
    }
    if(convval > LONG_MAX)
        return -2;
    return (long) convval;
}
This program was originally written since "sleep" in coreutils does not display how much time are left. (Of course, the same feature can be implemented by a shell script, but that's just wasting CPU cycles.) Chances are most Windows users have no need to use them at all, but for *nix users, this is probably occasionally useful.
For the detailed argument format, do $ sleep --help.