What are you working on?

Any discussion of software that doesn't fit into any category goes here.
User avatar
Wam
Posts: 26
Joined: Thu Dec 08, 2022 12:55 pm

Re: What are you working on?

Post by Wam »

maxmoon wrote: Fri Jan 27, 2023 2:43 pm I can't follow this comparison, because the thread owner mentioned something about understanding the engine and because she wrote about C# and Windows, I just thought she is limited to Microsofts World. And if the limitation is gone, it can be an eye opener, because Windows can often just hinder your work.
Not everything has to become "Windows vs. Linux", I use Linux in a bunch of places, servers primarily, but also on my PowerMacs. This particular project targets Windows Phone yes, but also creates binaries that run flawlessly on macOS and Linux alike. C# is a very portable language in this sense.
User avatar
flatrute
Posts: 307
Joined: Sat Dec 17, 2022 11:32 am
Location: Thành phố Hồ Chí Minh, Việt Nam
Contact:

Re: What are you working on?

Post by flatrute »

This semester I attended to Object Oriented Programming class for mandatory credits and during my first week I had to solve a problem as a warmup:

Code: Select all

#if __STDC__ != 1
#error Please use standard compliance compiler.
#endif

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Employee {
	struct EmployeeBasic {
		char name[32];
		struct EmployeeBasicBirthday {
			unsigned short year;
			unsigned short month;
			unsigned short day;
		} birth;
	} basic;
	enum EmployeeRole { UNKNOWN, OFFICE, PRODUCTION } role;
	union EmployeeDetail {
		struct {
			unsigned short count_workday;
		} office;
		struct {
			unsigned short wage_basic;
			unsigned short count_product;
		} production;
	} detail;
};

static int employee_birthday_sort(void const * a, void const * b);
static void employee_input(size_t * count, struct Employee ** e);
static void employee_output_list(size_t count, struct Employee * e);
static void employee_output_wage_total(size_t count, struct Employee * e);
static void employee_output_birthday_closest(size_t count, struct Employee * e);

int
main(void)
{
	size_t count;
	struct Employee * list;
	
	employee_input(&count, &list);
	qsort(list, count, sizeof(*list), employee_birthday_sort);
	employee_output_list(count, list);
	employee_output_wage_total(count, list);
	employee_output_birthday_closest(count, list);
	
	return EXIT_SUCCESS;
}

static int
employee_birthday_sort(void const * a, void const * b)
{
	struct EmployeeBasicBirthday m = ((struct Employee *)a)->basic.birth;
	struct EmployeeBasicBirthday n = ((struct Employee *)b)->basic.birth;
	unsigned long x = m.year * 10000 + m.month * 100 + m.day;
	unsigned long y = n.year * 10000 + n.month * 100 + n.day;

	if (x < y) {
		return -1;
	}
	if (x > y) {
		return 1;
	}
	return 0;
}

enum Status { GOOD, BAD };
typedef enum Status (*Callback)(size_t sz, char * bff, void * ud);
static void buffer_scan(size_t sz, char * bff, char const * msg, Callback fn, void * ud);

static enum Status employee_get_count(size_t sz, char * bff, void * ud);
static enum Status employee_get_name(size_t sz, char * bff, void * ud);
static enum Status employee_get_birth_year(size_t sz, char * bff, void * ud);
static enum Status employee_get_birth_month(size_t sz, char * bff, void * ud);
static enum Status employee_get_birth_day(size_t sz, char * bff, void * ud);
static enum Status employee_get_role(size_t sz, char * bff, void * ud);
static enum Status employee_get_detail(size_t sz, char * bff, void * ud);

