LINUX.ORG.RU

Быдлокод не быдлокод?

 ,


1

2

Тривиальный код, только начал и тут подумал, а может я быдлокодер ::). Если да, то почему?

На русские буковки ниже внимания не обращаем, это временно. В остальном можете конструктивно и обоснованно закидать какашками/тапками/помидорами.

Смысл поста? Нуу не знаю, может кто чего полезного скажет.

/**--------------------------------------------------------------------------**/
/**----------------------------HIMERA CORE-----------------------------------**/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/*enum { TRUE, FALSE }; ::) */  

enum { FALSE, TRUE };

enum { SECTION_START,
       SECTION_END,
       SECTION_NAME_START,
       SECTION_NAME_END,
       KEY_START,
       KEY_END,
       VALUE_START,
       VALUE_END
     };

/*  defauil style  */
char himera_style[]= {'{', '}', '(', ')', '[', ']', '(', ')' };

/*  default events  */
enum { EVENT_OPEN_SECTION,
       EVENT_CLOSE_SECTION,
       EVENT_OPEN_SETION_NAME,
       EVENT_CLOSE_SECTION_NAME,
       EVENT_OPEN_KEY,
       EVENT_CLOSE_KEY,
       EVENT_OPEN_VALUE,
       EVENT_CLOSE_VALUE,
       EVENT_NULL
     };
unsigned int himera_event_status=EVENT_NULL;


enum { FILE_OPEN, FILE_CLOSE};
static unsigned int himera_file_status=FILE_CLOSE;
static FILE *himera_file_point=NULL;


#define MAX_LEN_NAME_FILE 1024
static char himera_file_name[MAX_LEN_NAME_FILE];


static char * himera_file_ram=NULL;
unsigned int ramstatus=FALSE;



/* open file, save name file, save point file
 * himerafile: output to file
 *
 * FIXME: тут надо переоткрывать файл и уведомлять об этом
 *        это если по хорошему. Ане кричать что он уже открыт.
 */
void himeraopen(const char * himerafile)
{

    if(himera_file_status==FILE_CLOSE)
    {
        FILE *himerapoint;

        if((himerapoint=fopen(himerafile,"r"))==NULL)
        {
            printf("[ERROR] Нет такого файла!\n");
            exit(1);
        };
        printf("[INFO] Открытие фалла [%s]\n",himerafile);
        himera_file_point=himerapoint;
        himera_file_status=FILE_OPEN;

        for(int i=0; himerafile[i]!='\0'; i++)
        {
            if(i>MAX_LEN_NAME_FILE)
            {
                printf("[ERROR] Длинна имени файла больше MAX_LEN_NAME_FILE\n");
                fclose(himerapoint);
                exit(1);
            };
        };

        memset(himera_file_name, 0, sizeof(himera_file_name));
        strcpy(himera_file_name,himerafile);

    }
    else
    {
        if(!(strcmp(himerafile,himera_file_name)))
        {
            printf("[WARNING] этот файл уже открыт, ничего не будет сделанно\n");
            return;
        };

        printf("[INFO] закрытие старого файла\n");

        fclose(himera_file_point);
        himera_file_status=FILE_CLOSE;
        memset(himera_file_name, 0, sizeof(himera_file_name));

        printf("[INFO] освобождение ресурсов\n");

        free(himera_file_ram);
        ramstatus=FALSE;
        himera_file_ram=NULL;

        printf("[INFO] открытие нового файла \n");

        himeraopen(himerafile);



    };


}

/* print himerafile on stdio
 * print sample information himerafile
 */
void himeracat(void)
{

    if(himera_file_status==FILE_CLOSE)
    {
        printf("[WARNING] нет открытого файла \n");
        exit;
    };

    char ch;
    long long int strcount=1;
    long long int chcount;
    printf("\n**********************************\n");
    printf("[INFO] Файл на носителе file:[%s]",himera_file_name);
    printf("\n**********************************\n1: ");
    for(long long int j=0; (ch=fgetc(himera_file_point))!=EOF; chcount=++j)
    {
        printf("%c",ch);
        if(ch=='\n')
        {
            printf("%lld: ",++strcount);
        };
    };
    printf("\n**********************************\n");
    printf("lines: [%lld] chars [%lld]",strcount,chcount);
    printf("\n**********************************\n");

    /*---------------------------------------------------------------------*/
    if(ramstatus==TRUE)
    {
        char ch;
        long long int strcount=1;
        long long int chcount;
        printf("\n**********************************\n");
        printf("[INFO] Файл в памяти file:[%s]",himera_file_name);
        printf("\n**********************************\n1: ");
        for(long long int j=0; (ch=fgetc(himera_file_ram))!=EOF; chcount=++j)
        {
            printf("%c",ch);
            if(ch=='\n')
            {
                printf("%lld: ",++strcount);
            };
        };
        printf("\n**********************************\n");
        printf("lines: [%lld] chars [%lld]",strcount,chcount);
        printf("\n**********************************\n");
    };
    /*---------------------------------------------------------------------*/
}

