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.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.
What are you working on?
Re: What are you working on?
- flatrute
- Posts: 335
- 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?
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:
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
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;
}
It turns out leaving an Internet identity behind is hard
My username is read as "flatorte".
[deleted] posts index
Avatar source
My username is read as "flatorte".
[deleted] posts index
Avatar source
Re: What are you working on?
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.
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
- ReleaseTheGeese
- Posts: 10
- Joined: Tue Jul 11, 2023 6:53 pm
Re: What are you working on?
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!
Github: https://github.com/lordfeck/rsru
Project homepage: http://soft.thran.uk/
Hopefully CPAN treats you nicely when setting it up!
Re: What are you working on?
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
https://github.com/Eclipse-Community/r3dfox
Kinda also need some help with it. (please help)
https://github.com/Eclipse-Community/r3dfox/issues/20
- Gordinator
- Posts: 24
- Joined: Wed Dec 28, 2022 2:04 pm
- Location: Peshtonshire, United Kingdom
- Contact:
Re: What are you working on?
I jump from project to project a lot, but rn I'm working on:
I do other stuff but that's just the more interesting ones.
I do other stuff but that's just the more interesting ones.
Signed, Gordinator.
Re: What are you working on?
Rn im working on installing Windows drivers on kubuntu
viewtopic.php?t=397
viewtopic.php?t=397