1
0
mirror of https://gitlab.com/klmp200/fish.git synced 2024-11-25 10:34:16 +00:00
fish/fish_shell/fish_globbing.c

397 lines
7.6 KiB
C
Raw Normal View History

// 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
WordList* expandWord(char* path){
2017-05-16 05:32:19 +00:00
if(!stringContains(path, '/')){
2017-05-28 15:25:04 +00:00
return getFiles((char*) "./", path);
2017-05-28 20:02:05 +00:00
}
else{
WordList* expandedList = createWordList();
recursiveExpandWord(path, expandedList);
return expandedList;
2017-05-29 13:19:52 +00:00
}
}
void recursiveExpandWord(char* path, WordList* listToExpand){
2017-06-02 12:58:43 +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 (?)
tempElement = pathToList->first;
while(i < pathToList->size - 1 && indexToExpand == -1){
if(stringContains(tempElement->word, '*') || stringContains(tempElement->word, '?')){
indexToExpand = i;
lastToExpand = 0;
}
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);
}
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);
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-06-13 09:13:06 +00:00
for(i=0; i < foundFiles->size; i++){
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-06-13 09:13:06 +00:00
tempElement = tempElement->next;
2017-06-13 09:13:06 +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;
if(concatenedString == NULL) crash();
2017-06-02 11:43:31 +00:00
concatenedString[0] = '\0';
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");
}
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");
}
WordListElement* tempElement = list->first;
for(i=0; i < firstElemIndex; i++){
tempElement = tempElement->next;
}
for(i=firstElemIndex; i < lastElemIndex; i++){
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);
tempElement = tempElement->next;
2017-05-28 20:02:05 +00:00
}
2017-05-28 15:25:04 +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
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;
if(!stringContains(string, '/')){
return string;
}
else{
2017-06-06 08:37:58 +00:00
int i = wordSize;
while(string[i] != '/'){
2017-06-06 08:37:58 +00:00
i--;
}
2017-06-13 09:13:06 +00:00
return strndup(string + i + 1,wordSize);
2017-06-02 15:53:45 +00:00
}
2017-06-06 08:37:58 +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();
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
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-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;
int finished = 0; //boolean
int firstEncounter = 0; //boolean
2017-05-29 13:19:52 +00:00
WordList* newWordList = createWordList();
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;
}
}