/*загружает весь файл в память*/
void himeraload(void)
{

    if(ramstatus==TRUE)
    {
        /*  printf("[WARNING] попытка повторной загрузки, файл уже загружен!\n");
            return;
        */
        printf("[INFO] обновление копии файла в памяти\n");
        free(himera_file_ram);
        ramstatus=FALSE;
        himera_file_ram=NULL;
    };

    setbuf(stdout,NULL);
    printf("[INFO] загрузка файла [%s] старт \n",himera_file_name);

    /* узнаём размер файла */
    int size_file=0;
    for(long long int count=0; fgetc(himera_file_point)!=EOF; size_file=++count);



    /* выделяем память под файл*/
    himera_file_ram = calloc(size_file, sizeof(int));/* FIXME: int vs char? */

    if(himera_file_ram=NULL)
    {
        printf("Ошибка при распределении памяти\n");
        exit(1);
    }

    /*копируем файл в память*/
    int ch,count=0;
    while((ch=fgetc(himera_file_point))!=EOF)
    {
        himera_file_ram[count]=ch;
    };
    printf("[INFO] загрузка файла [%s] загруженно \n",himera_file_name);

    ramstatus=TRUE;
}

/*сохраняет текущий открытый изменённый файл на носитель*/
//himerasave()
/*находит искомую секцию или ключ */
//himeragrep()
//himeratype()


void himeraget_int(int * var,const char  section, const char key)
{

};

void himeraget_float(float * var,const char  section, const char key)
{

};

void himeraget_char(char * var,const char  section, const char key)
{

};


/*free resource and exit himera*/
void himeraclose(void)
{

    printf("[INFO] освобождение ресурсов \n");

    fclose(himera_file_point);
    himera_file_status=FILE_CLOSE;
    memset(himera_file_name, 0, sizeof(himera_file_name));
    free(himera_file_ram);
    ramstatus=FALSE;
    himera_file_ram=NULL;
}
★★★★★

статические массивы данных это прямо какойто кусок баунти-расйкого-наслаждения, или даже куча этого наслаждения потом в этом ковыряться.

Deleted ()

';' после '}' умиляют. И chimera, епт.

Код неряшливый, стиль ублюдочный, но ничего слишком быдло- я не вижу.

tailgunner ★★★★★ ()

enum { TRUE, FALSE };

Я что-то не понимаю или:

int x=FALSE;
if(x)
 BOOM();
staseg ★★★★★ ()

простыня знатная :-)

код-то хоть рабочий ? если работает и память не течёт, то всё нормально - твори дальше

MKuznetsov ★★★★★ ()
enum { TRUE, FALSE };

ага

int TRUE = 0, FALSE = 1;

а потом где-нибудь

int val = TRUE;
...
if(val){
  // гыгыгы
}
Eddy_Em ☆☆☆☆☆ ()
enum { TRUE, FALSE };

Что это? Может, наоборот? Дальше не читал.

Упс, Эдди опередил.

HerrWeigel ★★★★ ()
Последнее исправление: HerrWeigel (всего исправлений: 1)

может stdbool будешь использовать?

dimon555 ★★★★★ ()

заведи что ли какой макрос LOG_INFO, LOG_WARN

dimon555 ★★★★★ ()

статика - плохо. strcpy - плохо. exit(1) - плохо, метод всегда знает реакцию на отсутствие файла? всегда возвращали код ошибки и вызывающая сторона решает чего делать. ошибки/предупреждения должны писаться в stderr, info в stdout. по хорошему должно отключаемо. про true/false уже сказали.

а файлик

/home/vitus/моя любимая;папка&/документ^&.txt
откроет нормально?

vtVitus ★★★★★ ()

if(himera_file_ram=NULL)

if(himera_file_ram == NULL)

dimon555 ★★★★★ ()
Ответ на: комментарий от vtVitus

статика - плохо

Почему же?

strcpy - плохо

Чем?

exit(1) плохо

тут согласен, но это потом.

по хорошему должно отключаемо

да, но это тоже потом.

откроет нормально?

