Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Teach me to remove bloat!

Name: Anonymous 2010-02-24 0:34

Hey guys, I would like some pointer (no, not that kind) on removing bloat in code. Here is a fully functional piece of code that I wrote which I'm worried about bloat in. How do I shorten this?

int get_input()
{
    int count, paren_count, total_count, c;
    char *input, *temp;

    input = (char *) malloc (500 * sizeof (char));

    if (input == NULL) return 0;
    printf("%% ");
    for (count = paren_count = total_count = 0; (c = getchar()) != EOF; count++, input++, total_count++)
    {
        if (count == 499)
        {
            input -= total_count;
            temp = (char *) realloc (input, (500 + total_count) * sizeof (char));
            if (temp == NULL)
                return 0;
            input = temp;
            input += total_count;
        }
        if (c == '\n')
        {
            *input = '\0';
            temp = input;
            temp -= (count);
            count = 0;
            for (; *temp != '\0'; temp++)
            {
                if (*temp == '(')
                    paren_count++;
                else if (*temp == ')')
                    paren_count--;
            }
            if (paren_count == 0)
                break;
            printf("  ");
        }
        *input = c;
    }
    *temp = '\0';
    input -= total_count;
    printf("%s\n", input);
    free(input);
    return 0;
}

Name: Anonymous 2010-02-24 0:42

here, OP, let me help you with the first step:


int get_input()
{
    int count, paren_count, total_count, c;
    char *input, *temp;

    input = (char *) malloc (500 * sizeof (char));

    if (input == NULL) return 0;
    printf("%% ");
    for (count = paren_count = total_count = 0; (c = getchar()) != EOF; count++, input++, total_count++)
    {
        if (count == 499)
        {
            input -= total_count;
            temp = (char *) realloc (input, (500 + total_count) * sizeof (char));
            if (temp == NULL)
                return 0;
            input = temp;
            input += total_count;
        }
        if (c == '\n')
        {
            *input = '\0';
            temp = input;
            temp -= (count);
            count = 0;
            for (; *temp != '\0'; temp++)
            {
                if (*temp == '(')
                    paren_count++;
                else if (*temp == ')')
                    paren_count--;
            }
            if (paren_count == 0)
                break;
            printf("  ");
        }
        *input = c;
    }
    *temp = '\0';
    input -= total_count;
    printf("%s\n", input);
    free(input);
    return 0;
}

Name: Anonymous 2010-02-24 1:30

Use a better language, I guess.

(defun get-input (&optional (stream *terminal-io*))
  (with-output-to-string (input)
    (prog (i (p 0))
     loop
     (setf i (read-line stream nil nil)
           p (+ p (count-parens i)))
     (write-string i input)
     (if (or (null i)
             (zerop p))
         (return)
         (go loop)))))

