548 行
16 KiB
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;
|
|
}
|