Skip to content

Commit

Permalink
Implementation of rev(1B) (#52)
Browse files Browse the repository at this point in the history
* feat: Initial implementation of rev(1).

* chore: No need to use printf() if we could just puts().

* chore: Close string correctly.

* chore: Mention new rev(1B) implementation at CHANGES.

* chore: rev refactor.

* feat: Added (rudimentary) multibyte support for rev.c.

* feat: Full support for UTF-8 multibyte at rev(1).

Borrowed from suckless sbase implementation, as mentioned on the header.

* chore: Update CHANGES

* docs: Added manual page for rev(1).

* chore: Added rev/ to the build list at the top 'makefile'.

* chore: Mention where UTF-8 support at rev(1) comes from in CHANGES
  • Loading branch information
takusuman authored Jul 22, 2024
1 parent eb428c1 commit 450eba8
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
Release ...
* rev: UTF-8 support, borrowed from suckless sbase. In varietate concordia.
* [NEW] apply, pick: Complete implementation for both apply and pick, from
Research UNIX 8th and 10th respectively; extended payloads for pick in
comparison with the original implementation.
* seq: Support for counting from negative numbers to positive or making a
negative sequence.
* rev: Full refactor (made by Samuel Brederodes).
* Fixes for building dynamically on Arch Linux and other GNU C
Library-based Linux systems which ships exclusively dynamic versions
of its libraries, also remove `readlink_ucb' object file at `readlink/'
Expand All @@ -13,6 +15,7 @@ Release ...
is not used as much on most common architectures such as x86
(patch by Samuel Brederodes).
* watch: `use_default_colors()', do not force black and white.
* [NEW] rev: New implementation, not capable of UTF-8 yet.
* cpio, diff, tabs: Fix duplicated definitions (made/reported by crumbtoo,
merged by me, Luiz Antônio Rangel). Thanks! --- or better: Merci!
* rm: Added real support for the POSIX 1003.1(2008) standard, implemented
Expand Down
2 changes: 1 addition & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ SUBDIRS = build libwchar libcommon libuxre _install \
mail man mesg mkdir mkfifo mknod more mvdir \
nawk news nice nl nohup oawk od \
paste pathchk pg pgrep pr printenv printf priocntl ps psrinfo pwd \
random readlink renice rm rmdir \
random readlink renice rev rm rmdir \
sdiff sed seq setpgrp shl sleep sort spell split stty su sum sync \
tabs tail tapecntl tar tcopy tee test time touch tr true tsort tty \
ul uname uniq units users watch wc what who whoami whodo xargs yes
Expand Down
15 changes: 15 additions & 0 deletions rev/Makefile.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
all: rev

rev: rev.o
$(LD) $(LDFLAGS) rev.o $(LCOMMON) $(LWCHAR) $(LIBS) -o rev

rev.o: rev.c
$(CC) $(CFLAGSU) $(CPPFLAGS) $(ICOMMON) $(IWCHAR) -c rev.c

install: all
$(UCBINST) -c rev $(ROOT)$(DEFBIN)/rev
$(STRIP) $(ROOT)$(DEFBIN)/rev
$(MANINST) -c -m 644 rev.1 $(ROOT)$(MANDIR)/man1/rev.1

clean:
rm -f rev rev.o core log *~
27 changes: 27 additions & 0 deletions rev/rev.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.\"
.\" Copyright (c) 2024 Luiz Antônio Rangel
.\"
.\" SPDX-Licence-Identifier: Zlib
.\"
.TH REV 1 "07/21/24" "Heirloom Toolchest" "User Commands"
.SH NAME
rev \- reverse lines of a file
.SH SYNOPSIS
\fBrev\fR [\fIfile\fR]
.SH DESCRIPTION
.I Rev
copies the lines of the specified
files to the standard output, but
reversing the order of characters.
If no file is specified, it reads
from the standard input.
.SH NOTES
This
.I rev
supports internationalisation. In
varietate concordia.
.SH HISTORY
A
.I rev
command first appeared in UNIX 6th
Edition.
121 changes: 121 additions & 0 deletions rev/rev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* rev.c - reverse lines of a file
*
* A little bit based on Luiz' implementation
*/
/*
* Copyright (C) 2024: Luiz Antônio Rangel (takusuman)
* Copyright (C) 2024: Samuel Brederodes (callsamu)
*
* SPDX-Licence-Identifier: Zlib
*
* UTF-8 support borrowed from suckless sbase implementation.
* Copyright (C) 2016 Mattias Andrée ([email protected])
* SPDX-Licence-Identifier: MIT
*/

#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#if defined(__linux__) || defined(__dietlibc__)
#define _XOPEN_SOURCE 600L
#endif

#define NULL_BYTE '\0'

static char *progname;

int copy_line(FILE *from, char *to_buffer, size_t to_buffer_size) {
for (int i = 0; i < to_buffer_size; i++) {
int c = fgetc(from);

switch (c) {
case EOF:
to_buffer[i] = NULL_BYTE;
return EOF;
case '\n':
to_buffer[i] = '\n';
to_buffer[(i + 1)] = NULL_BYTE;
return 0;
default:
to_buffer[i] = c;
}
}

return 0;
}

bool isutf8chr(char c) {
if ((c & 0xC0) == 0x80) {
return true;
} else {
return false;
}
}

void reverse_string(char *string) {
int len = strlen(string),
i = 0,
lf = 0;

lf = len && string[(len - 1)] == '\n';
len -= lf;
i = len;
for (len = 0; i--;) {
switch (isutf8chr(string[i])) {
case true:
len++;
break;
default: /* "Else", "false", call it what you like. */
fwrite((string + i), 1,
(len + 1), stdout);
len = 0;
break;
}
}

if (len) fwrite(string, 1, len, stdout);
if (lf) fputc('\n', stdout);
}

int main(int argc, char *argv[]) {
progname = argv[0];

int fdinput = STDIN_FILENO;
if (argc > 1) {
fdinput = open(argv[1], O_RDONLY);

if (fdinput < 0) {
fprintf(stderr, "%s: %s\n",
progname, strerror(errno));
return EXIT_FAILURE;
}
}

FILE *input = fdopen(fdinput, "r");
if (!input) {
fprintf(stderr, "%s: cannot open stream at descriptor %d: %s\n",
progname, fdinput, strerror(errno));
return EXIT_FAILURE;
}

char buffer[BUFSIZ];

while (true) {
int eof = copy_line(input, buffer, BUFSIZ);
reverse_string(buffer);

if (eof == EOF) {
if (fdinput) {
fclose(input);
}
return EXIT_SUCCESS;
}
}
}

0 comments on commit 450eba8

Please sign in to comment.