2017-05-28 14:35:35 +00:00
// Created by Arthur Amalvy
2017-05-15 12:32:41 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <dirent.h>
2017-05-16 05:32:19 +00:00
# include <string.h>
2017-05-15 12:32:41 +00:00
# include "fish_core.h"
# include "fish_globbing.h"
2017-05-16 05:32:19 +00:00
WordList * fishExpand ( WordList * wordList ) {
2017-05-15 12:32:41 +00:00
2017-06-13 09:13:06 +00:00
if ( wordList - > size > 1 ) {
2017-05-15 12:32:41 +00:00
2017-06-13 09:13:06 +00:00
int i ;
WordList * newWordList = createWordList ( ) ; // creating the list to return
2017-05-15 12:32:41 +00:00
2017-06-13 09:13:06 +00:00
if ( newWordList = = NULL ) { //crash when the allocation is unsuccessful
crash ( ) ;
2017-05-27 15:36:55 +00:00
}
2017-05-16 05:32:19 +00:00
2017-05-27 15:36:55 +00:00
addEndWordList ( newWordList , wordList - > first - > word ) ; //copy the command into the returning word list
2017-05-16 05:32:19 +00:00
2017-06-13 09:13:06 +00:00
WordListElement * tempElement = wordList - > first - > next ; //temporary nav element
2017-05-16 05:32:19 +00:00
2017-06-13 09:13:06 +00:00
for ( i = 1 ; i < wordList - > size ; i + + ) {
2017-05-16 05:32:19 +00:00
2017-05-27 15:36:55 +00:00
//TODO : optimize the stringContains() function to test for a list of characters
//test if we have to expand a string or not, for optimization purposes
if ( stringContains ( tempElement - > word , ' * ' ) | | stringContains ( tempElement - > word , ' ? ' ) ) {
2017-05-16 05:32:19 +00:00
2017-05-27 15:36:55 +00:00
concatWordList ( newWordList , expandWord ( tempElement - > word ) ) ;
2017-05-16 05:32:19 +00:00
2017-05-27 15:36:55 +00:00
}
//If we dont have to expand, add the current word unchanged to the new list
else {
addEndWordList ( newWordList , tempElement - > word ) ;
}
2017-05-16 05:32:19 +00:00
2017-06-13 09:13:06 +00:00
tempElement = tempElement - > next ;
2017-05-16 05:32:19 +00:00
2017-06-07 15:58:44 +00:00
2017-05-27 15:36:55 +00:00
}
freeWordList ( wordList ) ;
2017-05-29 13:19:52 +00:00
//TODO : move this in recursion in case multiples commands are in the same line
if ( newWordList - > size = = 1 ) {
addEndWordList ( newWordList , ( char * ) ERROR_STRING ) ;
}
2017-06-13 09:13:06 +00:00
return newWordList ;
2017-05-27 15:36:55 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-16 05:32:19 +00:00
2017-05-28 15:25:04 +00:00
else return wordList ;
2017-05-15 12:32:41 +00:00
2017-05-27 15:36:55 +00:00
}
2017-05-16 05:32:19 +00:00
2017-05-30 09:31:00 +00:00
WordList * expandWord ( char * path ) {
2017-05-16 05:32:19 +00:00
2017-05-30 09:31:00 +00:00
if ( ! stringContains ( path , ' / ' ) ) {
2017-05-28 15:25:04 +00:00
2017-05-30 09:31:00 +00:00
return getFiles ( ( char * ) " ./ " , path ) ;
2017-05-28 20:02:05 +00:00
}
else {
2017-05-30 09:31:00 +00:00
WordList * expandedList = createWordList ( ) ;
recursiveExpandWord ( path , expandedList ) ;
return expandedList ;
2017-05-29 13:19:52 +00:00
2017-05-30 09:31:00 +00:00
}
2017-05-29 15:25:31 +00:00
2017-05-30 09:31:00 +00:00
}
2017-05-29 15:25:31 +00:00
2017-05-30 09:31:00 +00:00
void recursiveExpandWord ( char * path , WordList * listToExpand ) {
2017-05-29 15:25:31 +00:00
2017-06-02 12:58:43 +00:00
2017-05-30 09:31:00 +00:00
int lastToExpand = 1 ;
int i = 0 ;
int indexToExpand = - 1 ;
WordList * pathToList = splitWordIntoList ( path , ' / ' ) ;
2017-06-02 11:43:31 +00:00
WordListElement * tempElement ; //beware of the size, should be checked before anyway (?)
2017-05-30 09:31:00 +00:00
tempElement = pathToList - > first ;
while ( i < pathToList - > size - 1 & & indexToExpand = = - 1 ) {
if ( stringContains ( tempElement - > word , ' * ' ) | | stringContains ( tempElement - > word , ' ? ' ) ) {
indexToExpand = i ;
lastToExpand = 0 ;
2017-05-29 15:25:31 +00:00
}
2017-05-30 09:31:00 +00:00
i + + ;
tempElement = tempElement - > next ;
}
if ( lastToExpand ) {
2017-06-06 08:37:58 +00:00
char * tmpPath = getPath ( path ) ;
char * tmpFileName = getFileName ( path ) ;
concatWordList ( listToExpand , getFiles ( tmpPath , tmpFileName ) ) ;
free ( tmpPath ) ;
free ( tmpFileName ) ;
freeWordList ( pathToList ) ;
2017-05-30 09:31:00 +00:00
}
else {
2017-06-02 11:43:31 +00:00
char * correctedPath = concatWordListToWord ( pathToList , 0 , indexToExpand + 1 ) ;
2017-06-06 08:37:58 +00:00
char * pathOfCorrectedPath = getPath ( correctedPath ) ;
char * fileNameOfCorrectedPath = getFileName ( correctedPath ) ;
WordList * foundFiles = getFiles ( pathOfCorrectedPath , fileNameOfCorrectedPath ) ;
char * tmpWord = NULL ;
free ( pathOfCorrectedPath ) ;
free ( fileNameOfCorrectedPath ) ;
free ( correctedPath ) ;
2017-05-30 09:31:00 +00:00
if ( foundFiles - > size > 0 ) {
tempElement = foundFiles - > first ;
2017-06-02 15:53:45 +00:00
char * concatenedEndOfPath = concatWordListToWord ( pathToList , indexToExpand , pathToList - > size - 1 ) ;
2017-06-07 15:58:44 +00:00
int isDir ;
2017-05-30 09:31:00 +00:00
2017-06-13 09:13:06 +00:00
for ( i = 0 ; i < foundFiles - > size ; i + + ) {
2017-05-30 09:31:00 +00:00
2017-06-13 09:13:06 +00:00
tmpWord = tempElement - > word ;
2017-06-07 15:58:44 +00:00
2017-06-13 09:13:06 +00:00
isDir = isDirectory ( tmpWord ) ;
2017-06-07 15:58:44 +00:00
2017-06-13 09:13:06 +00:00
tempElement - > word = trueStrcat ( tempElement - > word , concatenedEndOfPath ) ;
free ( tmpWord ) ;
tmpWord = NULL ;
if ( isDir ) {
recursiveExpandWord ( tempElement - > word , listToExpand ) ;
}
2017-05-30 09:31:00 +00:00
2017-06-13 09:13:06 +00:00
tempElement = tempElement - > next ;
2017-05-30 09:31:00 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-30 09:31:00 +00:00
free ( concatenedEndOfPath ) ;
}
freeWordList ( pathToList ) ;
freeWordList ( foundFiles ) ;
}
}
char * concatWordListToWord ( WordList * list , int firstElemIndex , int lastElemIndex ) {
if ( list - > size = = 0 | | list = = NULL ) crash ( ) ;
int i ;
char * concatenedString = ( char * ) malloc ( sizeof ( char ) ) ;
2017-06-07 15:58:44 +00:00
char * tmpConcatenedString = NULL ;
2017-05-30 09:31:00 +00:00
if ( concatenedString = = NULL ) crash ( ) ;
2017-06-02 11:43:31 +00:00
concatenedString [ 0 ] = ' \0 ' ;
2017-05-30 09:31:00 +00:00
if ( lastElemIndex > list - > size - 1 ) {
lastElemIndex = list - > size - 1 ;
2017-06-02 12:58:43 +00:00
fprintf ( stderr , " fish : Warning : you are a miserable failure, your element is beyond the list. pfff. I corrected it for you. \n " ) ;
2017-05-30 09:31:00 +00:00
}
if ( firstElemIndex > lastElemIndex ) {
firstElemIndex = lastElemIndex ;
2017-06-02 12:58:43 +00:00
fprintf ( stderr , " fish : Warning : how are you so bad ? your inferior index is superior to your superior index. pfff. I corrected it for you. \n " ) ;
2017-05-30 09:31:00 +00:00
}
WordListElement * tempElement = list - > first ;
for ( i = 0 ; i < firstElemIndex ; i + + ) {
tempElement = tempElement - > next ;
}
for ( i = firstElemIndex ; i < lastElemIndex ; i + + ) {
2017-05-29 15:25:31 +00:00
2017-06-07 15:58:44 +00:00
tmpConcatenedString = concatenedString ;
2017-06-02 11:43:31 +00:00
concatenedString = trueStrcat ( concatenedString , tempElement - > word ) ;
2017-06-06 08:37:58 +00:00
free ( tmpConcatenedString ) ;
2017-05-30 09:31:00 +00:00
tempElement = tempElement - > next ;
2017-05-28 20:02:05 +00:00
}
2017-05-28 15:25:04 +00:00
2017-05-30 09:31:00 +00:00
return concatenedString ;
2017-05-16 05:32:19 +00:00
2017-05-27 15:36:55 +00:00
}
2017-05-16 05:32:19 +00:00
2017-05-29 15:25:31 +00:00
char * getFileName ( char * string ) {
2017-05-16 05:32:19 +00:00
2017-06-06 08:37:58 +00:00
int wordSize = strlen ( string ) - 1 ;
2017-05-29 15:25:31 +00:00
if ( ! stringContains ( string , ' / ' ) ) {
return string ;
}
else {
2017-06-06 08:37:58 +00:00
int i = wordSize ;
2017-05-29 15:25:31 +00:00
while ( string [ i ] ! = ' / ' ) {
2017-06-06 08:37:58 +00:00
i - - ;
2017-05-29 15:25:31 +00:00
}
2017-06-13 09:13:06 +00:00
return strndup ( string + i + 1 , wordSize ) ;
2017-06-02 15:53:45 +00:00
2017-05-29 15:25:31 +00:00
}
2017-06-06 08:37:58 +00:00
2017-05-29 15:25:31 +00:00
}
//get path of a file
char * getPath ( char * string ) {
if ( ! stringContains ( string , ' / ' ) ) {
return string ;
}
else {
int i = strlen ( string ) - 1 ;
while ( i ! = - 1 & & string [ i ] ! = ' / ' ) {
i = i - 1 ;
}
return strndup ( string , i + 1 ) ;
}
}
2017-05-16 05:32:19 +00:00
2017-05-15 12:32:41 +00:00
2017-05-28 20:02:05 +00:00
WordList * getFiles ( char * path , char * wildcardedString ) {
2017-05-15 12:32:41 +00:00
2017-06-13 09:13:06 +00:00
DIR * directory ;
dirent * dir ;
2017-05-16 05:32:19 +00:00
2017-06-13 09:13:06 +00:00
WordList * files = createWordList ( ) ;
2017-05-29 15:25:31 +00:00
if ( files = = NULL ) crash ( ) ;
2017-05-15 12:32:41 +00:00
2017-06-13 09:13:06 +00:00
if ( ( directory = opendir ( path ) ) ! = NULL ) {
2017-05-15 12:32:41 +00:00
2017-06-13 09:13:06 +00:00
while ( ( dir = readdir ( directory ) ) ! = NULL ) {
2017-05-15 12:32:41 +00:00
2017-06-13 13:57:13 +00:00
if ( wildcardedString ! = NULL & & strcmp ( dir - > d_name , " . " ) & & strcmp ( dir - > d_name , " .. " ) & & wildcardedStringMatches ( wildcardedString , dir - > d_name ) ) { //sorry strcmp but I dont like you :(
2017-05-15 12:32:41 +00:00
2017-05-29 15:25:31 +00:00
char * filePath = trueStrcat ( path , dir - > d_name ) ;
2017-05-28 20:02:05 +00:00
addEndWordList ( files , filePath ) ;
free ( filePath ) ;
2017-05-15 17:10:46 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-28 14:35:35 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-15 12:32:41 +00:00
2017-05-28 15:25:04 +00:00
closedir ( directory ) ; //YY U LEAK MEMORY ? NOT ON MY WATCH
2017-05-15 12:32:41 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-15 12:32:41 +00:00
2017-06-13 09:13:06 +00:00
return files ;
2017-05-15 12:32:41 +00:00
}
2017-05-28 20:02:05 +00:00
2017-06-19 13:06:37 +00:00
int wildcardedStringMatches ( char * string1 , char * string2 ) {
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
int i = 0 ;
char tempIChar ;
int j = 0 ;
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
if ( string1 ! = NULL & & string2 ! = NULL ) {
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
while ( string1 [ i ] ! = ' \0 ' & & string2 [ j ] ! = ' \0 ' ) {
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
if ( string1 [ i ] = = ' * ' ) {
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
tempIChar = string1 [ i + 1 ] ;
if ( tempIChar = = ' \0 ' ) {
return 1 ;
}
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
while ( string2 [ j ] ! = tempIChar ) {
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
j + + ;
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
if ( string2 [ j ] = = ' \0 ' ) {
return 0 ;
}
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
i + + ;
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
if ( string1 [ i ] ! = string2 [ j ] & & string1 [ i ] ! = ' ? ' ) {
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
return 0 ;
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
i + + ;
j + + ;
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
if ( string1 [ i ] = = ' \0 ' & & string2 [ j ] = = ' \0 ' ) {
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
return 1 ;
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
}
else {
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
return 0 ;
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
else {
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
printf ( " fish : Warning : fuck you, strings are considered null " ) ;
crash ( ) ;
return 0 ;
2017-05-28 20:02:05 +00:00
2017-06-13 09:13:06 +00:00
}
2017-05-28 20:02:05 +00:00
}
2017-05-29 13:19:52 +00:00
//beware : will purposedly ignore the first occurence of the character
WordList * splitWordIntoList ( char * string , char splitChar ) {
if ( stringContains ( string , ' / ' ) ) {
int i = 0 ;
int mark = 0 ;
2017-05-29 15:25:31 +00:00
int finished = 0 ; //boolean
int firstEncounter = 0 ; //boolean
2017-05-29 13:19:52 +00:00
WordList * newWordList = createWordList ( ) ;
2017-05-29 15:25:31 +00:00
if ( newWordList = = NULL ) crash ( ) ;
2017-05-29 13:19:52 +00:00
2017-06-02 11:43:31 +00:00
if ( string [ 0 ] = = ' . ' ) {
addEndWordList ( newWordList , ( char * ) " . " ) ;
i + + ;
}
2017-05-29 13:19:52 +00:00
while ( ! finished ) {
if ( string [ i ] = = splitChar | | string [ i ] = = ' \0 ' ) {
if ( ! firstEncounter ) {
firstEncounter = 1 ;
}
else {
char * tempStr = strndup ( string + mark , i - mark ) ;
2017-05-28 20:02:05 +00:00
2017-05-29 13:19:52 +00:00
if ( tempStr = = NULL ) {
crash ( ) ;
}
addEndWordList ( newWordList , tempStr ) ;
free ( tempStr ) ;
mark = i ;
if ( string [ i ] = = ' \0 ' ) {
finished = 1 ;
}
}
}
i + + ;
}
return newWordList ;
}
else {
WordList * newWordList = createWordList ( ) ;
addEndWordList ( newWordList , string ) ;
return newWordList ;
}
}