more updates for dos compatibility

This commit is contained in:
Gregory Gauthier 2026-01-30 12:37:28 +00:00
parent 0ffe156bcd
commit 814f1014a1
8 changed files with 195 additions and 51 deletions

View File

@ -10,12 +10,12 @@ ECHO.
REM Create build directory if it doesn't exist REM Create build directory if it doesn't exist
IF NOT EXIST build MKDIR build IF NOT EXIST build MKDIR build
ECHO Compiling addnote.exe... ECHO Compiling cnadd.exe...
TCC -A -w -ml -I.\include -ebuild\addnote.exe src\addnote.c TCC -A -w -ml -I.\include -ebuild\cnadd.exe src\cnadd.c
IF ERRORLEVEL 1 GOTO ERROR IF ERRORLEVEL 1 GOTO ERROR
ECHO Compiling dumpnotes.exe... ECHO Compiling cndump.exe...
TCC -A -w -ml -I.\include -ebuild\dumpnotes.exe src\dumpnotes.c TCC -A -w -ml -I.\include -ebuild\cndump.exe src\cndump.c
IF ERRORLEVEL 1 GOTO ERROR IF ERRORLEVEL 1 GOTO ERROR
ECHO. ECHO.

18
CMakeLists.txt Normal file
View File

@ -0,0 +1,18 @@
# CMakeLists.txt - For CLion IDE support only
# Actual builds should use: make (Linux) or make -f MAKEFILE.TC (DOS/Win32)
cmake_minimum_required(VERSION 3.10)
project(cnotes C)
# Force C89/C90 standard
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
# Match our Makefile flags for consistent IDE warnings
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ansi -Wpedantic -Wall -Wextra")
include_directories(include)
add_executable(cnadd src/cnadd.c)
add_executable(cndump src/cndump.c)

View File

@ -23,16 +23,16 @@ BUILDDIR = build
.c.obj: .c.obj:
$(CC) $(CFLAGS) -c -o$*.obj $< $(CC) $(CFLAGS) -c -o$*.obj $<
all: $(BUILDDIR) $(BUILDDIR)\addnote.exe $(BUILDDIR)\dumpnotes.exe all: $(BUILDDIR) $(BUILDDIR)\cnadd.exe $(BUILDDIR)\cndump.exe
$(BUILDDIR): $(BUILDDIR):
if not exist $(BUILDDIR) mkdir $(BUILDDIR) if not exist $(BUILDDIR) mkdir $(BUILDDIR)
$(BUILDDIR)\addnote.exe: $(SRCDIR)\addnote.c $(INCDIR)\platform.h $(BUILDDIR)\cnadd.exe: $(SRCDIR)\cnadd.c $(INCDIR)\platform.h $(INCDIR)\config.h
$(CC) $(CFLAGS) -e$(BUILDDIR)\addnote.exe $(SRCDIR)\addnote.c $(CC) $(CFLAGS) -e$(BUILDDIR)\cnadd.exe $(SRCDIR)\cnadd.c
$(BUILDDIR)\dumpnotes.exe: $(SRCDIR)\dumpnotes.c $(INCDIR)\platform.h $(BUILDDIR)\cndump.exe: $(SRCDIR)\cndump.c $(INCDIR)\platform.h $(INCDIR)\config.h
$(CC) $(CFLAGS) -e$(BUILDDIR)\dumpnotes.exe $(SRCDIR)\dumpnotes.c $(CC) $(CFLAGS) -e$(BUILDDIR)\cndump.exe $(SRCDIR)\cndump.c
clean: clean:
if exist $(BUILDDIR)\*.exe del $(BUILDDIR)\*.exe if exist $(BUILDDIR)\*.exe del $(BUILDDIR)\*.exe

View File

