Вход на сайт
Командный интерпретатор 22.03.2025
1325
NEW 22.03.25 03:15
Последний раз изменено 22.03.25 03:22 (uscheswoi_82)
Всем привет! Делаю командный интерпретатор:
Вот код interp.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 0
#define FALSE !TRUE
#define MAX_SUBSTR 10
#define MAX_CMD 15
#define MAX_BUFFER 512
char *cmd[] = {"CON", // 0
"PRN",// 1
"F",// 2
"D",// 3
"DEL",// 4
"IF",// 5
"Q.",// 6
"MD",// 7
"CD",// 8
"FOR",// 9
"WAIT",// 10
"REM",// 11
"VR",// 12
"VAR",//13
"BEEP",// 14
"JMP",//15
"CL",// 16
"GXY",// 17
"RET",// 18
"ENUM",// 19
"RUN",// 20
"DR",// 21
"ED",// 22
"MSG",// 23
"CAL", // 24
"none"}; // 25
/* См. https://groups.germany.ru/showmessage.pl?
Number=41060081&Board=12994140000001 */
char splits[MAX_SUBSTR][250];
int split_str(char *buf, char del, int idx) {
int j=0, i=0, k=-1;
for(j=0; j<idx; j++) splits[j][0] = '\0';
for(j=0; j<strlen(buf); j++) {
k++;
splits[ i ][k] = buf[j];
if(buf[j] == del) {
splits[ i ][k] = '\0';
i++;
k=-1;
}
}
splits[ i ][k+1] = '\0';
return i;
}
int main(void) {
char buf[MAX_BUFFER]; // Буфер для команды
char scr[MAX_BUFFER]; // Буфер для экрана
FILE *f; // Для файла
int i = 0; // Для цикла for
int is_new_line = FALSE; // Перенос строки?
int is_echo = FALSE; // Эхо?
int is_file = FALSE; // Читаем из файла?
f = fopen("STARTUP.INT", "r"); // Открываем файл startup.int
if(f != NULL) { is_file = TRUE; }
START:
while(1) {
if(is_file == FALSE) {
printf("\n? ");
gets(buf);
}
else {
fgets(buf, 512, f);
if(feof(f)) { fclose(f); is_file = FALSE; goto START; }
}
// Если команда Q., то выходим из файла или программы
if(strcmp(strupr(buf), "Q.") == 0) {
if(is_file == FALSE) exit(0);
else {
fclose(f);
goto START;
}
}
// Расщипляем строку на подстроки
split_str(buf, ' ', MAX_SUBSTR);
for(i=0; i<MAX_CMD; i++) {
if(strcmp(strupr(splits[0]), cmd[ i ]) == 0)
break;
}
switch(i) {
case 0:
//printf("\nCON");
// Перенос строки
if(strcmp(strupr(splits[1]), "NON") == 0) is_new_line = TRUE;
else if(strcmp(strupr(splits[1]), "EON") == 0) is_echo = TRUE; // Эхо
else {
strncpy(scr, buf+4, strlen(buf)-2);
printf("%s", scr);
}
break;
default:
f = fopen(buf, "r"); // Читаем из файла команды
if(f != NULL) {
is_file = TRUE;
goto START;
}
else
printf("\nНет такого файла или команды.");
break;
}
}
return 0;
}
Продолжение следует...
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
Моя ФЛ Он и Она
Моя ФЛ Он и Она
NEW 22.03.25 05:02
в ответ uscheswoi_82 22.03.25 03:15
Работает вот так:

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
Моя ФЛ Он и Она
Моя ФЛ Он и Она
NEW 22.03.25 23:00
в ответ uscheswoi_82 22.03.25 05:02
Короче в моей программе файл startup.int, запускается первый раз, при запуске командного интерпретатора для каких-нибудь настроек, это так-же как в MS-DOS при первом запуске запускались autoexec.bat и config.sys.
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
Моя ФЛ Он и Она
Моя ФЛ Он и Она
NEW 24.03.25 03:13
в ответ uscheswoi_82 22.03.25 23:00
Немножко добавил кода:
void convert_wrtime_to_hhmmss(unsigned short wrtime, int *hours, int *minutes, int *seconds) {
*hours = (wrtime >> 11) & 0x1F;
*minutes = (wrtime >> 5) & 0x3F;
*seconds = (wrtime & 0x1F) * 2;
}
case 3:
is_done = _dos_findfirst("*.*",_A_NORMAL,&ffblk);
while(!is_done) {
printf("%s", ffblk.name);
gotoxy(13, wherey());
printf("%ld", ffblk.size);
gotoxy(13+9, wherey());
convert_wrtime_to_hhmmss(ffblk.wr_time, &hours, &minutes, &seconds);
printf("d:d:d\n", hours, minutes, seconds);
is_done = _dos_findnext(&ffblk);
}
break;
Результат работы кода, даём команду d:
? d BC.BAT 65 02:35:48 INTERP.CPP 3838 01:40:08 INTERP.EXE 17927 03:08:22 INTERP.OBJ 4145 03:08:22 README.DOC 1700 06:11:34 STARTUP.INT 39 02:50:26 TC0000.SWP 262144 03:08:22 TEST.INT 16 01:35:36
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
Моя ФЛ Он и Она
Моя ФЛ Он и Она
24.03.25 21:19
в ответ uscheswoi_82 24.03.25 03:13
Я немного поменял код, команда теперь называется dr:
char *cmd[] = {"CON", // 0
"PRN",// 1
"F",// 2
"DR", // 3 Теперь DR для отображения файлов и директорий!!!
"D",// 4
"DEL",// 5
"IF",// 6
"Q.",// 7
"MD",// 8
"CD",// 9
"FOR",// 10
"WAIT",// 11
"REM",// 12
"VR",// 13
"VAR",//14
"BEEP",// 15
"JMP",//16
"CL",// 17
"GXY",// 18
"RET",// 19
"ENUM",// 20
"RUN",// 21
"DR",// 22
"ED",// 23
"MSG",// 24
"CAL", // 25
"none"}; // 26
Команда dr:
case 3:
is_done = _dos_findfirst("*.*",_A_NORMAL,&ffblk);
while(!is_done) {
printf("%s", ffblk.name);
gotoxy(14, wherey());
printf("%ld", ffblk.size);
gotoxy(14+9, wherey());
convert_wrtime_to_hhmmss(ffblk.wr_time, &hours, &minutes, &seconds);
printf("d:d:d\n", hours, minutes, seconds);
is_done = _dos_findnext(&ffblk);
}
break;
Результат работы команды dr:
C:\sanix_2025>bc.bat Добро пожаловать в SanixOS v1.0 ? dr 12345678.123 0 21:14:46 BC.BAT 65 02:35:48 INTERP.CPP 3895 21:15:22 INTERP.EXE 17970 21:15:30 INTERP.OBJ 4215 21:15:30 README.DOC 1700 06:11:34 STARTUP.INT 39 02:50:26 TC0000.SWP 262144 21:15:28 TEST.INT 16 01:35:36 ?
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
Моя ФЛ Он и Она
Моя ФЛ Он и Она
NEW 06.04.25 13:18
в ответ uscheswoi_82 24.03.25 21:19
Продолжаю программировать командный интерпретатор. Улучшил код:
1.
#define OS_VERSION "1.0" #define FALSE 0 #define TRUE 1
2
int day; int month; int year;
3.
char *messages[] = {"Нет такого файла или команды.",
"Версия командного интерпретатора:"};
4.
case 3:
is_done = _dos_findfirst("*.*",_A_NORMAL,&ffblk);
while(!is_done) {
printf("%s", ffblk.name);
gotoxy(14, wherey());
printf("%ld", ffblk.size);
gotoxy(14 + 9, wherey());
convert_wrtime_to_hhmmss(ffblk.wr_time, &hours, &minutes, &seconds);
printf("d:d:d", hours, minutes, seconds);
gotoxy(14 + 9 + 9, wherey());
convert_wrdate_to_ddmmyyyy(ffblk.wr_date, &day, &month, &year);
printf("d:d:d\n", day, month, year);
is_done = _dos_findnext(&ffblk);
}
break;
5.
case 13:
// Выдаёт версию командного интерпретатора
printf("\n%s %s", messages[1], OS_VERSION);
break;
Результат работы программы:
C:\sanix_2025>INTERP.EXE Добро пожаловать в SanixOS v1.0 ? vr Версия командного интерпретатора: 1.0 ? dr !! 840 01:12:14 25:03:2025 12345678.123 0 22:14:46 24:03:2025 BC.BAT 65 03:35:48 22:03:2025 INTERP.CPP 4624 13:06:58 06:04:2025 INTERP.EXE 18444 13:07:04 06:04:2025 README.DOC 1700 07:11:34 26:02:2004 STARTUP.INT 39 03:50:26 22:03:2025 TEST.INT 16 02:35:36 24:03:2025 ?
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
Моя ФЛ Он и Она
Моя ФЛ Он и Она
NEW 06.04.25 13:20
в ответ uscheswoi_82 06.04.25 13:18
Ой ошибка, вот подправил:
printf("d.d.d\n", day, month, year);
Вот новый результат:
? dr !! 840 01:12:14 25.03.2025 12345678.123 0 22:14:46 24.03.2025 BC.BAT 65 03:35:48 22.03.2025 INTERP.BAK 4624 13:06:58 06.04.2025 INTERP.CPP 4624 13:18:40 06.04.2025 INTERP.EXE 18444 13:18:44 06.04.2025 INTERP.OBJ 4825 13:18:44 06.04.2025 README.DOC 1700 07:11:34 26.02.2004 STARTUP.INT 39 03:50:26 22.03.2025 TC0000.SWP 262144 13:18:26 06.04.2025 TEST.INT 16 02:35:36 24.03.2025
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
Моя ФЛ Он и Она
Моя ФЛ Он и Она
NEW 06.04.25 14:04
Для тестирования var.cpp:
#include <stdio.h>
#include <string.h>
int var_index=0; // Количество переменных
char var_name[20][10]; // Переменные, максимум до 20 переменных, длина имени переменной макс. 10 символов
char var_value[20][80]; // Значение переменных, максимум до 20 переменных, длина значения макс. 80 символов
// Создаёт переменную в памяти, и добавляет значение в памяти
void add_variable(char *name, char *value) {
strcpy(var_name[ var_index ], name); // Копирует имя переменной в массив
strcpy(var_value[ var_index ], value); // Копирует значение в переменной в массив
// Если переменные меньше 20, то можно добавлять новую переменную
if(var_index < 20) var_index ++ ;
}
// Ищет и возвращает адрес значения переменной
int get_value(char *name) {
int i;
// Ищет переменную name
for(i=0; i < var_index; i ++) {
if(strcmp(var_name[ i ], name) == 0) return i;
}
return -1; // Ошибка
}
int main(void) {
int i;
add_variable("VAR1", "HELLO WORLD"); // Добавляет новую переменную VAR1, и значение HELLO WORLD
i = get_value("VAR1"); // Ищет переменную VAR1, и возвращает адрес
if(i != -1) printf("%s", var_value[ i ]); // Если i не -1, то отображает значение переменной по этому адресу, т.е. по i
return 0;
}
Результат:
C:\sanix_2025>bc VAR.CPP HELLO WORLD
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
Моя ФЛ Он и Она
Моя ФЛ Он и Она
NEW 18.04.25 00:06
в ответ uscheswoi_82 06.04.25 14:04
Дальше доделал, очищает экран, вот код:
#define MAX_CMD 17
case 17: // Очищает экран clrscr(); break;
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
Моя ФЛ Он и Она
Моя ФЛ Он и Она
список