Code:
/* ls2.c
* version
* problem with division - when you divide two numbers
* to compile gcc -lm lsfixattempt.c -o lsfix
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <math.h>
void do_ls(char[]);
int get_screen_cols();
int cstring_cmp(const void *a, const void *b);
void print_files(char *files[], int numFiles, int colWidths[], int numRows);
void find_col_widths(char *files[], int numFiles);
void pause()
{
int c;
while((c = getchar()) != '\n' && c != EOF);
}
main(int ac, char *av[])
{
if(ac == 1)
{
do_ls(".");
}
else
{
while(--ac)
{
printf("%s:\n", *++av);
do_ls(*av);
}
}
}
int cstring_cmp(const void *a, const void *b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return strcmp(*ia, *ib);
}
void do_ls(char dirname[])
{
DIR *dir_ptr;
struct dirent *direntp;
int maxEntries = 20;
int index = 0;
char *entries[maxEntries];
if( (dir_ptr = opendir(dirname)) == NULL )
{
fprintf(stderr, "ls1: cannot open %s\n", dirname);
}
else
{
while( (direntp = readdir(dir_ptr)) != NULL )
{
if( (strcmp(direntp->d_name, ".") != 0) &&
(strcmp(direntp->d_name, "..") != 0) )
{
entries[index++] = direntp->d_name;
}
}
closedir(dir_ptr);
qsort(entries, (size_t)index, sizeof(char *), cstring_cmp);
printf("Index = %d\n", index);
find_col_widths(entries, index);
}
}
void find_col_widths(char *files[], int numFiles)
{
int lenArray[numFiles];
int testWidths[numFiles];
int avg = 0;
int i;
for(i=0; i<numFiles; i++)
{
testWidths[i] = 0;
lenArray[i] = strlen(files[i])+2;
// printf("lenArray[%d]: %d\n", i, lenArray[i]);
avg += lenArray[i];
}
avg = round(avg/i);
printf("avg = %d\n", avg);
//avg /= i;
int maxCol = get_screen_cols();
int numCol = round(maxCol/avg);
printf("maxCol is %d, numCol is %d\n", maxCol, numCol);
int numRows = round(numFiles/numCol)+1;
int testLen = 0;
int rowDir = 0;
int complete = 0;
int colIndex = 0;
while( !complete )
{
for(i=0; i<numFiles; i++)
{
if( (i%numRows == 0) && (i != 0) )
{
colIndex++;
}
if(testWidths[colIndex] < lenArray[i])
{
testWidths[colIndex] = lenArray[i];
printf("testWidths[%d]: %d\n", colIndex, testWidths[colIndex]);
}
}
colIndex = 0;
for(i=0; i<numFiles; i++)
{ printf("got heree\n");
testLen += testWidths[i];
printf("current testLen %d\n", testLen);
}
testLen = round(testLen);
printf("testLen: %d", testLen);
//pause();
if (testLen > maxCol)
{
printf("testLen > maxCol\n");
if(rowDir > -1)
{
// printf("rowDir > -1\n");
numRows++;
if(numRows >= numFiles)
{
complete = 1;
}
else
{
rowDir = 1;
}
}
else
{
// printf("rowDir == -1\n");
numRows++;
// complete = 1;
rowDir = 1;
}
}
else // testWidth < max num of columns
{
// printf("testLen < maxCol\n");
if(rowDir < 1)
{
// printf("rowDir > -1\n");
numRows--;
if(numRows < 0)
{
numRows = 1;
complete = 1;
}
else
{
rowDir = 1;
}
}
else
{
// printf("rowDir == 1\n");
complete = 1;
}
}
testLen = 0;
for(i=0; i<numFiles; i++)
{
testWidths[i] = 0;
}
// printf("rowDir = %d\nnumRows = %d", rowDir, numRows);
// pause();
}
colIndex = 0;
for(i=0; i<numFiles; i++)
{
if( (i%numRows == 0) && (i != 0) )
{
colIndex++;
}
if(testWidths[colIndex] < lenArray[i])
{
testWidths[colIndex] = lenArray[i];
// printf("testWidths[%d]: %d\n", colIndex, testWidths[colIndex]);
}
}
print_files(files, numFiles, testWidths, numRows);
}
void print_files(char *files[], int numFiles, int colWidth[], int numRows)
{
// printf("numRows: %d\n", numRows);
int whitespace, i, col, row;
col = 0;
row = 0;
while(row < numRows)
{
for(i=0; i<numFiles; i++)
{
if(i%numRows == row)
{
whitespace = colWidth[col] - strlen(files[i]);
printf("%s", files[i]);
while(whitespace > 0)
{
putchar(' ');
whitespace--;
}
col++;
}
}
row++;
col = 0;
putchar('\n');
}
}
int get_screen_cols()
{
struct winsize wbuf;
if( ioctl(0, TIOCGWINSZ, &wbuf) != -1 )
{
return wbuf.ws_col;
// printf("%d rows x %d cols\n", wbuf.ws_row, wbuf.ws_col);
// printf("%d wide x %d tall\n", wbuf.ws_xpixel, wbuf.ws_ypixel);
}
return 0;
}