Skip to content

Commit 3440bc7

Browse files
committed
[FEATURE] Added static functions check + started libft check
1 parent b088562 commit 3440bc7

2 files changed

Lines changed: 192 additions & 2 deletions

File tree

42PyChecker.py

Lines changed: 165 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,123 @@ def check_norme(project_path: str):
7272
return 0
7373

7474

75+
def check_makefile(project_path: str, binary_name: str):
76+
"""
77+
:param project_path: The path of the project
78+
:param binary_name: The binary that the makefile makes
79+
80+
:return: Returns 0 if makefile ok,
81+
1 if the makefile doesnt exists
82+
2 if the binary wasn't removed
83+
3 if the .o files weren't removed
84+
"""
85+
# @todo: Split check_makefile in separate methods for each rule
86+
makefile_path = project_path + '/Makefile'
87+
if not os.path.exists(makefile_path):
88+
print("Error: Makefile not found.")
89+
return 1
90+
with open(os.path.dirname(os.path.realpath(__file__)) + "/.mymakefile", 'w+') as file:
91+
file.write("Cleaning Directory\n")
92+
file.write("*------------------------------------------------------*\n")
93+
file.write("")
94+
result = subprocess.run('make ' + '-C ' + project_path + ' fclean', shell=True, stdout=subprocess.PIPE).stdout.decode('utf-8')
95+
file.write(result + '\n')
96+
if os.path.exists(project_path + '/' + binary_name):
97+
file.write("-> Error when processing rule `fclean': It should have removed {}\n".format(binary_name))
98+
#return 2 @todo: Here it doesnt return, it will just add more errors to the error counter
99+
if glob.glob(project_path + '*.o'):
100+
file.write("-> Error when processing rule `fclean': It should have removed *.o\n")
101+
#return 3
102+
file.write("*------------------------------------------------------*\n")
103+
file.write("Checking rule: `all'\n")
104+
if 'all: ' not in open(makefile_path).read():
105+
file.write("-> Error: rule `all' not found in the Makefile.\n")
106+
if 'all: $(NAME)' not in open(makefile_path).read():
107+
file.write("-> Error: rule `all' should call the rule `$(NAME)'\n")
108+
result = subprocess.run('make ' + '-C ' + project_path + ' all', shell=True, stdout=subprocess.PIPE).stdout.decode('utf-8')
109+
file.write(result + '\n')
110+
if not os.path.exists(project_path + '/' + binary_name):
111+
file.write("-> Error when processing rule `fclean': It should have created {}\n".format(binary_name))
112+
if not glob.glob(project_path + '/*.o'):
113+
file.write("-> Error when processing rule `fclean': It should NOT have removed *.o\n")
114+
# todo: [ -z "$(echo ${MAKEALLTWICE} | grep -i "Nothing to be done")" -a -z "$(echo ${MAKEALLTWICE} | grep -i "is up to date")" ] && printf "%s\n" "-> Failing rule: Processing the rule 'all' twice in a row should result in nothing to be done" && RET=1
115+
116+
file.write("*------------------------------------------------------*\n")
117+
file.write("Checking rule: `clean'\n")
118+
if 'clean: ' not in open(makefile_path).read():
119+
file.write("-> Error: rule `clean' not found in the Makefile.\n")
120+
if not os.path.exists(project_path + '/' + binary_name):
121+
file.write("-> Error: Cannot test rule `clean' because rule `all' failed\n")
122+
# Stop the makefile test here
123+
result = subprocess.run('make ' + '-C ' + project_path + ' clean', shell=True, stdout=subprocess.PIPE).stdout.decode('utf-8')
124+
file.write(result + '\n')
125+
if not os.path.exists(project_path + '/' + binary_name):
126+
file.write("-> Error: Failing Rule: It should not have cleaned the binary named {}.".format(binary_name))
127+
if glob.glob(project_path + '/*.o'):
128+
file.write("-> Error: Failing Rule: It should have cleaned the *.o")
129+
130+
file.write("*------------------------------------------------------*\n")
131+
file.write("Checking rule: `re'\n")
132+
if 're: ' not in open(makefile_path).read():
133+
file.write("-> Error: rule `re' not found in the Makefile.\n")
134+
if not os.path.exists(project_path + '/' + binary_name):
135+
file.write("-> Error: Cannot test rule `re' because rule `all' failed\n")
136+
inode1 = os.stat(project_path + '/' + binary_name).st_ino
137+
file.write("-- Before running rule `re', the {} inode is {}\n".format(binary_name, inode1))
138+
result = subprocess.run('make ' + '-C ' + project_path + ' re', shell=True, stdout=subprocess.PIPE).stdout.decode('utf-8')
139+
file.write(result + '\n')
140+
inode2 = os.stat(project_path + '/' + binary_name).st_ino
141+
file.write("-- After running rule `re', the {} inode is {}\n".format(binary_name, inode2))
142+
if not glob.glob(project_path + '/*.o'):
143+
file.write("-> Error when processing rule `re': It should have built the object file `*.o'\n")
144+
if not os.path.exists(project_path + '/' + binary_name):
145+
file.write("--> Error when processing rule `re': It should have compiled a binary named {}\n".format(binary_name))
146+
if inode1 == inode2:
147+
file.write("-> Failing rule `re': It should have compiled again the binary named {} (inode unchanged)\n".format(binary_name))
148+
149+
file.write("*------------------------------------------------------*\n")
150+
file.write("Checking rule: `fclean'\n")
151+
if 'fclean: ' not in open(makefile_path).read():
152+
file.write("-> Error: rule `fclean' not found in the Makefile.\n")
153+
result = subprocess.run('make ' + '-C ' + project_path + ' fclean', shell=True, stdout=subprocess.PIPE).stdout.decode('utf-8')
154+
file.write(result + '\n')
155+
if os.path.exists(project_path + '/' + binary_name):
156+
file.write("--> Error when processing rule `re': It should have removed the binary named {}\n".format(binary_name))
157+
if glob.glob(project_path + '/*.o'):
158+
file.write("-> Error: Failing Rule: It should have cleaned the *.o")
159+
if glob.glob(project_path + '/*.a'):
160+
file.write("-> Error: Failing Rule: It should have cleaned the *.a")
161+
162+
file.write("*------------------------------------------------------*\n")
163+
file.write("Checking rule: `$(NAME)'\n")
164+
if '$(NAME):' not in open(makefile_path).read():
165+
file.write("-> Error: rule `$(NAME)' not found in the Makefile.\n")
166+
result = subprocess.run('make ' + '-C ' + project_path + ' ' + binary_name, shell=True, stdout=subprocess.PIPE).stdout.decode('utf-8')
167+
file.write(result + '\n')
168+
if not os.path.exists(project_path + '/' + binary_name):
169+
file.write("--> Error when processing rule `re': It should have compiled a binary named {}\n".format(binary_name))
170+
if not glob.glob(project_path + '/*.o'):
171+
file.write("-> Error when processing rule `fclean': It should NOT have removed *.o\n")
172+
# @todo : [ -z "$(echo ${MAKEALLTWICE} | grep -i "Nothing to be done")" -a -z "$(echo ${MAKEALLTWICE} | grep -i "is up to date")" ] && printf "%s\n" "-> Failing rule: Processing the rule 'all' twice in a row should result in nothing to be done" && RET=1
173+
174+
file.write("*------------------------------------------------------*\n")
175+
file.write("Checking rule: `.PHONY'\n")
176+
if '.PHONY:' not in open(makefile_path).read():
177+
file.write("-> Error: rule `.PHONY' not found in the Makefile.\n")
178+
if not os.path.exists(project_path + '/' + binary_name):
179+
file.write("-> Error: Cannot test rule `re' because rule `$(NAME)' failed\n")
180+
result = subprocess.run('make ' + '-C ' + project_path + ' .PHONY', shell=True, stdout=subprocess.PIPE).stdout.decode('utf-8')
181+
file.write(result + '\n')
182+
if not os.path.exists(project_path + '/' + binary_name):
183+
file.write("--> Error when processing rule `.PHONY': It should not have cleaned the binary named {}\n".format(binary_name))
184+
if glob.glob(project_path + '/*.o'):
185+
file.write("-> Error: Failing Rule: It should have cleaned the *.o")
186+
return 0
187+
188+
75189
def check_42_commandements(project_path:str):
76190
"""
77-
:param project_path: The path of the project where you want to check the author file
191+
:param project_path: The path of the project
78192
:return: Will return 0 if everything is ok,
79193
1 if the file doesn't exists,
80194
2 if the file content is different.
@@ -89,5 +203,54 @@ def check_42_commandements(project_path:str):
89203
return 2
90204
return 0
91205

206+
def check_libft(project_path: str):
207+
required_functions = ['libft.h', 'ft_strcat.c', 'ft_strncat.c',
208+
'ft_strlcat.c', 'ft_strchr.c', 'ft_strnstr.c',
209+
'ft_strrchr.c', 'ft_strclr.c', 'ft_strcmp.c',
210+
'ft_strncmp.c', 'ft_strcpy.c', 'ft_strncpy.c',
211+
'ft_strdel.c', 'ft_strdup.c', 'ft_strequ.c',
212+
'ft_strnequ.c', 'ft_striter.c', 'ft_striteri.c',
213+
'ft_strjoin.c', 'ft_strlen.c', 'ft_strmap.c',
214+
'ft_strmapi.c', 'ft_strnew.c', 'ft_strstr.c',
215+
'ft_strsplit.c', 'ft_strsub.c', 'ft_strtrim.c',
216+
'ft_atoi.c', 'ft_itoa.c', 'ft_tolower.c',
217+
'ft_toupper.c', 'ft_putchar.c', 'ft_putchar_fd.c',
218+
'ft_putstr.c', 'ft_putstr_fd.c', 'ft_putnbr.c',
219+
'ft_putnbr_fd.c', 'ft_putendl.c', 'ft_putendl_fd.c',
220+
'ft_isalnum.c', 'ft_isalpha.c', 'ft_isascii.c',
221+
'ft_isdigit.c', 'ft_isprint.c', 'ft_memalloc.c',
222+
'ft_memchr.c', 'ft_memcmp.c', 'ft_memcpy.c',
223+
'ft_memccpy.c', 'ft_memdel.c', 'ft_memmove.c',
224+
'ft_memset.c', 'ft_bzero.c']
225+
bonus_functions = ['ft_lstnew.c', 'ft_lstdelone.c', 'ft_lstdel.c',
226+
'ft_lstiter.c', 'ft_lstadd.c', 'ft_lstmap.c']
227+
while True:
228+
if all([os.path.isfile(project_path + '/' + function) for function in required_functions]):
229+
break
230+
else:
231+
print("ERROR: not all required files are here")
232+
break
233+
while True:
234+
if all([os.path.isfile(project_path + '/' + function) for function in bonus_functions]):
235+
break
236+
else:
237+
print("Warning: not all bonus files are here")
238+
break
239+
file_list = []
240+
for file in glob.glob(project_path + '/*.c'):
241+
file_list.append(file.replace(project_path + '/', ''))
242+
extra_functions = [item for item in file_list if item not in required_functions and item not in bonus_functions]
243+
print("You have {} extra functions.".format(len(extra_functions)))
244+
check_norme(project_path)
245+
with open(os.path.dirname(os.path.realpath(__file__)) + "/.mystatic", 'w+') as file:
246+
result = subprocess.run(['sh', 'check_static.sh', project_path], stdout=subprocess.PIPE).stdout.decode('utf-8')
247+
file.write(result)
248+
check_makefile(project_path, "libft.a") # @todo: Have number of errors printed for makefile check
249+
#forbidden @todo: Add forbidden function check utility method
250+
#moulitest
251+
#libft-unit-test
252+
#maintest
253+
return 0
254+
92255

93-
sys.exit(check_42_commandements("/tmp/jlasne3"))
256+
sys.exit(check_libft("/tmp/libft"))

check_static.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
TOTAL=$(find "$1" -type f -name "*.c")
2+
OLDIFS=${IFS}
3+
IFS=$'\n'
4+
if [ "${TOTAL}" == "" ]
5+
then
6+
printf "Files not found"
7+
else
8+
for i in $(find "$1" -type f -name "*.c")
9+
do
10+
FILEN=$(basename "$i")
11+
awk -v FILEN="${FILEN}" -v FILEN2="${FILEN}" 'BEGIN \
12+
{ \
13+
OFS = ""
14+
sub(/\.c/, "", FILEN)
15+
} \
16+
$0 ~ /^[a-z_]+[ ]+\**[a-z_]*\(.*/ \
17+
{ \
18+
gsub (/^[a-z_]*[ ]+\**/, "")
19+
gsub (/ *\(.*$/, "")
20+
if ($1 != FILEN) \
21+
{ \
22+
print FILEN2, " (line ", NR, ") : ", $0, "() should be declared as static" \
23+
} \
24+
}' "$i"
25+
done
26+
fi
27+
IFS=${OLDIFS}

0 commit comments

Comments
 (0)