Next: Translate Program, Previous: Dupword Program, Up: Miscellaneous Programs [Contents][Index]
Nothing cures insomnia like a ringing alarm clock.
Sleep is for web developers.
The following program is a simple “alarm clock” program. You give it a time of day and an optional message. At the specified time, it prints the message on the standard output. In addition, you can give it the number of times to repeat the message as well as a delay between repetitions.
This program uses the getlocaltime() function from
Getlocaltime Function.
All the work is done in the BEGIN rule. The first part is argument
checking and setting of defaults: the delay, the count, and the message to
print. If the user supplied a message without the ASCII BEL
character (known as the “alert” character, "\a"), then it is added to
the message. (On many systems, printing the ASCII BEL generates an
audible alert. Thus, when the alarm goes off, the system calls attention
to itself in case the user is not looking at the computer.)
Just for a change, this program uses a switch statement
(see Switch Statement), but the processing could be done with a series of
if-else statements instead.
Here is the program:
# alarm.awk --- set an alarm
#
# Requires getlocaltime() library function
# usage: alarm time [ "message" [ count [ delay ] ] ]
BEGIN {
# Initial argument sanity checking
usage1 = "usage: alarm time ['message' [count [delay]]]"
usage2 = sprintf("\t(%s) time ::= hh:mm", ARGV[1])
if (ARGC < 2) {
print usage1 > "/dev/stderr"
print usage2 > "/dev/stderr"
exit 1
}
switch (ARGC) {
case 5:
delay = ARGV[4] + 0
# fall through
case 4:
count = ARGV[3] + 0
# fall through
case 3:
message = ARGV[2]
break
default:
if (ARGV[1] !~ /[[:digit:]]?[[:digit:]]:[[:digit:]]{2}/) {
print usage1 > "/dev/stderr"
print usage2 > "/dev/stderr"
exit 1
}
break
}
# set defaults for once we reach the desired time
if (delay == 0)
delay = 180 # 3 minutes
if (count == 0)
count = 5
if (message == "")
message = sprintf("\aIt is now %s!\a", ARGV[1])
else if (index(message, "\a") == 0)
message = "\a" message "\a"
The next section of code turns the alarm time into hours and minutes, converts it (if necessary) to a 24-hour clock, and then turns that time into a count of the seconds since midnight. Next it turns the current time into a count of seconds since midnight. The difference between the two is how long to wait before setting off the alarm:
# split up alarm time
split(ARGV[1], atime, ":")
hour = atime[1] + 0 # force numeric
minute = atime[2] + 0 # force numeric
# get current broken down time
getlocaltime(now)
# if time given is 12-hour hours and it's after that
# hour, e.g., `alarm 5:30' at 9 a.m. means 5:30 p.m.,
# then add 12 to real hour
if (hour < 12 && now["hour"] > hour)
hour += 12
# set target time in seconds since midnight
target = (hour * 60 * 60) + (minute * 60)
# get current time in seconds since midnight
current = (now["hour"] * 60 * 60) + \
(now["minute"] * 60) + now["second"]
# how long to sleep for
naptime = target - current
if (naptime <= 0) {
print "alarm: time is in the past!" > "/dev/stderr"
exit 1
}
Finally, the program uses the system() function
(see I/O Functions)
to call the sleep utility. The sleep utility simply pauses
for the given number of seconds. If the exit status is not zero,
the program assumes that sleep was interrupted and exits. If
sleep exited with an OK status (zero), then the program prints the
message in a loop, again using sleep to delay for however many
seconds are necessary:
# zzzzzz..... go away if interrupted
if (system(sprintf("sleep %d", naptime)) != 0)
exit 1
# time to notify!
command = sprintf("sleep %d", delay)
for (i = 1; i <= count; i++) {
print message
# if sleep command interrupted, go away
if (system(command) != 0)
break
}
exit 0
}
Next: Translate Program, Previous: Dupword Program, Up: Miscellaneous Programs [Contents][Index]