@ -2,17 +2,17 @@
# Strict C89/ANSI compliant build # Strict C89/ANSI compliant build
CC = gcc CC = gcc
CFLAGS = -ansi -pedantic -Wall -Wextra -O2 CFLAGS = -ansi -Wpedantic -Wall -Wextra -O2
INCLUDES = -I include INCLUDES = -I include
SRCDIR = src SRCDIR = src
INCDIR = include INCDIR = include
BUILDDIR = build BUILDDIR = build
SOURCES = $(SRCDIR)/addnote.c $(SRCDIR)/dumpnotes.c SOURCES = $(SRCDIR)/cnadd.c $(SRCDIR)/cndump.c
HEADERS = $(INCDIR)/platform.h HEADERS = $(INCDIR)/platform.h $(INCDIR)/config.h
TARGETS = $(BUILDDIR)/addnote $(BUILDDIR)/dumpnotes TARGETS = $(BUILDDIR)/cnadd $(BUILDDIR)/cndump
.PHONY: all clean install uninstall .PHONY: all clean install uninstall
@ -21,19 +21,19 @@ all: $(BUILDDIR) $(TARGETS)
$(BUILDDIR): $(BUILDDIR):
mkdir -p $(BUILDDIR) mkdir -p $(BUILDDIR)
$(BUILDDIR)/addnote: $(SRCDIR)/addnote.c $(HEADERS) $(BUILDDIR)/cnadd: $(SRCDIR)/cnadd.c $(HEADERS)
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $(SRCDIR)/addnote.c $(CC) $(CFLAGS) $(INCLUDES) -o $@ $(SRCDIR)/cnadd.c
$(BUILDDIR)/dumpnotes: $(SRCDIR)/dumpnotes.c $(HEADERS) $(BUILDDIR)/cndump: $(SRCDIR)/cndump.c $(HEADERS)
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $(SRCDIR)/dumpnotes.c $(CC) $(CFLAGS) $(INCLUDES) -o $@ $(SRCDIR)/cndump.c
clean: clean:
rm -rf $(BUILDDIR) rm -rf $(BUILDDIR)
# Install to /usr/local/bin (optional, run with sudo) # Install to /usr/local/bin (optional, run with sudo)
install: $(TARGETS) install: $(TARGETS)
install -m 755 $(BUILDDIR)/addnote /usr/local/bin/ install -m 755 $(BUILDDIR)/cnadd /usr/local/bin/
install -m 755 $(BUILDDIR)/dumpnotes /usr/local/bin/ install -m 755 $(BUILDDIR)/cndump /usr/local/bin/
uninstall: uninstall:
rm -f /usr/local/bin/addnote /usr/local/bin/dumpnotes rm -f /usr/local/bin/cnadd /usr/local/bin/cndump

12
compile_commands.json Normal file
View File

@ -0,0 +1,12 @@
[
{
"directory": ".",
"command": "gcc -ansi -Wpedantic -Wall -Wextra -O2 -I include -c src/cnadd.c -o build/cnadd.o",
"file": "src/cnadd.c"
},
{
"directory": ".",
"command": "gcc -ansi -Wpedantic -Wall -Wextra -O2 -I include -c src/cndump.c -o build/cndump.o",
"file": "src/cndump.c"
}
]

77
include/config.h Normal file
View File

@ -0,0 +1,77 @@
/*
* config.h - Configuration settings for cnotes
*
* Platform-specific defaults for notes file location.
* Users can override at compile time with -DCNOTES_DIR="path"
* or at runtime via CNOTES_PATH environment variable.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "platform.h"
/*
* CNOTES_FILE - The filename for the notes database
* This is the same across all platforms (8.3 compatible for DOS)
*/
#ifndef CNOTES_FILE
#define CNOTES_FILE "cnotes.csv"
#endif
/*
* CNOTES_DIR - Default directory path (relative to home)
*
* Can be overridden at compile time:
* gcc -DCNOTES_DIR=\".cnotes\" ...
* tcc -DCNOTES_DIR=".cnotes" ...
*
* Platform defaults:
* DOS: Current directory (empty string)
* Windows: .cnotes (in USERPROFILE)
* Unix: .local/share/cnotes (XDG-style)
*/
#ifndef CNOTES_DIR
#if defined(__MSDOS__) || defined(__DOS__)
#define CNOTES_DIR ""
#elif defined(_WIN32)
#define CNOTES_DIR ".cnotes"
#else
#define CNOTES_DIR ".local/share/cnotes"
#endif
#endif
/*
* CNOTES_PATH_ENV - Environment variable to override notes location
*
* If set, this environment variable provides the full path to the
* notes directory, overriding both CNOTES_DIR and HOME_ENV.
*
* Example:
* export CNOTES_PATH=/custom/path/to/notes
* set CNOTES_PATH=C:\NOTES
*/
#define CNOTES_PATH_ENV "CNOTES_PATH"
/*
* Field lengths and limits
*/
#define CATEGORY_LENGTH 10
#define FREETEXT_MAX_LENGTH 125
#define DEFAULT_CATEGORY "General"
/*
* MAX_ENTRIES - Maximum number of entries dumpnotes can load
*
* DOS has limited memory, so we use a smaller default there.
* Can be overridden at compile time: -DMAX_ENTRIES=500
*/
#ifndef MAX_ENTRIES
#if defined(__MSDOS__) || defined(__DOS__)
#define MAX_ENTRIES 500
#else
#define MAX_ENTRIES 5000
#endif
#endif
#endif /* CONFIG_H */

