/* depend: */
/* cflags: */
-/* linker: */
+/* linker: atoi.o fdprintf.o */
-#include <assert.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
+#include <stddef.h>
+
+#include "atoi.h"
+#include "fdprintf.h"
/* macros */
#define VERBOSE(level, statement...) do { if (level <= verbose) { statement; } } while(0)
+#define VERSION "0.9"
/* gobal variables */
/* help function */
-void usage (int ret)
+int usage (int ret)
{
- FILE *fd = ret ? stderr : stdout;
- fprintf (fd, "usage: %s\n", progname);
- fprintf (fd, " -c : number of columns (%d)\n", nbcols);
- fprintf (fd, " -h : help message\n");
- fprintf (fd, " -v : verbose level (%d)\n", verbose);
+ int fd = ret ? _fd_stderr : _fd_stdout;
+ fdprintf (fd, "usage: %s\n", progname);
+ fdprintf (fd, " -c : number of columns (%d)\n", nbcols);
+ fdprintf (fd, " -h : help message\n");
+ fdprintf (fd, " -v : show version\n");
- exit (ret);
+ return ret;
}
/* main function */
int main (int argc, char *argv[])
{
- int i;
+ int i = 0;
progname = argv[0];
+ while (progname[i] != '\0') {
+ if ((progname[i] == '/') || (progname[i] == '\\')) {
+ progname += i + 1;
+ i = 0;
+ } else {
+ i++;
+ }
+ }
- int c;
- while ((c = getopt(argc, argv, "c:hv:")) != EOF) {
+ while (argc-- > 1) {
+ char *arg = *(++argv);
+ if (arg[0] != '-') {
+ PRINTERR ("%s: invalid option -- %s\n", progname, arg);
+ return usage (1);
+ }
+ char c = arg[1];
switch (c) {
case 'c':
- nbcols = atoi (optarg);
+ arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
+ if (arg == NULL) {
+ PRINTERR ("%s: missing number of columns\n", progname);
+ return usage (1);
+ }
+ nbcols = atoi (arg);
break;
case 'v':
- verbose = atoi (optarg);
+ PRINTOUT ("%s: version %s\n", progname, VERSION);
+ return 0;
break;
case 'h':
default:
- usage (c != 'h');
+ return usage (c != 'h');
}
}
- if (argc - optind != 0) {
- fprintf (stderr, "%s: invalid option -- %s\n", progname, argv[optind]);
- usage (1);
- }
+
+ /* main */
for (i = 0; i < 256; i++) {
- char line[] = " : : x";
+ char line[] = " [ ] x";
if (i > 99) line[0] = '0' + i / 100;
if (i > 9) line[1] = '0' + (i / 10) % 10;
}
line[11] = (((i + 1) % nbcols == 0) || (i == 255)) ? '\n' : ' ';
- write (STDOUT_FILENO, line, 12);
+ fdprintf (_fd_stdout, "%s", line);
}
return 0;
--- /dev/null
+#include "atoi.h"
+
+int atoi (char *str)
+{
+ int i = 0;
+ int s = 1;
+
+ if (*str == '-') {
+ s = 0;
+ str++;
+ }
+
+ while (*str != 0) {
+ if ((*str <'0') || (*str > '9')) {
+ return 0;
+ }
+ i = i * 10 + (int)(*(str++) - '0');
+ }
+
+ return (s) ? i : -i;
+}
+
+/* vim: set ts=4 sw=4 et */
--- /dev/null
+#ifndef __ATOI_H__
+#define __ATOI_H__
+
+int atoi (char *str);
+
+#endif /* __ATOI_H__ */
+
+/* vim: set ts=4 sw=4 et */
--- /dev/null
+/*
+ File name : fprintf.c
+ Date of creation : 05/12/2022
+ Version : 1.0
+ Copyright : Soft'n'design
+ Author : Laurent Mazet <mazet@softndesign.org>
+
+ Description : This file contains embedded printf
+
+ History :
+ - initial version
+*/
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "fdprintf.h"
+
+int _fd_stdout = STDOUT_FILENO;
+int _fd_stderr = STDERR_FILENO;
+
+unsigned int nextpow (unsigned int x, int base) {
+ unsigned int n = 0;
+ while (x) {
+ n++;
+ x = x / base;
+ }
+ return (n == 0) ? 1 : n;
+}
+
+/* simple fprintf function */
+
+int fdprintf (int fd, const char *fmt, ...)
+{
+ char buffer[1024 + 1] = { 0 };
+ char *str = buffer;
+
+ va_list ap;
+ va_start (ap, fmt);
+ while (*fmt) {
+ char *s;
+ int d = 0;
+ unsigned int u;
+ char c = *fmt++;
+
+ /* copy standard char */
+ if (c != '%') {
+ *str++ = c;
+ } else {
+ int t = 0;
+ char w = '0';
+ int i, sz = 0;
+ void *p = NULL;
+
+ /* stamp */
+ if ((*fmt == ' ') || (*fmt == '0')) {
+ w = *fmt++;
+ }
+
+ /* size */
+ if ((*fmt >= '1') && (*fmt <= '9')) {
+ sz = *fmt++ - '0';
+ }
+
+ /* process format char */
+ switch (*fmt++) {
+ case 'c': /* char */
+ c = (char) va_arg (ap, int);
+ *str++ = c;
+ break;
+ case 'd': /* int */
+ d = va_arg (ap, int);
+ if (d < 0) {
+ *str++ = '-';
+ d = -d;
+ }
+ t = 1;
+ /* fall through */
+ case 'u': /* unsigned int */
+ u = (t) ? (unsigned int)d : va_arg (ap, unsigned int);
+ for (i = nextpow (u, 10), s = str; i > 0; i--, s++) {
+ str[i - 1] = '0' + (u % 10);
+ u /= 10;
+ }
+ str = s;
+ break;
+ case 'p': /* pointer */
+ *str++ = '0';
+ *str++ = 'x';
+ w = '0';
+ sz = sizeof (void *) * 2;
+ p = va_arg (ap, void *);
+ /* fall through */
+ case 'x': /* integer hexa */
+ if (!p) {
+ u = va_arg (ap, unsigned int);
+ if (sz == 0) {
+ sz = nextpow (u, 16);
+ }
+ } else {
+ u = (uintptr_t)p;
+ }
+ for (i = sz, t = 1; i > 0; i--) {
+ char x = (char)((u >> (i * 4 - 4)) & 0xf);
+ if ((t == 1) && (x == 0)) {
+ *str++ = w;
+ } else {
+ *str++ = (x > 9) ? 'a' + x - 10 : '0' + x;
+ t = 0;
+ }
+ }
+ break;
+ case 's': /* string */
+ s = va_arg (ap, char *);
+ while (s && *s)
+ *str++ = *s++;
+ break;
+ default:
+ *str++ = '?';
+ }
+ }
+ }
+ va_end (ap);
+
+ /* output string */
+ int n = str - buffer;
+ if (n < (int)sizeof (buffer) - 1) {
+ return write (fd, buffer, n);
+ }
+ return 0;
+}
+
+/* vim: set ts=4 sw=4 et: */
--- /dev/null
+#ifndef __FDPRINTF_H__
+#define __FDPRINTF_H__
+
+int fdprintf (int fd, const char *fmt, ...);
+
+extern int _fd_stdout;
+extern int _fd_stderr;
+
+#define PRINTOUT(fmt...) fdprintf (_fd_stdout, fmt)
+#define PRINTERR(fmt...) fdprintf (_fd_stderr, fmt)
+
+#endif /* __FDPRINTF_H__ */
+
+/* vim: set ts=4 sw=4 et: */
%.ld: %.c
$(call TITLE, "Building $@")
- echo ${<:.c=.exe}: $(shell ./getcomments.pl -p='linker:\s' -f='%' $< | awk '{for (i=1;i<=NF;i++) if ($$(i) ~ /.o$$/) printf " %s", $$(i)}') >> $@
+ echo ${<:.c=.exe}: $(shell ./getcomments.pl -p='linker:\s' -f='%' $< | awk '{for (i=1;i<=NF;i++) if ($$(i) ~ /.o$$/) printf " %s", $$(i)}') > $@
$(call PASS, SUCCESS)
%.o: %.c