zos/main.c

548 行
16 KiB
C

/*********************************************
* Description - ZOS Operating System
* Author - Vilyaem
* Date - Apr 02 2024
* *******************************************/
/*----------PREPROCESSOR----------*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*S language*/
#define LOOP_FINISHING 1
#define LOOP_HARDLOOP 3
#define LOOP_HARDLOOP_IDLE 5
#define LOOP_NOLOOP 0
#define LOOP_TEMPLOOP 2
#define LOOP_TEMPLOOP_IDLE 4
#define SMAXCNT 64
/*MiniFS*/
#define MINIFS_MAXNAMESIZE 16
#define MINIFS_MAXBYTESIZE 32768
#define MINIFS_MAXFILES 16
/*Vedlin*/
#define VEDMAXCNT 128
/*----------DATA STRUCTURES----------*/
/*--MINIFS--*/
typedef struct{
char name[MINIFS_MAXNAMESIZE];
unsigned char data[MINIFS_MAXBYTESIZE];
}MiniFile;
typedef struct{
MiniFile files[MINIFS_MAXFILES];
int filecnt;
}MiniFileSystem;
/*----------GLOBALS----------*/
MiniFileSystem filesystem;
char hist[SMAXCNT][SMAXCNT];
char interact[SMAXCNT];
char promptbuf[SMAXCNT];
char vedfile[VEDMAXCNT][VEDMAXCNT];
char vedfilename[VEDMAXCNT];
char workspace[SMAXCNT];
int histcnt = 0;
int i,j,k,l;
int ifskip = 0;
int loopend = 0xDEADBEEF;
int loopstart = 0xDEADBEEF;
int loopstatus = LOOP_NOLOOP;
int pnum;
int stack[SMAXCNT];
int stackptr = 0;
/*----------FUNCTIONS----------*/
/*--MINI FILESYSTEM--*/
/*********************************************
* Description - Initialize a file system,
* blank all files.
* Author - Vilyaem
* Date - Mar 08 2024
* *******************************************/
void InitFileSystem(MiniFileSystem* sys){
for(i = 0;i != MINIFS_MAXFILES;i++){
sys->files[i].name[0] = '_';
sys->files[i].name[1] = '\0';
for(j = 0;j != MINIFS_MAXBYTESIZE;j++){
sys->files[i].data[j] = '\0';
}
}
}
/*********************************************
* Description - Create a file,
* given the name, an array of data, and the filesystem.
* Author - Vilyaem
* Date - Mar 08 2024
* *******************************************/
void CreateFile(MiniFileSystem* sys, unsigned char data[], char name[]){
if(strlen(name) > MINIFS_MAXNAMESIZE){
puts("error: filename too long");
return;
}
if(sys->filecnt >= MINIFS_MAXFILES){
puts("error: too many files");
return;
}
strcpy(sys->files[sys->filecnt].name,name);
memcpy(&sys->files[sys->filecnt].data,&data,MINIFS_MAXBYTESIZE);
printf("created file name: %s | data: %s | filecnt: %d\n",name,data,sys->filecnt);
sys->filecnt++;
printf("filecnt now: %d\n",sys->filecnt);
}
/*********************************************
* Description - Get filesystem indice given filename
* Author - Vilyaem
* Date - Apr 10 2024
* *******************************************/
int GetFileIndice(MiniFileSystem* sys, char name[]){
for(i = 0; i != MINIFS_MAXFILES;i++){
if(sys->files[i].name[0] != '_'){
if(strcmp(sys->files[i].name,name) == 0){
return i;
}
}
}
return -1;
}
/*********************************************
* Description - Resort the file system,
* we do this after deleting a file, otherwise we
* will start overwriting stuff.
* Author - Vilyaem
* Date - Mar 08 2024
* *******************************************/
void SortFS(MiniFileSystem* sys){
for(i = 0;i != MINIFS_MAXFILES;i++){
MiniFile swap;
if(sys->files[i].name[0] == '_' ){
swap = sys->files[i];
sys->files[i] = sys->files[i+1];
sys->files[i+1] = swap;
}
}
}
/*********************************************
* Description - Delete a file, given the name and the
* file system
* Author - Vilyaem
* Date - Mar 08 2024
* *******************************************/
void DeleteFile(MiniFileSystem* sys, char name[]){
int getfile = GetFileIndice(sys,name);
if(getfile != -1){
sys->files[getfile].name[0] = '_';
for(i = 0;j != MINIFS_MAXBYTESIZE;i++){
sys->files[i].data[i] = '\0';
}
SortFS(sys);
}
}
/*********************************************
* Description - List files
* Author - Vilyaem
* Date - Apr 04 2024
* *******************************************/
void ListFiles(MiniFileSystem* sys){
for(i = 0; i != MINIFS_MAXFILES;i++){
printf("%d: (%d)\t\t\t\t %s\n",i,sys->files[i].name[0],sys->files[i].name);
}
}
/*********************************************
* Description - Copy contents of a file to another file
* Author - Vilyaem
* Date - Apr 04 2024
* *******************************************/
void CopyFile(MiniFileSystem* sys, char destname[], char srcname[]){
int getfilesrc = GetFileIndice(sys,srcname);
int getfiledest = GetFileIndice(sys,destname);
if(getfilesrc == -1){
return;
}
if(getfiledest == -1){
sys->filecnt++;
memcpy(&sys->files[sys->filecnt].data,&sys->files[getfilesrc].data,sizeof(MINIFS_MAXBYTESIZE));
}
else {
memcpy(&sys->files[getfiledest].data,&sys->files[getfilesrc].data,sizeof(MINIFS_MAXBYTESIZE));
}
strcpy(sys->files[getfilesrc].name,destname);
}
/*********************************************
* Description - Rename file
* Author - Vilyaem
* Date - Apr 04 2024
* *******************************************/
void RenameFile(MiniFileSystem* sys, char newname[], char oldname[]){
int getfileold = GetFileIndice(sys,oldname);
strcpy(sys->files[getfileold].name,newname);
}
/*********************************************
* Description - Write data to a file
* Author - Vilyaem
* Date - Apr 04 2024
* *******************************************/
void WriteToFile(MiniFileSystem* sys, char destname[], unsigned char content[]){
int getfile = GetFileIndice(sys,destname);
if(getfile != -1){
for(i = 0; i != MINIFS_MAXBYTESIZE;i++){
sys->files[getfile].data[i] = content[i];
}
}
}
/*********************************************
* Description - Show a file, like in DOS
* Author - Vilyaem
* Date - Apr 10 2024
* *******************************************/
void TypeFile(MiniFileSystem* sys, char* name){
int getfile = GetFileIndice(sys,name);
if(getfile != -1){
for(i = 0; i != MINIFS_MAXBYTESIZE;i++){
printf("%c",(char)sys->files[getfile].data[i]);
}
}
}
/*********************************************
* Description - Universally prompt the user for a string
* Author - Vilyaem
* Date - Apr 17 2024
* *******************************************/
char* prompt(){
memset(promptbuf,0,sizeof(promptbuf));
int c;
while ((c = getchar()) != '\n' && c != EOF);
fgets(promptbuf,SMAXCNT,stdin);
promptbuf[strcspn(promptbuf,"\n")] = '\0';
return promptbuf;
}
/*--VEDLIN TEXT EDITOR--*/
/*********************************************
* Description - Print out vedlin's buffer
* Author - Vilyaem
* Date - Apr 16 2024
* *******************************************/
void VedlinPrintFile(){
for(i = 0; i != VEDMAXCNT;i++){
if(vedfile[i][0] != '\0'){
printf("%d : ",i);
puts(vedfile[i]);
}
}
}
/*********************************************
* Description - Append to a certain line in vedlin
* Author - Vilyaem
* Date - Apr 16 2024
* *******************************************/
void VedlinAppendFile(){
for(i = 0; i != VEDMAXCNT;i++){
if(vedfile[i][0] == '\0'){
strcpy(vedfile[i],prompt());
break;
}
}
}
/*********************************************
* Description - Vedlin saving
* Author - Vilyaem
* Date - Apr 16 2024
* *******************************************/
void VedlinWriteFile(){
int wrtfile = GetFileIndice(&filesystem,vedfilename);
unsigned char data[MINIFS_MAXBYTESIZE];
if(wrtfile == -1){
puts("The file isnt there");
}
else {
puts("The file is there");
}
/*Format the data*/
for(i = 0; i != VEDMAXCNT;i++){
strcat((char*)data,(char*)vedfile[i]);
}
if(wrtfile != 1){
/*memcpy(&filesystem.files[wrtfile].data,&data,sizeof(MINIFS_MAXBYTESIZE));*/
CreateFile(&filesystem,data,vedfilename);
}
else {
WriteToFile(&filesystem,filesystem.files[wrtfile].name,data);
}
}
/*********************************************
* Description - Load a file from the filesystem
* and put it in vedlin's file buffer
* Author - Vilyaem
* Date - Apr 16 2024
* *******************************************/
void LoadFileVedlin(){
/*Get the file*/
int fileindice = GetFileIndice(&filesystem,vedfilename);
for(i = 0; i != VEDMAXCNT;i++){
/*strcpy(file[i],strtok(filesystem.files[fileindice].data,"\n"));*/
char strbuf[VEDMAXCNT];
sprintf(strbuf,"%s",strtok((char*)filesystem.files[fileindice].data,"\n"));
strcpy(vedfile[i],strbuf);
}
}
/*********************************************
* Description - The vedlin line editor
* Author - Vilyaem
* Date - Apr 16 2024
* *******************************************/
void Vedlin(void){
puts("VEDLIN text editor by Vilyaem 2024 https://vilyaem.xyz thekenyaz@yandex.com\nThis software is CFSL licensed, you should have recieved the license with this program,\nyou can view the license here https://peepsoft.3vm.cl/LICENSE.TXT\n\nq:quit\nw:write\nc:change line\nd:delete line\na:append\np:put file buffer\nk:clear\n\nEnter filename:");
strcpy(vedfilename,prompt());
puts(vedfilename);
/*vedfilename[0] = 'a';*/
/*LoadFileVedlin();*/
while(1){
char operation;
int selectline;
printf("*");
scanf("%c",&operation);
/*operation = fgetc(stdin);*/
switch(operation){
case 'q': puts("Goodbye."); return; break;
case 'w': VedlinWriteFile(); break;
case 'c': scanf("%d",&selectline); for(i = 0; i != selectline - 1; i++){if(vedfile[i][0]=='\0'){vedfile[i][0] = '\n';}}
prompt();strcpy(vedfile[selectline],promptbuf);break;
case 'd': scanf("%d",&selectline); vedfile[selectline][0] = '\0'; break; /* haha! */
case 'a': VedlinAppendFile(); break;
case 'p': VedlinPrintFile(); break;
case 'k': puts("\x1b[H\x1b[J"); break;
default: puts("?"); break;
}
}
}
/*--S PROGRAMMING LANGUAGE & SHELL--*/
/*********************************************
* Description - Push onto the stack
* Author - Vilyaem
* Date - Mar 14 2024
* *******************************************/
void Push(int num){
stack[stackptr] = num;
stackptr++;
}
/*********************************************
* Description - Pop off the stack
* Author - Vilyaem
* Date - Mar 14 2024
* *******************************************/
void Pop(){
stack[stackptr] = 0xDEADBEEF;
stackptr--;
}
/*********************************************
* Description - Setup S Lang
* You can also use this
* to reset everything
* Author - Vilyaem
* Date - Apr 04 2024
* *******************************************/
void SetupS(){
/*Setup stack and history*/
for(i = 0; i != SMAXCNT;i++){
stack[i] = 0xDEADBEEF;
}
for(i = 0; i != SMAXCNT;i++){
hist[i][0] = '\0';
strcpy(hist[i],"hello");
}
}
/*********************************************
* Description - Do it!
* Author - Vilyaem
* Date - Mar 14 2024
* *******************************************/
void Do(char interact[]){
/*Get ready, and add to history*/
strcpy(workspace,interact);
/*If we are skipping an if statement, skip until endif*/
if(ifskip != 0 && strcmp(workspace,"endif") != 0){
return;
}
/*If we have broken out of a loop, skip over statements*/
if(loopstatus == LOOP_FINISHING && workspace[0] != '_'){
return;
}
switch(workspace[0]){
case 'b': puts("Bye."); exit(0); break; /* shutting off */
case 'p': scanf("%d",&pnum); Push(pnum);break; /* pushing number */
case ';': return; break; /* asm-like comments */
case 'i': if(stack[stackptr-1] != 1){ifskip = 1;}break; /* 'if' */
case 'e': ifskip = 0; break; /* 'endif' */
case '!': if(stack[stackptr-1] != stack[stackptr-2]){Push(1);}break; /* != */
case '<': if(stack[stackptr-1] < stack[stackptr-2]){Push(1);}break; /* < */
case '>': if(stack[stackptr-1] > stack[stackptr-2]){Push(1);}break; /* > */
case '=': if(stack[stackptr-1] == stack[stackptr-2]){Push(1);}break; /* == */
case 'd': Pop();break; /* drop */
case '+': stack[stackptr-1] = stack[stackptr-1] + stack[stackptr-2];Pop();break; /* + */
case '-': stack[stackptr-1] = stack[stackptr-1] - stack[stackptr-2];Pop();break; /* - */
case '*': stack[stackptr-1] = stack[stackptr-1] * stack[stackptr-2];Pop();break; /* * */
case '/': stack[stackptr-1] = stack[stackptr-1] / stack[stackptr-2];Pop();break; /* / */
case '%': stack[stackptr-1] = stack[stackptr-1] % stack[stackptr-2];Pop();break; /* % */
case 'k': pnum = getchar();Push(pnum);break; /* key */
case '@': loopstart = histcnt+1; loopstatus = LOOP_TEMPLOOP_IDLE; break; /* @ temporary loop */
case '&': loopstart = histcnt+1; loopstatus = LOOP_HARDLOOP_IDLE; break; /* & hard loop */
case '{': loopstatus = LOOP_FINISHING; break; /* { breaks */
case '_':
loopend = histcnt;
if(loopstatus == LOOP_HARDLOOP_IDLE){
loopstatus = LOOP_HARDLOOP;
while(loopstatus != LOOP_NOLOOP){
for(i = loopstart; i != loopend;i++){
Do(hist[i]);
}
}
}
if(loopstatus == LOOP_TEMPLOOP_IDLE){
loopstatus = LOOP_TEMPLOOP;
while(loopstatus != LOOP_NOLOOP){
for(i = loopstart; i != loopend;i++){
Do(hist[i]);
if(stack[stackptr-1] == 1){
loopstatus = LOOP_NOLOOP;
break;
}
}
}
}
break; /* _ marks end of loop */
/*Special dot commands*/
case '.':
switch(workspace[1]){
case 's': /*.s prints the stack */
printf("STACK:");
for(i = 0;i != SMAXCNT;i++){
if(i == stackptr){
printf("->");
}
printf(" %d:",i);
if(stack[i] != 0xDEADBEEF){
printf(" <%d> ",stack[i]);
}
else{
printf(" <NULL> ");
}
}
puts("");
break;
case 'p': /* print value as ASCII and pop*/
putchar(stack[stackptr]);
Pop();
break;
case 'c': /*.clr clears the stack and sets stackptr to 0*/
SetupS();
break;
case 'h': /*.hist shows history*/
for(i = 0; i != SMAXCNT;i++){
if(hist[i][0] != '\0'){
printf("%s\n",hist[i]);
}
}
printf("histcnt: %d\n",histcnt);
break;
default: /* . just prints and pops */
printf("%d\n",stack[stackptr]);
Pop();
break;
}
/*ZOS specific commands*/
case '$':
switch(workspace[1]){
case 't': /* $type a file */
TypeFile(&filesystem,prompt());
break;
case 'd': /* $delete a file */
DeleteFile(&filesystem,prompt());
break;
case 'v': /* $vedlin */
Vedlin();
break;
case 'c': /* $copy a file */
CopyFile(&filesystem,prompt(),prompt());
break;
case 's': /* $save the system to disk */
/*SaveToDisk();*/
break;
case 'l': /* $list files */
ListFiles(&filesystem);
break;
}
}
/* handle stack being broken */
if(stackptr <= -1){
puts("STACK UNDERFLOW");
SetupS();
stackptr = 0;
}
else if(stackptr > SMAXCNT){
puts("STACK OVERFLOW");
SetupS();
stackptr = 0;
}
puts("ok");
printf("-> %d\n",stackptr);
}
/*----------ZOS OPERATING SYSTEM----------*/
/*********************************************
* Description - Main
* Author - Vilyaem
* Date - Apr 02 2024
* *******************************************/
int main(void){
InitFileSystem(&filesystem);
SetupS();
puts("ZOS by Vilyaem (https://vilyaem.xyz thekenyaz@yandex.com)");
while(1){
printf("?>");
Do(prompt());
}
return 0;
}