• # Toute nouvelle version

    Posté par (site web personnel) . En réponse au journal [Script Python] Création automatique des fichiers headers en C. Évalué à 2.

    Ca y est. Il fonctionne parfaitement (j'ai pu compiler sans problème raydium avec). Maintenant:
    • Change les #include (lorsque ce n'est pas un fichier header inclus) pour le fichier header correspondant. Si le fichier header n'existe pas, il est créé
    • Les lignes non reconnues sont commentées et ne viennent pas polluer le fichier .h
    • Les lignes commencant par static sont supprimées (avant, juste le mot-clef static était supprimé)
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # 
    # version 0.6
    # 
    ############
    ## TODO ##
    ############
    # 
    # [X] Suivre les #include
    # [X] Déclarations des variables
    # 	[X] Suprimer la valeur après le "="
    # [X] Fonctions
    # 	[X] permettre la mise en forme des fonctions ne possédant pas de bloc {}
    # [ ] C++
    # 	[ ] Voir si ca fonctionne
    # [X] Bugs
    # 	[X] Lorsque du code contenant "}" est commenté. Solution: rajouter "-fc1" à indent
    # 	[X] Ca ne compile pas lorsque le mot "static" apparait au début des lignes
    # 	[X] Il fallait ajouter le mot clef "extern" pour les déclarations de variables
    # 	[X] Ajout de constantes pour un inclusion conditionelle lors des #include ""
    # 
    import os, os.path, sys, string, re, Queue;
    SHORT_CONST=1
    def get_const(filename):
    	if SHORT_CONST:		filename=os.path.basename(filename)
    	if filename[-2:]=='.c':	filename=filename+".h"
    	CONST="_"+re.sub('[^A-Z]', '_', string.upper(filename))
    	return CONST;
    def get_indent_file(filename):
    	return os.popen('indent -l0 -npsl -fc1 -bbb < '+filename+' 2>/dev/null')
    def make_line(line):
    	if line[:6]=="static":
    		line = line[7:]
    	line=string.replace(line, ';;', ';')
    	line=string.replace(line, 'extern extern', 'extern')
    	line=string.replace(line, '/**/', '')
    	return line+"\n";
    def create_header(input_name, output_name, filename, origin='shell', tab=0):
    	input=get_indent_file(input_name)
    	output=open(output_name, 'w')
    	print '%s<"%s" origin="%s">'%(" "*tab, filename, origin)
    	output.write("#ifndef "+get_const(filename)+"\n")
    	output.write("#define "+get_const(filename)+"\n")
    	delete=0
    	keep=0
    	while 1:
    		line=input.readline()
    		if len(line)==0: break; # EOF
    		line=line.rstrip()
    		if len(line)==0: continue
    		try:	spaces=re.match(r'^(?P\s*)\S+.*$', line).group('spaces')
    		except:	spaces=''
    		
    		if line[0]=="#":
    			match=re.match(r'^#\s*include\s*"(?P[^"]*)"', line)
    			if match:
    				file=match.group('file')
    				dir=os.path.dirname(filename)+"/"
    				if file[-2:]!='.h' and os.access(dir+file, os.F_OK):
    					line=line.replace(file, file+'.h')
    					tab+=1
    					create_header(dir+file, dir+file+'.h', dir+file+'.h', filename[:], tab)
    					tab-=1
    			output.write(line+"\n")
    			continue
    		if keep==2 and line[0]=="{":	keep=1
    		if delete==2 and line[0]=="{":	delete=1
    		if delete==1:
    			if line[0]!="}" : continue
    			delete=0
    		elif keep==1:
    			output.write(line+"\n")
    			if line[0]!="}" : continue
    			keep=0
    		else:
    			if line[:6]=='static' : continue
    			elif line[:6]=='struct' :
    				line="extern "+line
    				if line[-1]=='{': keep=1 ; delete=0
    				elif line[-1]!=';': keep=2 ; delete=0
    			elif line[:7]=='typedef':
    				if line[-1]=='{': keep=1 ; delete=0
    				elif line[-1]!=';': keep=2 ; delete=0
    			else:
    				match = re.match(r'^(?P[A-Za-z_]+(\s+[(][^=;]*)?[^=(;]*)\s*(?P[\S])', line)
    				if match:
    					if match.group('char')=='(':
    						# function
    						if line[-1]=='{': delete=1 ; keep=0
    						elif line[-1]!=';': delete=2 ; keep=0
    						line="extern "+line+";"
    					else: # maybe '=' or ';'
    						if line[-1]=='{': delete=1 ; keep=0
    						elif line[-1]!=';': delete=2 ; keep=0
    						line="extern "+match.group('begin').rstrip()+";"
    # 				else:	line="/**UNRECOGNIZED** "+line+" **/"
    				else:	line="// "+line+" // Unrecognized"
    			output.write(line+"\n")
    			continue
    	print '%s</"%s">'%(" "*tab, filename)
    	output.write("#endif\n")
    	input.close()
    	output.close()
    if 1<len(sys.argv):
    	input_name=sys.argv[1]
    else:
    	print "Please select a file to create the header"
    	sys.exit(1);
    if 2<len(sys.argv):
    	output_name=sys.argv[2]
    else:	output_name=input_name+'.h'
    if 3<len(sys.argv):
    	CONST=sys.argv[3]
    else:	CONST=get_const(output_name)
    create_header(input_name, output_name, output_name)