dron@gnu:~/проекты/himera$ make
cc -std=c99   -c -o test.o test.c
cc   himera.o test.o   -o himera
dron@gnu:~/проекты/himera$ ./himera 
[INFO] Открытие фалла [/home/dron/моя любимая;папка&/документ^&.txt]

**********************************
[INFO] Файл на носителе file:[/home/dron/моя любимая;папка&/документ^&.txt]
**********************************
1: hello vtVitus!
**********************************
lines: [1] chars [12]
**********************************
[INFO] освобождение ресурсов 
dron@gnu:~/проекты/himera$ 

Dron ★★★★★ ()

himeraopen вызывается рекурсивно, это то что нужно?

p.s. всё устал без редактора, а загружать текст влом.

dimon555 ★★★★★ ()
Ответ на: комментарий от Dron

хотя бы в том, что у тебя count long long int, а file_size int легко может переполнится.

dimon555 ★★★★★ ()
Ответ на: комментарий от dimon555

himeraopen вызывается рекурсивно, это то что нужно?

Ага.

Dron ★★★★★ ()

ещё можешь попробовать скомпилировать с -Wall и запустить под valgrind

а так же использовать linux/limits.h для MAX_PATHNAME

dimon555 ★★★★★ ()
Ответ на: комментарий от dimon555

Ну да в принципе, тут в динамике надо выделять память «под всё».

Просто привык сначала писать прототип что-бы просто работало (шаг в лево шаг в право расстрел ;) ), а потом уже допиливать отказоустойчивость.

Dron ★★★★★ ()
Ответ на: комментарий от dimon555

ещё можешь попробовать скомпилировать с -Wall

Поправил код

dron@gnu:~/проекты/himera$ make
clang -std=c99 -Wall -pedantic   -c -o himera.o himera.c
clang -std=c99 -Wall -pedantic   -c -o test.o test.c
clang   himera.o test.o   -o himera
dron@gnu:~/проекты/himera$ 
-Wall -pedantic надо всегда использовать, а пока линейкой мне по ,,,.

valgrind

Не разу не использовал, надо попробовать.

linux/limits.h для MAX_PATHNAME

Да.

Dron ★★★★★ ()
Ответ на: комментарий от Dron

strcpy - плохо

Чем?

Это потенциальная уязвимость, на вход могут прийти данные, которые вызовут переполнение буфера, например, из-за того, что где-то потерян терминирующий ноль. Если мне не изменяет память, strcpy is deprecated, надо использовать strncpy.

hippi90 ★★★★ ()
Ответ на: комментарий от hippi90

Если мне не изменяет память, strcpy is deprecated, надо использовать strncpy.

Ничего подобного! Если у тебя строка не null-terminated, с ней libc работать не будет!

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Ничего подобного! Если у тебя строка не null-terminated, с ней libc работать не будет!

Она будет с ней работать ровно до тех пор, пока не встретит нулевой символ, либо не вызовет ошибку сегментации.

hippi90 ★★★★ ()
Ответ на: комментарий от Eddy_Em

:) с gcc да c clang нет

/*file test.c*/
#include <stdio.h>
#include <string.h>

int main(void)
{

    char  buff[10];
    char  str[]={'0','1','2','3','4','5','6','7','8','9','1'};

    strcpy(buff,str);
    printf("%s\n",buff);

	return 0;
}

Выхлоп:

dron@gnu:~/проекты/scripts$ gcc test.c
dron@gnu:~/проекты/scripts$ ./a.out 
01234567891
dron@gnu:~/проекты/scripts$ clang test.c
dron@gnu:~/проекты/scripts$ ./a.out 
Ошибка сегментирования
dron@gnu:~/проекты/scripts$ 

Dron ★★★★★ ()

Из рогатки за такой код надо убивать. Да, быдлокод. И, как понимаю, не весь. Опасный. Без стиля. Со связностью.

А еще русиш грамманаци жаждет живительного граммакоста над тобой отдельно взятым индивидом.

Почему логирование не из одной точки ведешь и нафига в лог эти сраные лишние линии пихаешь?

Попутно по треду выявились еще быдлокодеры, нашедшие этот кусок... кода нормальным. Рекомендую им почитать творения диджея МС Коннелла.

d_Artagnan ★★ ()
Ответ на: комментарий от hippi90

Ну тут без разницы, так как перед strcpy всё равно стоит проверка, и она там должна быть, а strncpy просто включает проверку в себя. Получается двойная проверка. Плюс проверять до strcpy в том что копироваться ничего не будет, в данном случае мне это и не надо (нафига мне обрезанный путь до файла?).

strncpy удобно если там скопировать первые n символов и тому подобное.

