7 ms·
Show HN: Greg – a simple “cal” clone written in C
- zamfofex 6y agoHello, everyone! Having known about this website for a while, this is my first time deciding to create an account and making a post. I have (somewhat) recently decided to start working on a simple C project. It is a “replacement” for the Unix utility ‘cal’. Of course, it is far from actually hoping to replace anything, it is more of a clone with some different functionalities than anything else. One of my friends mentioned that in his classes for his degree in computer science, he was assigned to fix a ‘cal’ clone the teacher had written in Java. Since I was always kinda interested by calendars and timekeeping, that sparked some interest in me. I decided to start the project because I felt like it would be fun to try to come up with something simple to display the calendar. I chose C because it is a (relatively) straightfoward language, and it is very popular, so basically anyone can understand it. Initially, the program was really short, but lacked a lot of functionalities. As the time went on, and I felt periodically bored enough to work on it, I decided to sacrifice some simplicity for more useful features. I feel like now it has gotten to the point in which it is “mature enough”, and could potentially be used by people who regularly use ‘cal’. Don’t mind the bugs too much. (But of course, feel free to bring them up!) One that I know exists and just haven’t gotten around fixing yet is the overflow handling for my function for parsing integers. I’m looking forward to know what people might think about it! Any kind of feedback is really appreciated, be it regarding functionality, code style, or anything else! P.S., You can try it through a Web interface through the first link on the website. Try e.g. ‘greg -yh’ for output very similar to ‘cal’.
- raldi 6y agoThe link could really use a quick description of why someone would want to install it (e.g., features cal doesn’t have) and a copy of the manual.
- zamfofex 6y agoI made it because I felt like it would be fun! There is not much reason to actually install it if you already have ‘cal’, unless for some reason you really want your weeks to start on e.g. Wednesday.
- JdeBP 6y agoYou haven't done a complete clone until you have included Latin, by the way. * https://unix.stackexchange.com/q/572653/5132 https://unix.stackexchange.com/q/572653/5132
- cogburnd02 6y agoThat is hilarious.
- xzlzx 6y agoAlthough this looks like it has a ways to go before being a viable replacement to cal, I give you props for putting yourself out there and gathering feedback. That's never an easy thing to do.
- DiabloD3 6y agoMy hands are physically unable to write "gre" and not finish with "p".
- parenthesis 6y agoPut your right hand behind your back first (in standard qwerty touch-typing, `greg' is an all-left-hand word).
- Skunkleton 6y agoEasier? $(rev <<<gerg)
- sgt 6y agocal is supposed to optionally take YYYY as the only parameter. When running greg 2020 I get the usage screen.
- zamfofex 6y ago‘greg’ is not able to display more than one month by itself. If you only provide one argument, it’ll consider it as a month number, e.g. ‘greg 9’ for September (of the current year). I had made a simple Bash script that displayed the calendar of a given month using ‘greg’ with ‘paste’, ‘columns’, and some other common utilities, but I haven’t uploaded it anywhere yet.
- zabzonk 6y agoAny reason for not using C Standard Library functions such as (for example) strlen and isdigit?
- zamfofex 6y agoNot really, to be honest! Originally, I had written a linker script that could generate really small ELF executables, using the information I found on this website: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html http://www.muppetlabs.com/~breadbox/software/tiny/teensy.htm... That meant I had to implement functions for myself, including ‘write’ in x86 assembly. As soon as I started storing function pointers, however, my program started to segfault, and I didn’t bother to figure out how to fix it. Do I stopped providing those builds on the website, and decided to start using other standard library functions, such as the time‐related functions. Since I already had those functionalities there, I decided to keep them anyway. It would make sense to reuse the library functions, though, I agree!
- raverbashing 6y agoAh yes the util I love to hate There's nothing easier than just typing cal on the terminal and getting the calendar. Cool But the one in Linux works in one way, the one in MacOS works in a different way and if you try to install gcal it's still different. And it also has these crazy usability issues. No, I don't want the calendar of year 11 thanks.
- raldi 6y agoBig upvote for that last point. I got into the habit of never looking up a specific month just because of getting repeatedly bitten by this hazard. If I want to see November I'll type `cal 2020` and eyeball the whole year.
- caymanjim 6y agoThis appears to be a very limited subset of Unix standard cal, without a single new feature, and missing some of the basic cal features (like 'cal 2020'). Writing something like this is a great way for someone to learn programming basics, but why is this on the HN front page? It's not particularly educational or interesting and has no practical utility for anyone.
- netmare 6y agoI love it. As an older Windows coder, it's one of the few things on HN I can fully grasp. There's no monads/shaders/ML/business involved--just plain old C. Almost everything else posted here makes me feel depressed and inadequate. Some people view abstraction as something they can happily ignore. They use libraries, upon frameworks, in VMs, on blockchains, just so that they can pile on. If all we do is add, there's no purpose. Absolutum obsoletum. Maybe it's some sort of existential crisis I'm going through, but I'm starting to ditch many advanced programs/services in favor of simple tools I can fully build and understand myself. YMMV, of course.
- xupybd 6y agoHave you looked into these tools? https://suckless.org/ https://suckless.org/
- easytiger 6y ago> Maybe it's some sort of existential crisis I'm going through, but I'm starting to ditch many advanced programs/services in favor of simple tools I can fully build and understand myself. YMMV, of course It isn't just you. A lot of my own energy wasted on tools and other things that don't really help you solve problems.
- cblum 6y agoI share the feeling. You're not alone :)
- miccah 6y ago> simple tools I can fully build and understand myself This reminds me of an excerpt from PoC||GTFO. "[W]hen you’re tooling around with a from-scratch tool and your neighbors tell you to use this or use that, look ’em in the eye and say, “I’m building my own fucking birdfeeder.”" [1] [1] https://q3k.org/birdfeeder.pdf https://q3k.org/birdfeeder.pdf
- bla3 6y agoNice! The time math in the source looks like stuff gmtime()/mktime() do internally -- maybe you could delete some code by using these and working with Unix timestamps.
- JdeBP 6y agoThe program that you likely know as "cal" is itself a clone, named "ncal" and written by Wolfgang Helbig in the 1990s. It was preceded by a clone written for BSD by Kim Letkeman in 1989, which was in turn a replacement for a "cal" written by Bill Joy. * https://svnweb.freebsd.org/csrg/usr.bin/cal/cal.c?view=log https://svnweb.freebsd.org/csrg/usr.bin/cal/cal.c?view=log * https://manpages.debian.org/buster/bsdmainutils/ncal.1.en.html https://manpages.debian.org/buster/bsdmainutils/ncal.1.en.ht...
- mwcremer 6y agoC.f. https://github.com/v7unix/v7unix/blob/master/v7/usr/src/cmd/cal.c https://github.com/v7unix/v7unix/blob/master/v7/usr/src/cmd/...
- mouldysammich 6y agoSemi unrelated, but I had never seen that webasembly site wapm, its pretty cool!
- petemc_ 6y agoNice, it even has the missing weeks in September 1752.. $ wapm install zamfofex/greg@2020.10.10 Package zamfofex/greg@2020.10.10 installed successfully! → Installed commands: greg $ cal 9 1752 September 1752 Su Mo Tu We Th Fr Sa 1 2 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
- zamfofex 6y agoWell, I wanted to mention that to use the program, you should type ‘greg’, not ‘cal’. But it does also skip those couple days in 1752 with the same arguments: ‘greg 9 1752’.
- petemc_ 6y agoWhoops! Should have had my coffee before commenting. Cheers.
- EdSchouten 6y agoI always find that behaviour somewhat arbitrary, as it was just the British empire that switched from the Julian to the Gregorian calendar that month. Most of mainland Europe already switched around 1582.
- tzs 6y agoCalendars can be fun. When I realized that my HP-48SX display had enough lines and was wide enough to display a one month calendar, I wrote one. My first try was annoyingly slow, and I determined that the problem was with the code to actually draw the calendar. Going through each day and telling it "draw this number here" was just not efficient enough. I switched to a string based approach. Here is what it would look like in Python. This draws a cal-style calendar or a month given the day of the week of the first day of the month (Sunday == 0, Monday == 1, ...) and the number of days in the month: def print_cal(first_day, num_days): hdr_str = "Su Mo Tu We Th Fr Sa " cal_str = " 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 " offset = 3*(6-first_day) cal_flat = cal_str[offset:18+3*num_days] cal_flat += " " print(hdr_str) print(cal_flat[0:21]) print(cal_flat[21:42]) print(cal_flat[42:63]) print(cal_flat[63:84]) print(cal_flat[84:105]) All the string operations were primitives in the calculator's slow interpreted language, implemented in fast assembly language, so this was very fast. Calculating the first day and number of days for a year/month was in the slow interpreted language, but that isn't much computation so it wasn't noticeable. In Python, it would be something like this: def first_and_length(year, month): # Correction for centuries 16, 17, 18, 19 # Repeats every 4 centuries. century_table = [2, 0, 5, 3] # Correction for each month for years that are not leap years. # For leap years, need to subtract 1 for January and February. month_table = [4, 0, 0, 3, 5, 1, 3, 6, 2, 4, 0, 2] month_length = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] num_days = month_length[month-1] first_day_on = 1 first_day_on += century_table[(year//100)%4] first_day_on += year%100 + (year%100)//4 first_day_on += month_table[month-1] if month <= 2 and year%4 == 0: if year%400 == 0 or year%100 != 0: first_day_on -= 1 if month == 2: num_days += 1 return first_day_on%7, num_days
- eggy 6y agoI have never used cal or Greg, but it reminds me of the J programming language's calendar function: calendar 2020 //for the full year in one row 3 4 $ calendar 2020 //full year in 4 row/3 column layout You can do all sorts of ranges and views too. Granted it doesn't show the missing days in September 1752 like one poster (petemc_21) replied in this thread, but I keep the J term open on my desktop for all sorts of calculator/programming goodies. Nothing geekier than an ASCII calendar at your fingertips in a full programming terminal!