(defun count-parens (string)
  (loop for x across string
     summing (case x
               (#\( 1)
               (#\) -1)
               (t 0))))

Name: Anonymous 2010-02-24 1:37

>>3
I'm trying to write the shell for an interpreted language, it wouldn't make much sense to write it in another interpreted language.

Name: Anonymous 2010-02-24 2:16

int getInput() {
    int size = 500, count = 0;
    char* input = malloc(size * sizeof(char)), c;
    printf("%% ");
    for(;(c=getchar())!=EOF; ++count) {
        if(count>=size-1) {
            size *= 2;
            input = realloc(input, size * sizeof(char));
        }
        input[count] = c;
        if(c=='\n') {
            input[count+1]='\0';
            if(!countParens(input)) break;
            printf("  ");
        }
    }
    input[count] = '\0';
    printf("%s\n", input);
    free(input);
    return 0;
}
int countParens(const char* s) {
    int n = 0;
    for(;*s;s++) n += *s=='('?1:*s==')':-1:0;
    return n;
}

Name: Anonymous 2010-02-24 2:23

>>4
Then you need more FIOC.

Name: Anonymous 2010-02-24 3:23

>>4
Lisp ... interpreted
Wut.

Name: Anonymous 2010-02-24 3:50

This must be a troll. Your program is a borderline IOCCC case. Read K&R.

Name: Anonymous 2010-02-24 3:53

>>5
Your unidiomatic use of for loops makes me sick.

Name: Anonymous 2010-02-24 6:01

UNTeSTED


int get_input() {
    int n,p,t,c;
    char *inp,*tmp;

    if(!(inp=malloc(500))
      return 0;

    printf("%% ");
    for(n=p=t=0;(c=getchar())!=EOF;n++,inp++,t++) {
        if(count==499) {
            inp -= t;
            if(!(tmp=realloc(inp,500+t))
              return 0;
            inp = tmp + t;
        }
        if(c=='\n') {
            *input = 0;
            tmp = inp;
            tmp -= n;
            n = 0;
            for(;*tmp!='\0';tmp++)
                p+=(*tmp=='(')?1:((*tmp==')')?-1:0);
            if(!p)
                break;
            printf("  ");
        }
        *inp = c;
    }
    *tmp = 0;
    inp -= t;
    printf("%s\n",inp);
    free(inp);
    return 0;
}

Name: Anonymous 2010-02-24 6:40

First of all, remove all the useless white spaces. Also change all of your variable names to shorter ones.

int get_input(){int u,p,t,c;char *i,*m;i=(char*)malloc(500*sizeof(char));if(i==NULL)return 0;printf("%% ");for(u=p=t=0;(c=getchar())!=EOF;u++,i++,t++){if(u==499){i-=t;m=(char*)realloc(i,(500+t)*sizeof(char));if(m==NULL)return 0;i=m;i+=t;}if(c=='\n'){*i='\0';m=i;m-=(u);u=0;for(;*m!='\0';m++){if(*m=='(')p++;else if(*m==')')p--;}if(p==0)break;printf("  ");}*i=c;}*m='\0';i-=t;printf("%s\n",i);free(i);return 0;}

ENTERPRISE QUALITY OMPIMIZATION

Name: Anonymous 2010-02-24 7:05

>>11
FrozenVoid Quality.

Name: Anonymous 2010-02-24 7:05

>>11
ZOMG OPTIMISED
#define return R
#define printf P
int g(){int u,p,t,c;char *i,*m;i=(char*)malloc(500*sizeof(char));if(i==0)R 0;P("%% ");for(u=p=t=0;(c=getchar())!=-1;u++,i++,t++){if(u==499){i-=t;m=(char*)realloc(i,(500+t)*sizeof(char));if(m==0)R 0;i=m;i+=t;}if(c=='\n'){*i='\0';m=i;m-=(u);u=0;for(;*m!='\0';m++){if(*m=='(')p++;else if(*m==')')p--;}if(p==0)break;P("  ");}*i=c;}*m='\0';i-=t;P("%s\n",i);free(i);R 0;}

Name: Anonymous 2010-02-24 7:16

>>13
You should move the lines
#define return R
#define printf P


to your void.h file.

Name: Anonymous 2010-02-24 7:26

>>14
I nearly spit my juice[1] on the keyboard.

--------------------------------
1- On the left in this image: http://www.kagome.co.jp/news/2008/images/090108001.jpg - pretty tasty

Name: Anonymous 2010-02-24 7:29

>>14
If we are going to allow modifications we could add a lot more to it
#define GC getchar
#define C  char
#define M  malloc
#define SO sizeof
#define RA realloc
#define I  int
#define B  break
#define F  free
#define P  printf
#define R  return
#define Q  if
#define EF else if
#define FR for

and then have
I g(){I u,p,t,c;C *i,*m;i=(C*)M(500*SO(C));Q(i==0)R 0;P("%% ");FR(u=p=t=0;(c=GC())!=-1;u++,i++,t++){Q(u==499){i-=t;m=(C*)RA(i,(500+t)*SO(C));Q(m==0)R 0;i=m;i+=t;}Q(c=='\n'){*i='\0';m=i;m-=(u);u=0;FR(;*m!='\0';m++){Q(*m=='(')p++;EF(*m==')')p--;}Q(p==0)B;P("  ");}*i=c;}*m='\0';i-=t;P("%s\n",i);F(i);R 0;}

Thne we should replace everything that is >1 letter long with a single character.

Name: Anonymous 2010-02-24 7:30

>>16
s/modifications/modifications to void.h/

Name: Anonymous 2010-02-24 7:33

>>16
it's almost as unreadable as perl

Name: Anonymous 2010-02-24 7:36

>>16
;_; even FV didn't use one char identifiers. This hurts my eyes.

Name: Anonymous 2010-02-24 10:13

>>16
If we allow a header file we could even OMPTIMIZE even further:

h.h
#define GC getchar
#define C  char
#define M  malloc
#define SO sizeof
#define RA realloc
#define I  int
#define B  break
#define F  free
#define P  printf
#define R  return
#define Q  if
#define EF else if
#define FR for
#define G  I g(){I u,p,t,c;C *i,*m;i=(C*)M(500*SO(C));Q(i==0)R 0;P("%% ");FR(u=p=t=0;(c=GC())!=-1;u++,i++,t++){Q(u==499){i-=t;m=(C*)RA(i,(500+t)*SO(C));Q(m==0)R 0;i=m;i+=t;}Q(c=='\n'){*i='\0';m=i;m-=(u);u=0;FR(;*m!='\0';m++){Q(*m=='(')p++;EF(*m==')')p--;}Q(p==0)B;P("  ");}*i=c;}*m='\0';i-=t;P("%s\n",i);F(i);R 0;}


whatever.c
#include "h.h"

G

Name: Anonymous 2010-02-24 10:39

>>20
 ______
[ul](-_ -  )[/ul]

Name: Anonymous 2010-02-24 10:45

>>8
I'm not, and I already have. The plan was to get this to work first and then clean it up.
>>5
Input = realloc (input,...)
Realloc isn't gauranteed to work fool.

Name: Anonymous 2010-02-24 10:49

>>22
GUARANTEE MY ANUS

Name: Senior Anonix Developer 2010-02-24 11:14

>>5 uses exponential instead of linear allocation
>>10 didn't change much
>>11,13,16,20 IOCCC'd versions of OP

int get_input() {
 int len = 0, ulen = 0, pc = 0;
 char *input = 0, c;
 printf("%% ");
 while((c=getchar())!=EOF) {
  if(ulen>=len) {
   input = realloc(input,len+=500);
   if(!input)
    return 0;
  }
  if(c=='\n')
   if(pc)
    putchar(' ');
   else {
    input[ulen++] = 0;
    break;
   }
  else
   pc += (c=='(')?1:(c==')')?-1:0;
  input[ulen++] = c;
 }
 puts(input?input:"");
 free(input);
 return 0;
}


If you replace the putchar(' ') with printf("%*c",pc,' '), you get auto-indentation too.

Name: Anonymous 2010-02-24 11:37

You could start by using comments...

Name: Anonymous 2010-02-24 12:19

Congratulations.  We've taken a very modest function and rendered it illegible.

Name: Anonymous 2010-02-24 12:41

int get_input(void) {
  char* input;      
  int c, n, parens; 
  int incr = 500;   

  // get a buffer for storage
  if (!(input = (char*) malloc(incr)))
    return -1;                       
  n = parens = 0;                    

  // read until EOF or newline with balanced parens
  printf("%% ");                                  
  while ((c = getchar()) != EOF) {                
    if (c == '\n' && parens <= 0)                 
      break;                                      
    input[n++] = c;                               

    // handle parens
    if (c == '(')  
      ++parens;    
    else if (c == ')')
      --parens;      

    // grow buffer
    if (n % incr == 0)
      if (!(input = (char*) realloc(input, n + incr)))
        return -1;                                   
  }                                                  

  // done
  input[n] = 0;
  if (c == EOF) printf("\n");
  printf("%s\n", input);    
  free(input);              
  return c == EOF ? -1 : 0; 
}


- pulls out increment as a constant
- returns -1 on failure (you were returning 0 everywhere for some reason)
- checks for end of file (ctrl+d or closed pipe)
- checks for too many closing parens
- adds CODE COMMENTS, so you can actually see what's going on

Name: Anonymous 2010-02-24 12:44

>>27
- also, doesn't fuck around with your input pointer, so you can use it with garbage collectors and other analysis tools. It's a little scary that OP doesn't keep a fixed pointer to the start of the buffer.

Name: Anonymous 2010-02-24 13:24

>>28
fag

Name: Anonymous 2010-02-24 14:04

is this a side effect generator?

Name: Anonymous 2010-02-24 14:14

>>26

illegible
Isn't it the real point of /prog/?

Name: GRUNNUR 2010-02-24 14:16

GRUNNUR

Name: Anonymous 2010-02-24 17:24

>>25
You seriously need comments to understand this?

Name: Anonymous 2010-02-24 17:25

This does a lot more than you want it to do, but it's more generic:
(read)

Name: Anonymous 2010-02-24 17:56

>>22
You think I give a shit if realloc works or not? You think his program is going to be able to gracefully degrade if it runs out of memory? Get the fuck out with your useless pedantry.

Name: Anonymous 2010-02-24 18:24

>>35
My program? Frankly, I like protection.
Anyway today I fixed the bloat issue. I'll post it later for show.

Name: Anonymous 2010-02-24 18:42

>>36
Those who give up efficiency for security deserve neither.

Name: Anonymous 2010-02-24 19:04

>>37
Okay here's the thing: I am writing an interpreted programming language, this function is part of the shell.
God damn, I need to free all of the memory in the linked list before it exits, or else bad things will happen, and you know it.

Name: Anonymous 2010-02-24 19:14

>>38
Why don't you just write it in a higher level language? Until you have it working, worrying about efficiency is a waste.

Name: Anonymous 2010-02-24 19:50

>>39
I hate higher level languages in general (save for languages like scheme and perl), plus the linked lists are so much easier in C. And you're right, worrying about efficiency in the beginning is stupid, I was just saying how safety is necessary for what I'm doing.

Any way, here's my fixed version. Sorry if I don't get the bbcode right

int get_input()
{
    int count, post_count;
    char *input = NULL, *temp, c;

    printf("%% ");
    for (count = 0; (c = getchar()) != EOF; count++)
    {
        if (count % 500 == 0)
        {
            if ((temp = (char *) realloc (input, (500 + count) * sizeof (char))) == NULL)
            {
                free (input);
                return 2;
            }
            input = temp;
        }
        input[count] = c;
        if (c == '\n')
        {
            input[count + 1] = '\0';
            temp = input;
            post_count = 0;
            while (*temp != '\0')
            {
                if (*temp == '(')
                    post_count++;
                else if (*temp == ')')
                    post_count--;
                temp++;
            }
            if (post_count > 0)
                printf("  ");
            else
                break;
        }

    }
    printf("%s\n", input);
    free(input);
    return 0;
}

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List