Обрезанные данные с strncpy могут нанести ещё пущий вред чем вылет по ошибке сегментирования.

strncpy тоже не идеальна, что-бы она должным образом работала и буфер надо на 1 убавить передавая ей размер, да и по стандарту она не гарантирует что вставит '\0' это подразумевается будет делаться руками.

gcc '\0' ставит даже для strcpy не спрашивая.

Dron ★★★★★ ()
Последнее исправление: Dron (всего исправлений: 1)

Что за слово такое «himera»? Ты не «chimera» имел в виду?

anonymous ()
Ответ на: комментарий от Deleted

Вот не надо ля-ля. Посмотри на код qemu, там все на статических массивах построено, и это, прикинь, реально красиво.

anonymous ()
Ответ на: комментарий от slackwarrior

Смешивать три языка - это уже перебор. Двух достаточно, а лучше вообще один (за комментарии на русском надо ссаной тряпкой по хлебалу хлестать).

anonymous ()
Ответ на: комментарий от dimon555

if(himera_file_ram=NULL)

if(himera_file_ram == NULL)

if(NULL == himera_file_ram)

anonymous ()

enum { FALSE, TRUE };

Используйте stdbool.h, чтобы не плодить лишних сущностей.

akk ★★★★★ ()
Ответ на: комментарий от anonymous

за комментарии на русском надо ссаной тряпкой по хлебалу хлестать

Залогинься, быдлокодер!

anonymous ()
Ответ на: комментарий от Dron

В обоих случаях ты вылез за выделенную память, это и есть уязвимость.

POLTER ★★ ()

Глобальных переменных лучше избегать. Вместо префикса himera_ создай структуру с таким именем, и гоняй её по функциям. И уж точно не надо делать enum, define и объявления глобальных переменных вперемешку.

yauzahvi ()
Ответ на: комментарий от yauzahvi

Глобальных переменных лучше избегать.

Нормально, они глобальны в пределах модуля, static просто не везде расставил.

Dron ★★★★★ ()
Ответ на: комментарий от POLTER

В обоих случаях ты вылез за выделенную память, это и есть уязвимость.

Там как бэ это намеренно сделано :)

Я Эдику просто показал что clang и gcc ведут себя по разному в отношении авто-вставки '\0';

Dron ★★★★★ ()
Ответ на: комментарий от yauzahvi

И уж точно не надо делать enum, define и объявления глобальных переменных вперемешку.

Они логически связанны, разделение будет потом как только их не надо будет добавлять. А пока удобней так.

Вместо префикса himera_ создай структуру с таким именем, и гоняй её по функциям.

У меня мания на префиксы, да :) ничего не могу с собой поделать.

Dron ★★★★★ ()
Ответ на: комментарий от akk

За такое убивать.

Да вы что, ваши варианты?

false ★★★★★ ()
Ответ на: комментарий от anonymous

Смешивать три языка - это уже перебор. Двух достаточно

Ъ-термины обычно греко-латинские. А еще при этом норот родным языком пользуется.

slackwarrior ★★★★★ ()

Я так и не понял, почему должен уделять этому хоть какое-то внимание.

Хотя и уделил, написав этот коммент ;)

hvatitbanit ()
Ответ на: комментарий от Dron

Нормально, они глобальны в пределах модуля, static просто не везде расставил.

Ненормально. Глобальные переменные не дадут модулю реентерабельность, многопоточность и много чего другого. И нет необходимости их использовать, даже если с этим конкретным модулем «такое никогда-никогда не понадобится». Иногда бывает, что таки надобится. Почему бы любой модуль не писать сразу нормально? Вобщем, ты спросил насчёт быдлокожести, а я тебе отвечаю, что таки да, это лютый-бешеный быдлокод в самом извращённом его виде. И твои попытки отмазаться тем, что «быдлокод это нормально» в этом контексте выглядят странно и нелепо.

Они логически связанны, разделение будет потом как только их не надо будет добавлять. А пока удобней так.

Всё в мире логически связано, но это не причина мешать всё в одну кучу. Если это временно, это ещё можно понять, но нельзя выставлять такой код на всеобщее обозрение. Кто-то может не вытерпеть и поотрывать тебе кое-что чтобы впредь неповадно было.

У меня мания на префиксы, да :) ничего не могу с собой поделать.

Это не страшно, а порой даже неплохо. Но в этом конкретном случае лучше поместить всё в структуру.

yauzahvi ()
Ответ на: комментарий от dimon555

я для этого целый класс написал, но здесь не плюсы.

WRG ★★★★ ()
Ответ на: комментарий от Dron

Тебе просто повезло, что в конце массива был ноль.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.