static void
employee_input(size_t * count, struct Employee ** e)
{
	char buffer[32];
	size_t i;
	
	*count = 0;
	buffer_scan(sizeof(buffer), buffer,
		"Number of employees? ",
		employee_get_count, count
	);
	*e = calloc(*count, sizeof(**e));
	if (*e == NULL) {
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < *count; i = i + 1) {
		fprintf(stdout, "Employee #%u :\n", (unsigned)i + 1);
		buffer_scan(sizeof((*e + i)->basic.name), (*e + i)->basic.name,
			"Name? ",
			employee_get_name, NULL
		);
		buffer_scan(sizeof(buffer), buffer,
			"Birth year? ",
			employee_get_birth_year, &(*e + i)->basic.birth.year
		);
		buffer_scan(sizeof(buffer), buffer,
			"Birth month? ",
			employee_get_birth_month, &(*e + i)->basic.birth.month
		);
		buffer_scan(sizeof(buffer), buffer,
			"Birth day? ",
			employee_get_birth_day, &(*e + i)->basic.birth.day
		);
		buffer_scan(sizeof(buffer), buffer,
			"[O]ffice/[P]roduction? ",
			employee_get_role, &(*e + i)->role
		);
		switch ((*e + i)->role) {
		case OFFICE:
			buffer_scan(sizeof(buffer), buffer,
				"Work days? ",
				employee_get_detail,
				&(*e + i)->detail.office.count_workday
			);
			break;
		case PRODUCTION:
			buffer_scan(sizeof(buffer), buffer,
				"Basic wage? ",
				employee_get_detail,
				&(*e + i)->detail.production.wage_basic
			);
			buffer_scan(sizeof(buffer), buffer,
				"Number of products? ",
				employee_get_detail,
				&(*e + i)->detail.production.count_product
			);
			break;
		default:
			exit(EXIT_FAILURE);
		}
	}
}

static void
output_space(size_t count)
{
	size_t i;
	
	for (i = 0; i < count; i = i + 1) {
		fputc(' ', stdout);
	}
}

#define FIELD_WIDTH_MAX(x) CHAR_BIT * (int)sizeof(x) / 3

static void
employee_output_list_basic(struct EmployeeBasic b)
{
	/*
	 * Due to buffer_scan() only accepts string ending in "\n\0"
	 * instead of the normal '\0' there is no points reading
	 * the last characters.
	 */
	fprintf(stdout, "%*s %04hu-%02hu-%02hu",
		(int)sizeof(b.name) - 2, b.name,	
		b.birth.year,
		b.birth.month,
		b.birth.day
	);
}

static void
employee_output_list(size_t count, struct Employee * e)
{
	size_t i;
	
	for (i = 0; i < count; i = i + 1) {
		employee_output_list_basic(e[i].basic);
		fputs(" ", stdout);
		switch (e[i].role) {
		case OFFICE:
			fprintf(stdout, "OFFICE     %*hu",
				FIELD_WIDTH_MAX(e[i].detail.office.count_workday),
				e[i].detail.office.count_workday
			);
			break;
		case PRODUCTION:
			fputs("PRODUCTION ", stdout);
			output_space(FIELD_WIDTH_MAX(e[i].detail.office.count_workday));
			fprintf(stdout, " %*hu %*hu",
				FIELD_WIDTH_MAX(e[i].detail.production.count_product),
				e[i].detail.production.count_product,
				FIELD_WIDTH_MAX(e[i].detail.production.wage_basic),
				e[i].detail.production.wage_basic
			);
			break;
		default:
			exit(EXIT_FAILURE);
		}
		fputs("\n", stdout);
	}
}

static void
employee_output_wage_total(size_t count, struct Employee * e)
{
	size_t i;
	unsigned long total = 0;
	
	for (i = 0; i < count; i = i + 1) {
		switch (e[i].role) {
		case OFFICE:
			total = total + e[i].detail.office.count_workday * 100000;
			break;
		case PRODUCTION:
			total = total + e[i].detail.production.wage_basic + e[i].detail.production.count_product * 5000;
			break;
		default:
			exit(EXIT_FAILURE);
		}
	}
	fprintf(stdout, "Total wage: %*lu\n", FIELD_WIDTH_MAX(total), total);
}

static void
employee_output_birthday_closest(size_t count, struct Employee * e)
{
	int d = INT_MAX;
	int * a = calloc(count, sizeof(*a));
	size_t i;

	if (a == NULL) {
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < count; i = i + 1) {
		a[i] = abs(e[i].basic.birth.month * 100 + e[i].basic.birth.day - 225); /* YYYY-02-25 */
		if (a[i] < d) { 
			d = a[i];
		}
	}
	fputs("Employee(s) with their birthday closest to February 25th:\n", stdout);
	for (i = 0; i < count; i = i + 1) {
		if (a[i] == d) {
			employee_output_list_basic(e[i].basic);
			fputc('\n', stdout);
		}
	}
	free(a);
}

#undef FIELD_WIDTH_MAX