View File

@ -5,12 +5,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "platform.h" #include "platform.h"
#include "config.h"
#define CATEGORY_LENGTH 10
#define FREETEXT_MAX_LENGTH 125
#define DEFAULT_CATEGORY "General"
#define CNOTES_DIR ".local/share/cnotes"
#define CNOTES_FILE "cnotes.csv"
int ensure_directory_exists(const char *path) { int ensure_directory_exists(const char *path) {
struct stat st; struct stat st;
@ -34,23 +29,46 @@ int ensure_directory_exists(const char *path) {
} }
int get_cnotes_path(char *buffer, size_t bufsize) { int get_cnotes_path(char *buffer, size_t bufsize) {
const char *custom_path;
const char *home; const char *home;
size_t len; size_t len;
/* First check for CNOTES_PATH environment variable override */
custom_path = getenv(CNOTES_PATH_ENV);
if (custom_path != NULL && strlen(custom_path) > 0) {
if (strlen(custom_path) >= bufsize) {
fprintf(stderr, "Error: Path too long\n");
return 0;
}
strcpy(buffer, custom_path);
return 1;
}
/* Fall back to HOME_ENV + CNOTES_DIR */
home = getenv(HOME_ENV); home = getenv(HOME_ENV);
if (home == NULL) { if (home == NULL) {
fprintf(stderr, "Error: %s environment variable not set\n", HOME_ENV); fprintf(stderr, "Error: %s environment variable not set\n", HOME_ENV);
fprintf(stderr, "Hint: Set %s to specify notes directory\n", CNOTES_PATH_ENV);
return 0; return 0;
} }
/* Build path: $HOME/.local/share/cnotes */ /* Build path: $HOME/CNOTES_DIR (or just $HOME if CNOTES_DIR is empty) */
len = strlen(home); len = strlen(home);
if (len + strlen(CNOTES_DIR) + 2 > bufsize) { if (strlen(CNOTES_DIR) == 0) {
fprintf(stderr, "Error: Path too long\n"); /* DOS mode: use home directory directly */
return 0; if (len >= bufsize) {
fprintf(stderr, "Error: Path too long\n");
return 0;
}
strcpy(buffer, home);
} else {
/* Unix/Windows: append CNOTES_DIR to home */
if (len + strlen(CNOTES_DIR) + 2 > bufsize) {
fprintf(stderr, "Error: Path too long\n");
return 0;
}
sprintf(buffer, "%s" PATH_SEP_STR "%s", home, CNOTES_DIR);
} }
sprintf(buffer, "%s" PATH_SEP_STR "%s", home, CNOTES_DIR);
return 1; return 1;
} }

View File

@ -6,16 +6,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "platform.h" #include "platform.h"
#include "config.h"
#define MAX_LENGTH 500 /* Allow fgets to read up to this many characters */ #define MAX_LENGTH 500 /* Allow fgets to read up to this many characters */
#define DATE_LENGTH 10 /* YYYY-MM-DD */ #define DATE_LENGTH 10 /* YYYY-MM-DD */
#define TIME_LENGTH 5 /* HH:MM */ #define TIME_LENGTH 5 /* HH:MM */
#define CATEGORY_LENGTH 10 /* CATEGORY__ */
#define TXTMSG_LENGTH 125 /* Max length of a text message */ #define TXTMSG_LENGTH 125 /* Max length of a text message */
#define MAX_ENTRIES 1500 /* Maximum number of entries to load */
#define CNOTES_FILE "cnotes.csv"
#define CNOTES_DIR ".local/share/cnotes"
typedef enum { typedef enum {
@ -150,23 +146,46 @@ int parse_line(const char *line, Entry *entry) {
} }
int get_cnotes_path(char *buffer, size_t bufsize) { int get_cnotes_path(char *buffer, size_t bufsize) {
const char *custom_path;
const char *home; const char *home;
size_t len; size_t len;
/* First check for CNOTES_PATH environment variable override */
custom_path = getenv(CNOTES_PATH_ENV);
if (custom_path != NULL && strlen(custom_path) > 0) {
if (strlen(custom_path) + strlen(CNOTES_FILE) + 2 > bufsize) {
fprintf(stderr, "Error: Path too long\n");
return 0;
}
sprintf(buffer, "%s" PATH_SEP_STR "%s", custom_path, CNOTES_FILE);
return 1;
}
/* Fall back to HOME_ENV + CNOTES_DIR */
home = getenv(HOME_ENV); home = getenv(HOME_ENV);
if (home == NULL) { if (home == NULL) {
fprintf(stderr, "Error: %s environment variable not set\n", HOME_ENV); fprintf(stderr, "Error: %s environment variable not set\n", HOME_ENV);
fprintf(stderr, "Hint: Set %s to specify notes directory\n", CNOTES_PATH_ENV);
return 0; return 0;
} }
/* Build path: $HOME/.local/share/cnotes/cnotes.csv */ /* Build path to cnotes file */
len = strlen(home); len = strlen(home);
if (len + strlen(CNOTES_DIR) + strlen(CNOTES_FILE) + 3 > bufsize) { if (strlen(CNOTES_DIR) == 0) {
fprintf(stderr, "Error: Path too long\n"); /* DOS mode: file in home directory directly */
return 0; if (len + strlen(CNOTES_FILE) + 2 > bufsize) {
fprintf(stderr, "Error: Path too long\n");
return 0;
}
sprintf(buffer, "%s" PATH_SEP_STR "%s", home, CNOTES_FILE);
} else {
/* Unix/Windows: HOME/CNOTES_DIR/CNOTES_FILE */
if (len + strlen(CNOTES_DIR) + strlen(CNOTES_FILE) + 3 > bufsize) {
fprintf(stderr, "Error: Path too long\n");
return 0;
}
sprintf(buffer, "%s" PATH_SEP_STR "%s" PATH_SEP_STR "%s", home, CNOTES_DIR, CNOTES_FILE);
} }
sprintf(buffer, "%s" PATH_SEP_STR "%s" PATH_SEP_STR "%s", home, CNOTES_DIR, CNOTES_FILE);
return 1; return 1;
} }
@ -192,8 +211,8 @@ int main(int argc, char *argv[]) {
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--date") == 0) { if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--date") == 0) {
if (sort_mode != SORT_NONE) { if (sort_mode != SORT_NONE) {
fprintf(stderr, "dumpnotes: cannot specify multiple sort options\n"); fprintf(stderr, "cndump: cannot specify multiple sort options\n");
fprintf(stderr, "usage: dumpnotes [[-d|--date] | [-c|--category]] [-r|--reverse] [filename]\n"); fprintf(stderr, "usage: cndump [[-d|--date] | [-c|--category]] [-r|--reverse] [filename]\n");
exit(1); exit(1);
} }
sort_mode = SORT_DATE; sort_mode = SORT_DATE;
@ -201,8 +220,8 @@ int main(int argc, char *argv[]) {
else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--category") == 0) { else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--category") == 0) {
if (sort_mode != SORT_NONE) { if (sort_mode != SORT_NONE) {
fprintf(stderr, "dumpnotes: cannot specify multiple sort options\n"); fprintf(stderr, "cndump: cannot specify multiple sort options\n");
fprintf(stderr, "usage: dumpnotes [[-d|--date] | [-c|--category]] [-r|--reverse] [filename]\n"); fprintf(stderr, "usage: cndump [[-d|--date] | [-c|--category]] [-r|--reverse] [filename]\n");
exit(1); exit(1);
} }
sort_mode = SORT_CATEGORY; sort_mode = SORT_CATEGORY;
@ -228,7 +247,7 @@ int main(int argc, char *argv[]) {
notesfile = fopen(file_path, "r"); notesfile = fopen(file_path, "r");
if (notesfile == NULL) { if (notesfile == NULL) {
fprintf(stderr, "Error: Cannot open file '%s'\n", file_path); fprintf(stderr, "Error: Cannot open file '%s'\n", file_path);
fprintf(stderr, "Hint: Use 'addnote' to create your first entry\n"); fprintf(stderr, "Hint: Use 'cnadd' to create your first entry\n");
return 1; return 1;
} }
@ -238,7 +257,7 @@ int main(int argc, char *argv[]) {
entry_count++; entry_count++;
} }
else { else {
fprintf(stderr, "dumpnotes: invalid line: %s\n", line); fprintf(stderr, "cndump: invalid line: %s\n", line);
} }
} }
fclose(notesfile); fclose(notesfile);