static void
buffer_scan(size_t sz, char * bff, char const * msg, Callback fn, void * ud)
{
	/* Is goto-less without sacrifing the flow possible? */
	do_scan:
	if (msg != NULL) {
		fputs(msg, stdout);
	}
	fgets(bff, sz, stdin);
	if (strchr(bff, '\n') == NULL) {
		while (getchar() != '\n');
		goto do_scan;
	}
	if (fn != NULL) {
		if (fn(sz, bff, ud) != GOOD) {
			goto do_scan;
		}
	}
}
	
static enum Status
employee_get_count(size_t sz, char * bff, void * ud)
{
	unsigned * c = (unsigned *)ud;
	
	sscanf(bff, "%u", c);
	if (*c <= 0) {
		return BAD;
	} else {
		return GOOD;
	}
}

static enum Status
employee_get_name(size_t sz, char * bff, void * ud)
{
	bff[strcspn(bff, "\n")] = '\0';
	return GOOD;
}

static enum Status
employee_get_birth_year(size_t sz, char * bff, void * ud)
{
	unsigned short * y = (unsigned short *)ud;
	
	sscanf(bff, "%hu", y);
	if (*y <= 9999) {
		return GOOD;
	} else {
		return BAD;
	}
}

static enum Status
employee_get_birth_month (size_t sz, char * bff, void * ud)
{
	unsigned short * m = (unsigned short *)ud;
	
	sscanf(bff, "%hu", m);
	if (*m >= 1 && *m <= 12) {
		return GOOD;
	} else {
		return BAD;
	}
}

static enum Status
employee_get_birth_day (size_t sz, char * bff, void * ud)
{
	unsigned short * d = (unsigned short *)ud;
	
	sscanf(bff, "%hu", d);
	if (*d >= 1 && *d <= 31) {
		return GOOD;
	} else {
		return BAD;
	}
}

static enum Status
employee_get_role(size_t sz, char * bff, void * ud)
{
	size_t i;
	enum EmployeeRole * r = (enum EmployeeRole *)ud;
	
	for (i = 0; i < sz; i = i + 1) {
		switch (bff[i]) {
		case 'O':
		case 'o':
			*r = OFFICE;
			return GOOD;
		case 'P':
		case 'p':
			*r = PRODUCTION;
			return GOOD;
		default:
			*r = UNKNOWN;
			return BAD;
		}
	}
	return BAD;
}

static enum Status
employee_get_detail(size_t sz, char * bff, void * ud)
{
	sscanf(bff, "%hu", (unsigned short *)ud);
	return GOOD;
}
I know there are a lot of things to improve but suffice to say it has been the greatest week I have ever had since I last touched ANSI C programming SAWNIC
It turns out leaving an Internet identity behind is hard MikeBruh

My username is read as "flatorte".

[deleted] posts index

Avatar source
User avatar
catsanddo
Posts: 2
Joined: Tue Dec 27, 2022 9:50 pm

Re: What are you working on?

Post by catsanddo »

I got super interested in forth recently. I just love how simple and low level it can be.

I really wanted to dig in deep with it and learn how it works and how to write a forth myself. I'd highly recommend taking a look at sectorforth if anyone else is interested in forth. It's a minimal forth which fits into a boot sector and only has 8 main words. If you can read assembly it gives a pretty good idea of how to implement a basic forth interpreter. And reading through the examples gives good insight into how a lot of other words actually function because they are all built step by step using just those few primitives.

Currently I'm actually working on a user space port of it (as best as I can manage). It's not quite done yet, but maybe I'll try posting it here when I finish.
Low level programming is the best kind of programming
User avatar
ReleaseTheGeese
Posts: 10
Joined: Tue Jul 11, 2023 6:53 pm

Re: What are you working on?

Post by ReleaseTheGeese »

Not currently working on this, but the most complete thing I've had a hand in is RSRU, a static website builder written in Perl. It has four templates created by yours truly, and can generate gallery/blog style sites. I use it to build Well Made Web, a gallery of notable and high-effort indieweb/ancient websites.

Github: https://github.com/lordfeck/rsru

Project homepage: http://soft.thran.uk/

Hopefully CPAN treats you nicely when setting it up!
there shall be no peace when they release the geese
my website | software by me | well made web
User avatar
K4sum1
Posts: 3
Joined: Mon Dec 04, 2023 11:28 am

Re: What are you working on?

Post by K4sum1 »

Mostly just my fork of Firefox for Windows 7.

https://github.com/Eclipse-Community/r3dfox

Kinda also need some help with it. (please help)

https://github.com/Eclipse-Community/r3dfox/issues/20
Post Reply