Martin Liška <mli...@suse.cz> writes: >> This patch set contains the bootstrap linking tool as well as python3 >> scripts to automatically generate texi libraries section of the gm2 >> documentation. In the fullness of time this will be changed to emit >> sphinx. > > Yep, looking forward to it. I'm going to write an email with Sphinx transition > schedule once Sphinx 5.3 gets released (should happen during the upcoming > weekend). > > I have general comments about the Python scripts: > > 1) please follow the Python coding style and not the GCC one (I'm going to > document > it in https://gcc.gnu.org/codingconventions.html under a new Python section). > The easiest approach is using flake8 and the following plugins: > > python3-flake8, python3-flake8-builtins, python3-flake8-bugbear, > python3-flake8-import-order, python3-flake8-quotes
Hi Martin, many thanks for the pointers to the style tool and python lint - I'll reformat the code accordingly. > plus, you might want to come up with a setup.cfg like we have in: > ./maintainer-scripts/setup.cfg yes sounds sensible. Thanks for the detailed observations/suggestions/improvements below - I agree with them all and will fix/change the code and then repost the patch regards, Gaius >> ------8<----------8<----------8<----------8<----------8<----------8<---- >> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/tools-src/tidydates.py >> --- /dev/null 2022-08-24 16:22:16.888000070 +0100 >> +++ gcc-git-devel-modula2/gcc/m2/tools-src/tidydates.py 2022-10-07 >> 20:21:18.682097332 +0100 >> @@ -0,0 +1,184 @@ >> +#!/usr/bin/env python3 >> + >> +# utility to tidy dates and detect lack of copyright. >> + >> +# Copyright (C) 2016-2022 Free Software Foundation, Inc. >> +# >> +# This file is part of GNU Modula-2. >> +# >> +# GNU Modula-2 is free software; you can redistribute it and/or modify >> +# it under the terms of the GNU General Public License as published by >> +# the Free Software Foundation; either version 3, or (at your option) >> +# any later version. >> +# >> +# GNU Modula-2 is distributed in the hope that it will be useful, >> +# but WITHOUT ANY WARRANTY; without even the implied warranty of >> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> +# GNU General Public License for more details. >> +# >> +# You should have received a copy of the GNU General Public License >> +# along with GNU Modula-2; see the file COPYING. If not, write to the >> +# Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA >> +# 02110-1301, USA. >> + >> +import os, sys >> + >> +maxLineLength = 60 >> + >> + >> +# >> +# visitDir - call func for each file below, dir, matching extension, ext. >> +# >> + >> +def visitDir (dir, ext, func): >> + listOfFiles = os.listdir(dir) >> + listOfFiles.sort() >> + for file in listOfFiles: >> + if os.path.isfile(os.path.join(dir, file)): >> + l = len(ext) >> + if (len(file)>l) and (file[-l:] == ext): >> + func(os.path.join(dir, file)) > > please use pathlib.Path(...).stem > >> + elif os.path.isdir(os.path.join(dir, file)): >> + visitDir(os.path.join(dir, file), ext, func) >> + >> +# >> +# isYear - returns True if, year, is legal. >> +# >> + >> +def isYear (year): >> + if len(year)==5: >> + year = year[:-1] >> + for c in year: >> + if not c.isdigit(): >> + return False >> + return True >> + >> + >> +# >> +# handleCopyright - >> +# >> + >> +def handleCopyright (outfile, lines, n, leader1, leader2): >> + global maxLineLength >> + i = lines[n] >> + c = i.find('Copyright (C) ')+len('Copyright (C)') >> + outfile.write(i[:c]) >> + d = i[c:].split() >> + start = c >> + seenDate = True >> + years = [] >> + while seenDate: >> + if d == []: >> + n += 1 >> + i = lines[n] >> + d = i[2:].split() >> + else: >> + e = d[0] >> + punctuation = "" > > Please unify "" and '', you only apostrophes. > >> + if len(d)==1: >> + d = [] >> + else: >> + d = d[1:] >> + >> + if c>maxLineLength: >> + outfile.write('\n') >> + outfile.write(leader1) >> + outfile.write(leader2) >> + outfile.write(' '*(start-2)) >> + c = start >> + >> + if isYear(e): >> + if (e[-1]=='.') or (e[-1]==','): >> + punctuation = e[-1] >> + e = e[:-1] >> + else: >> + punctuation = "" >> + else: >> + seenDate = False >> + if seenDate: >> + if not (e in years): >> + c += len(e) + len(punctuation) >> + outfile.write(' ') >> + outfile.write(e) >> + outfile.write(punctuation) >> + years += [e] >> + else: >> + if start < c: >> + outfile.write('\n') >> + outfile.write(leader1) >> + outfile.write(leader2) >> + outfile.write(' '*(start-2)) >> + >> + outfile.write(' ') >> + outfile.write(e) >> + outfile.write(punctuation) >> + for w in d: >> + outfile.write(' ') >> + outfile.write(w) >> + >> + outfile.write('\n') >> + return outfile, n+1 >> + >> +# >> +# handleHeader - reads in the header of a file and inserts >> +# a line break around the Copyright dates. >> +# >> + >> +def handleHeader (file, leader1, leader2): >> + print("------------------------------") >> + l = open(file, 'r').readlines() >> + if len(l)>20: >> + outfile = open('tmptidy', 'w') > > use 'with open(...) as outfile:' > https://docs.python.org/3/reference/compound_stmts.html#the-with-statement > > >> + n = 0 >> + for i in l: >> + if i.find('Copyright (C)')>=0: >> + outfile, n = handleCopyright(outfile, l, n, leader1, >> leader2) >> + outfile.writelines(l[n:]) >> + outfile.close() >> + print("-> mv tmptidy", file) >> + command = "mv tmptidy %s" % file >> + os.system(command) > > shutil.move > >> + return >> + else: >> + outfile.write(l[n]) >> + n += 1 >> + outfile.close() > > ... will be closed automatically by 'with' statement. > >> + sys.stdout.write("%s:1:1 needs a Copyright notice..\n" % file) >> + >> + >> +# >> +# bashTidy - tidy up dates using '#' comment >> +# >> + >> +def bashTidy (file): > > Better putting comments here in function body. > >> + handleHeader(file, '#', ' ') >> + >> +# >> +# cTidy - tidy up dates using '/* */' comments >> +# >> + >> +def cTidy (file): >> + handleHeader(file, ' ', '*') >> + >> +# >> +# m2Tidy - tidy up dates using '(* *)' comments >> +# >> + >> +def m2Tidy (file): >> + handleHeader(file, ' ', ' ') >> + >> +# >> +# main - for each file extension call the appropriate tidy >> +# routine. >> +# >> + >> +def main (): >> + visitDir('.', '.in', bashTidy) >> + visitDir('.', '.py', bashTidy) >> + visitDir('.', '.c', cTidy) >> + visitDir('.', '.h', cTidy) >> + visitDir('.', '.def', m2Tidy) >> + visitDir('.', '.mod', m2Tidy) >> + >> + >> +main () >> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/tools-src/boilerplate.py >> --- /dev/null 2022-08-24 16:22:16.888000070 +0100 >> +++ gcc-git-devel-modula2/gcc/m2/tools-src/boilerplate.py 2022-10-07 >> 20:21:18.682097332 +0100 >> @@ -0,0 +1,599 @@ >> +#!/usr/bin/env python3 >> +# >> +# boilerplate.py utility to rewrite the boilerplate with new dates. >> +# >> +# Copyright (C) 2018-2022 Free Software Foundation, Inc. >> +# Contributed by Gaius Mulley <ga...@glam.ac.uk>. >> +# >> +# This file is part of GNU Modula-2. >> +# >> +# GNU Modula-2 is free software; you can redistribute it and/or modify >> +# it under the terms of the GNU General Public License as published by >> +# the Free Software Foundation; either version 3, or (at your option) >> +# any later version. >> +# >> +# GNU Modula-2 is distributed in the hope that it will be useful, but >> +# WITHOUT ANY WARRANTY; without even the implied warranty of >> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> +# General Public License for more details. >> +# >> +# You should have received a copy of the GNU General Public License >> +# along with GNU Modula-2; see the file COPYING3. If not see >> +# <http://www.gnu.org/licenses/>. >> +# >> +import sys >> +import os >> +import glob >> +import sys, getopt, string >> +import datetime >> + >> +forceGPL3x, forceGPL3 = False, False >> +doModify, verbose = True, False, >> +multiFilemode, updateAll, forceCheck = False, False, False >> + >> +summaryGiven, contributedBy, outputName = "", "", "-" >> +errorCount = 0 >> +startDir = "." >> +seenFiles = [] >> + >> + >> +# >> +# printf - keeps C programmers happy :-) >> +# >> + >> +def printf (fmt, *args): >> + print(str (fmt) % args, end=' ') >> + >> +# >> +# error - issue an error message. >> +# >> + >> +def error (fmt, *args): >> + global errorCount >> + >> + print(str (fmt) % args, end=' ') >> + errorCount += 1 >> + >> + >> +def haltOnError (): >> + if errorCount > 0: >> + os.sys.exit (1) >> + >> + >> +def basename (f): >> + b = f.split ("/") >> + return b[-1] >> + >> + >> +# >> +# analyseComment - >> +# >> + >> +def analyseComment (text, f): >> + start_date, end_date, contribution, summary, lic = None, None, None, >> None, None >> + if text.find ("Copyright ISO/IEC") > 0: >> + lic = "BSISO" >> + now = datetime.datetime.now () >> + for d in range (1984, now.year+1): >> + if text.find (str (d)) > 0: >> + if start_date == None: >> + start_date = str (d) >> + end_date = str (d) >> + return start_date, end_date, "", "", lic >> + elif text.find ("Copyright (C)") > 0: > > better 'Copyright (C)' in text, similarly at other places .. > >> + if text.find ("GNU General Public License") > 0: >> + lic = "GPL" >> + elif text.find ("GNU Lesser General") > 0: >> + lic = "LGPL" >> + if text.find ("version 2.1") > 0: >> + lic += "v2.1" >> + elif text.find ("version 2") > 0: >> + lic += "v2" >> + elif text.find ("version 3") > 0: >> + lic += "v3" >> + if text.find ("GCC Runtime Library Exception") > 0: >> + lic += "x" >> + now = datetime.datetime.now () >> + for d in range (1984, now.year+1): >> + if text.find (str (d)) > 0: >> + if start_date == None: >> + start_date = str (d) >> + end_date = str (d) >> + if text.find ("ontributed by") > 0: >> + i = text.find ("ontributed by") >> + i += len ("ontributed by") >> + j = text.index (". ", i) >> + contribution = text[i:j] >> + if text.find (basename (f)) > 0: >> + i = text.find (basename (f)) >> + j = text.find (". ", i) >> + if j < 0: >> + error ('summary of the file does not finish with a "."') >> + summary = text[i:] >> + else: >> + summary = text[i:j] >> + return start_date, end_date, contribution, summary, lic >> + >> + >> +# >> +# analyseHeader - >> +# >> + >> +def analyseHeader (f, start, end): >> + text = "" >> + if end == None: >> + for count, l in enumerate (open (f, "r").readlines ()): >> + parts = l.split (start) >> + if len (parts) > 1: >> + line = start.join (parts[1:]) >> + line = line.rstrip () >> + line = line.lstrip () > > line = line.strip() > >> + text += " " >> + text += line >> + elif (l.rstrip () != "") and (len (parts[0]) > 0): >> + return analyseComment (text, f), count >> + else: >> + inComment = False >> + for count, l in enumerate (open (f, "r").readlines ()): > > 'r' is default > >> + while l != "": >> + l = l.strip () >> + l = l.rstrip () >> + if inComment: >> + text += " " >> + pos = l.find (end) > > better use > https://docs.python.org/3/library/stdtypes.html?highlight=partition#str.partition > >> + if pos >= 0: >> + text += l[:pos] >> + l = l[pos:] >> + inComment = False >> + else: >> + text += l >> + l = "" >> + else: >> + pos = l.find (start) >> + if (pos >= 0) and (len (l) > len (start)): >> + before = l[:pos] >> + before = before.rstrip () >> + before = before.lstrip () >> + if before != "": >> + return analyseComment (text, f), count >> + l = l[pos + len (start):] >> + inComment = True >> + elif (l != "") and (l == end): >> + l = "" >> + else: >> + return analyseComment (text, f), count >> + return [None, None, None, None, None], 0 >> + >> + >> +# >> +# addStop - add a full stop to a sentance. >> +# >> + >> +def addStop (sentence): >> + if sentence is None: >> + return None >> + sentence = sentence.rstrip () >> + if (len (sentence) > 0) and (sentence[-1] != "."): >> + return sentence + "." >> + return sentence >> + >> + >> +GPLv3 = """ >> +%s >> + >> +Copyright (C) %s Free Software Foundation, Inc. >> +Contributed by %s >> + >> +This file is part of GNU Modula-2. >> + >> +GNU Modula-2 is free software; you can redistribute it and/or modify >> +it under the terms of the GNU General Public License as published by >> +the Free Software Foundation; either version 3, or (at your option) >> +any later version. >> + >> +GNU Modula-2 is distributed in the hope that it will be useful, but >> +WITHOUT ANY WARRANTY; without even the implied warranty of >> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> +General Public License for more details. >> + >> +You should have received a copy of the GNU General Public License >> +along with GNU Modula-2; see the file COPYING3. If not see >> +<http://www.gnu.org/licenses/>. >> +""" >> + >> +GPLv3x = """ >> +%s >> + >> +Copyright (C) %s Free Software Foundation, Inc. >> +Contributed by %s >> + >> +This file is part of GNU Modula-2. >> + >> +GNU Modula-2 is free software; you can redistribute it and/or modify >> +it under the terms of the GNU General Public License as published by >> +the Free Software Foundation; either version 3, or (at your option) >> +any later version. >> + >> +GNU Modula-2 is distributed in the hope that it will be useful, but >> +WITHOUT ANY WARRANTY; without even the implied warranty of >> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> +General Public License for more details. >> + >> +Under Section 7 of GPL version 3, you are granted additional >> +permissions described in the GCC Runtime Library Exception, version >> +3.1, as published by the Free Software Foundation. >> + >> +You should have received a copy of the GNU General Public License and >> +a copy of the GCC Runtime Library Exception along with this program; >> +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see >> +<http://www.gnu.org/licenses/>. >> +""" >> + >> +LGPLv3 = """ >> +%s >> + >> +Copyright (C) %s Free Software Foundation, Inc. >> +Contributed by %s >> + >> +This file is part of GNU Modula-2. >> + >> +GNU Modula-2 is free software: you can redistribute it and/or modify >> +it under the terms of the GNU Lesser General Public License as >> +published by the Free Software Foundation, either version 3 of the >> +License, or (at your option) any later version. >> + >> +GNU Modula-2 is distributed in the hope that it will be useful, but >> +WITHOUT ANY WARRANTY; without even the implied warranty of >> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> +Lesser General Public License for more details. >> + >> +You should have received a copy of the GNU Lesser General Public License >> +along with GNU Modula-2. If not, see <https://www.gnu.org/licenses/>. >> +""" >> + >> +BSISO = """ >> +Library module defined by the International Standard >> + Information technology - programming languages >> + BS ISO/IEC 10514-1:1996E Part 1: Modula-2, Base Language. >> + >> + Copyright ISO/IEC (International Organization for Standardization >> + and International Electrotechnical Commission) %s. >> + >> + It may be freely copied for the purpose of implementation (see page >> + 707 of the Information technology - Programming languages Part 1: >> + Modula-2, Base Language. BS ISO/IEC 10514-1:1996). >> +""" >> + >> +templates = { "GPLv3":GPLv3, >> + "GPLv3x":GPLv3x, >> + "LGPLv3":LGPLv3, >> + "LGPLv2.1":LGPLv3, >> + "BSISO":BSISO } >> + >> + >> +def writeTemplate (fo, magic, start, end, dates, contribution, summary, >> lic): >> + if lic in templates: >> + if lic == "BSISO": >> + # non gpl but freely distributed for the implementation of a >> compiler >> + text = templates[lic] % (dates) >> + text = text.rstrip () >> + else: >> + summary = summary.lstrip () >> + contribution = contribution.lstrip () >> + summary = addStop (summary) >> + contribution = addStop (contribution) >> + if magic != None: >> + fo.write (magic) >> + fo.write ("\n") >> + text = templates[lic] % (summary, dates, contribution) >> + text = text.rstrip () >> + if end == None: >> + text = text.split ("\n") >> + for line in text: >> + fo.write (start) >> + fo.write (" ") >> + fo.write (line) >> + fo.write ("\n") >> + else: >> + text = text.lstrip () >> + fo.write (start) >> + fo.write (" ") >> + fo.write (text) >> + fo.write (" ") >> + fo.write (end) >> + fo.write ("\n") >> + # add a blank comment line for a script for eye candy. >> + if start == "#" and end == None: >> + fo.write (start) >> + fo.write ("\n") >> + else: >> + error ("no template found for: %s\n", lic) >> + os.sys.exit (1) >> + return fo >> + >> + >> +def writeBoilerPlate (fo, magic, start, end, start_date, end_date, >> contribution, summary, gpl): >> + if start_date == end_date: >> + dates = start_date >> + else: >> + dates = "%s-%s" % (start_date, end_date) >> + return writeTemplate (fo, magic, start, end, dates, contribution, >> summary, gpl) >> + >> + >> +def rewriteFile (f, magic, start, end, start_date, end_date, contribution, >> summary, gpl, lines): >> + l = open (f, "r").readlines ()[lines:] >> + text = "".join (l) >> + if outputName == "-": >> + fo = sys.stdout >> + else: >> + fo = open (f, "w") >> + fo = writeBoilerPlate (fo, magic, start, end, start_date, end_date, >> contribution, summary, gpl) >> + fo.write (text) >> + fo.flush () >> + if outputName != "-": >> + fo.close () >> + >> + >> +# >> +# handleHeader - keep reading lines of file, f, looking for start, end >> +# sequences and comments inside. The comments are checked >> +# for: date, contribution, summary >> +# >> + >> +def handleHeader (f, magic, start, end): >> + global date, contribution, summary, doModify, forceCheck, errorCount >> + >> + errorCount = 0 >> + [start_date, end_date, contribution, summary, lic], lines = >> analyseHeader (f, start, end) >> + if lic == None: >> + error ("%s:1:no GPL found at the top of the file\n", f) >> + else: >> + if verbose: >> + printf ("copyright: %s\n", lic) > > f-string format might be better, but that's just a hint: > https://docs.python.org/3/reference/lexical_analysis.html#f-strings > >> + if (start_date != None) and (end_date != None): >> + if start_date == end_date: >> + printf ("dates = %s\n", start_date) >> + else: >> + printf ("dates = %s-%s\n", start_date, end_date) >> + if summary != None: >> + printf ("summary: %s\n", summary) >> + if contribution != None: >> + printf ("contribution: %s\n", contribution) >> + if start_date == None: > > I prefer 'if not start_date' (simiarly at other places). > >> + error ("%s:1:no date found in the GPL at the top of the >> file\n", f) >> + if contribution == None: >> + if contributedBy == "": >> + error ("%s:1:no contribution found in the GPL at the top of >> the file\n", f) >> + else: >> + contribution = contributedBy >> + if summary == None: >> + if summaryGiven == "": >> + error ("%s:1:no single line summary found in the GPL at the >> top of the file\n", f) >> + else: >> + summary = summaryGiven >> + if errorCount == 0: >> + now = datetime.datetime.now () >> + if doModify: >> + if lic == "BSISO": >> + # don't change the BS ISO license! >> + pass >> + elif forceGPL3x: >> + lic = "GPLv3x" >> + elif forceGPL3: >> + lic = "GPLv3" >> + rewriteFile (f, magic, start, end, start_date, str (now.year), >> contribution, summary, lic, lines) >> + elif forceCheck: >> + print(f, "suppressing change as requested", start_date, >> end_date, lic) >> + else: >> + printf ("too many errors, no modifications will occur\n") >> + >> + >> +# >> +# bashTidy - tidy up dates using '#' comment >> +# >> + >> +def bashTidy (f): >> + handleHeader (f, "#!/bin/bash", "#", None) >> + >> + >> +# >> +# pythonTidy - tidy up dates using '#' comment >> +# >> + >> +def pythonTidy (f): >> + handleHeader (f, "#!/usr/bin/env python3", '#', None) >> + >> + >> +# >> +# bnfTidy - tidy up dates using '--' comment >> +# >> + >> +def bnfTidy (f): >> + handleHeader (f, None, '--', None) >> + >> + >> +# >> +# cTidy - tidy up dates using '/* */' comments >> +# >> + >> +def cTidy (f): >> + handleHeader (f, None, '/*', '*/') >> + >> +# >> +# m2Tidy - tidy up dates using '(* *)' comments >> +# >> + >> +def m2Tidy (f): >> + handleHeader (f, None, '(*', '*)') >> + >> +# >> +# inTidy - tidy up dates using '#' as a comment and check the first line >> for magic number. >> +# >> + >> +def inTidy (f): >> + first = open (f, "r").readlines ()[0] >> + if (len (first) > 0) and (first[:2] == "#!"): >> + # magic number found, use this >> + handleHeader (f, first, "#", None) >> + else: >> + handleHeader (f, None, "#", None) >> + >> + >> +# >> +# doVisit - >> +# >> + >> +def doVisit (args, dirname, names): >> + global outputName >> + func, extension = args >> + for f in names: >> + if len (f) > len (extension) and f[-len (extension):] == extension: >> + # print os.path.join (dirname, f) >> + outputName = f >> + func (os.path.join (dirname, f)) >> + >> + >> +# >> +# visitDir - visit >> +# >> + >> +def visitDir (startDir, extension, func): >> + global outputName, seenFiles >> + # os.walk (startDir, doVisit, [func, extension]) >> + for dirName, subdirList, fileList in os.walk(startDir): >> + for fname in fileList: >> + if (len (fname) > len (extension)) and (fname[-len(extension):] >> == extension): > > Path(...).stem again would be better. > >> + fullpath = os.path.join (dirName, fname) >> + outputName = fullpath >> + # printf ("outputName = %s\n", outputName) >> + if not (fullpath in seenFiles): >> + seenFiles += [fullpath] >> + func (fullpath) >> + # Remove the first entry in the list of sub-directories >> + # if there are any sub-directories present >> + if len(subdirList) > 0: >> + del subdirList[0] >> + >> +# >> +# findFiles - for each file extension call the appropriate tidy >> +# routine. >> +# >> + >> +def findFiles (): >> + visitDir (startDir, '.h.in', cTidy) >> + visitDir (startDir, '.in', inTidy) >> + visitDir (startDir, '.sh', inTidy) >> + visitDir (startDir, '.py', pythonTidy) >> + visitDir (startDir, '.c', cTidy) >> + visitDir (startDir, '.h', cTidy) >> + visitDir (startDir, '.cc', cTidy) >> + visitDir (startDir, '.def', m2Tidy) >> + visitDir (startDir, '.mod', m2Tidy) >> + visitDir (startDir, '.bnf', bnfTidy) >> + >> + >> +# >> +# usage - output very brief usage instructions. >> +# >> + >> +def usage (code = 0): >> + print("boilerplate [-c contributionstring] [ -s summarystring ] [-d] >> [-v] [-g] [-x] [-o outputfile] inputfile.c") >> + print(" -o outputfile (this must be before the final inputfile on >> the command line).") >> + print(" -c a string which will be used as the >> contribution line.") >> + print(" -s a string which will be used as the summary >> line.") >> + print(" -f force a check to insist that the contribution, >> summary and GPL exists.") >> + print(" -g change to GPLv3.") >> + print(" -x change to GPLv3 with GCC runtime extension.") >> + print(" -r directory recusively scan directory for known file >> extensions (.def, .mod, .c, .h, .py, .in, .sh).") >> + print(" -u update all dates.") >> + print(" -v verbose.") >> + print(" -N do not modify any file") >> + os.sys.exit (code) > > https://docs.python.org/3/library/argparse.html would be much better, you get > arguments parsing for free. > >> + >> + >> +# >> +# handleArguments - check the legal arguments. >> +# >> + >> +def handleArguments (): >> + global multiFilemode, contributedBy, updateAll, forceCheck, outputName, >> verbose, startDir, doModify, forceGPL3, forceGPL3x, summaryGiven >> + try: >> + optlist, l = getopt.getopt (sys.argv[1:],':c:dfgho:r:s:uvxN') >> + except getopt.GetoptError: >> + usage (1) >> + for opt in optlist: >> + if opt[0] == '-c': >> + contributedBy = opt[1] >> + if opt[0] == '-s': >> + summaryGiven = opt[1] >> + if opt[0] == '-d': >> + debugging = True >> + if opt[0] == '-f': >> + forceCheck = True >> + if opt[0] == '-g': >> + forceGPL3 = True >> + if opt[0] == '-x': >> + forceGPL3x = True >> + if opt[0] == '-h': >> + usage () >> + if opt[0] == '-r': >> + multiFilemode = True >> + startDir = opt[1] >> + if opt[0] == '-o': >> + outputName = opt[1] >> + if opt[0] == '-u': >> + updateAll = True >> + if opt[0] == '-v': >> + verbose = True >> + if opt[0] == '-N': >> + doModify = False >> + if l == []: >> + return None >> + return l[0] > > ^^^ this will be done automatically. > > Hope it's usefull. > > Thanks, > Martin > >> + >> + >> +# >> +# hasExt - return True if, name, ends with, ext. >> +# >> + >> +def hasExt (name, ext): >> + if len (name) > len (ext): >> + return name[-len (ext):] == ext >> + return False >> + >> + >> +# >> +# singleFile - scan the single file for a GPL boilerplate which >> +# has a GPL, contribution field and a summary heading. >> +# >> + >> +def singleFile (i): >> + if hasExt (i, ".def") or hasExt (i, ".mod"): >> + m2Tidy (i) >> + elif hasExt (i, ".h") or hasExt (i, ".c") or hasExt (i, ".cc"): >> + cTidy (i) >> + elif hasExt (i, ".in"): >> + inTidy (i) >> + elif hasExt (i, ".sh"): >> + inTidy (i) # uses magic number for actual sh/bash >> + elif hasExt (i, ".py"): >> + pythonTidy (i) >> + >> + >> +# >> +# main - handleArguments and then find source files. >> +# >> + >> +def main (): >> + i = handleArguments () >> + if multiFilemode: >> + findFiles () >> + elif i == None: >> + print("an input file must be specified on the command line") >> + usage (1) >> + else: >> + singleFile (i) >> + haltOnError () >> + >> + >> +main () >> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/tools-src/buildpg >> --- /dev/null 2022-08-24 16:22:16.888000070 +0100 >> +++ gcc-git-devel-modula2/gcc/m2/tools-src/buildpg 2022-10-07 >> 20:21:18.682097332 +0100 >> @@ -0,0 +1,289 @@ >> +#!/bin/sh >> + >> +# Copyright (C) 2000-2022 Free Software Foundation, Inc. >> +# This file is part of GNU Modula-2. >> +# >> +# GNU Modula-2 is free software; you can redistribute it and/or modify >> +# it under the terms of the GNU General Public License as published by >> +# the Free Software Foundation; either version 3, or (at your option) >> +# any later version. >> +# >> +# GNU Modula-2 is distributed in the hope that it will be useful, >> +# but WITHOUT ANY WARRANTY; without even the implied warranty of >> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> +# GNU General Public License for more details. >> +# >> +# You should have received a copy of the GNU General Public License >> +# along with GNU Modula-2; see the file COPYING. If not, write to the >> +# Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA >> +# 02110-1301, USA. >> +# >> + >> +# builds the pg.bnf from ppg.mod >> +# usage buildpg ppg.mod destination [-e] >> +# -e build without error recovery >> +# >> +PPGSRC=$1 >> +PPGDST=$2 >> + >> +includeNonErrorChecking () { >> + sed -e "1,/StartNonErrorChecking/d" < $PPGSRC |\ >> + sed -e "1,/EndNonErrorChecking/!d" >> +} >> + >> +includeErrorChecking () { >> + sed -e "1,/StartErrorChecking/d" < $PPGSRC |\ >> + sed -e "1,/EndErrorChecking/!d" >> +} >> + >> + >> +echo "% module" $PPGDST "begin" >> +sed -e "1,/% declaration/!d" < $PPGSRC | sed -e "s/ppg/${PPGDST}/g" >> + >> +echo "% declaration" $PPGDST "begin" >> + >> +sed -e "1,/% declaration/d" < $PPGSRC | sed -e "1,/% rules/!d" | sed -e >> "s/ppg/${PPGDST}/g" >> + >> +if [ "$3" = "-e" ] ; then >> + includeNonErrorChecking >> + echo "% module" $PPGDST "end" >> + sed -e "1,/% module pg end/d" < $PPGSRC | sed -e "s/ppg/${PPGDST}/g" >> +else >> + includeErrorChecking >> + echo "% module" $PPGDST "end" >> + sed -e "1,/% module pg end/d" < $PPGSRC | sed -e "s/ppg/${PPGDST}/g" |\ >> + sed -e "s/WasNoError := Main() ;/Main({eoftok}) ;/" >> +fi >> + >> +echo "% rules" >> + >> +cat << EOFEOF | sed -e "s/ppg/${PPGDST}/g" >> +error 'WarnError' 'WarnString' >> +tokenfunc 'GetCurrentTokenType()' >> + >> +token 'identifier' identtok -- internal token >> +token 'literal' literaltok >> +token '%' codetok >> +token ':=' lbecomestok >> +token '=:' rbecomestok >> +token '|' bartok >> +token '[' lsparatok >> +token ']' rsparatok >> +token '{' lcparatok -- left curly para >> +token '}' rcparatok -- right curly para >> +token '(' lparatok >> +token ')' rparatok >> +token "error" errortok >> +token "tokenfunc" tfunctok >> +token "symfunc" symfunctok >> +token '"' dquotetok >> +token "'" squotetok >> +token "module" moduletok >> +token "begin" begintok >> +token "rules" rulestok >> +token "end" endtok >> +token '<' lesstok >> +token '>' gretok >> +token "token" tokentok >> +token "special" specialtok >> +token "first" firsttok >> +token "follow" followtok >> +token "BNF" BNFtok >> +token "FNB" FNBtok >> +token "declaration" declarationtok >> +token "epsilon" epsilontok >> +token '' eoftok -- internal token >> + >> +special Ident first { < identtok > } follow { } >> +special Modula2Code first { } follow { '%' } >> +special StartModName first { < identtok > } follow { } >> +special EndModName first { < identtok > } follow { } >> +special DoDeclaration first { < identtok > } follow { } >> +special CollectLiteral first { < literaltok > } follow { } >> +special CollectTok first { < identtok > } follow { } >> +special DefineToken first { < identtok > } follow { } >> + >> +BNF >> + >> +Rules := "%" "rules" { Defs } ExtBNF =: >> + >> +Special := Ident >> + % VAR p: ProductionDesc ; % >> + % p := NewProduction() ; >> + p^.statement := NewStatement() ; >> + p^.statement^.followinfo^.calcfollow := TRUE ; >> + p^.statement^.followinfo^.epsilon := false ; >> + p^.statement^.followinfo^.reachend := false ; >> + p^.statement^.ident := CurrentIdent ; >> + p^.statement^.expr := NIL ; >> + p^.firstsolved := TRUE ; >> + p^.followinfo^.calcfollow := TRUE ; >> + p^.followinfo^.epsilon := false ; >> + p^.followinfo^.reachend := false % >> + First Follow [ "epsilon" % p^.statement^.followinfo^.epsilon >> := true ; (* these are not used - but they are displayed when debugging *) >> + p^.statement^.followinfo^.reachend >> := true ; >> + p^.followinfo^.epsilon := true ; >> + p^.followinfo^.reachend := true >> + % ] >> + [ Literal % p^.description := LastLiteral % ] >> + =: >> + >> +Factor := "%" Modula2Code "%" | >> + Ident % WITH CurrentFactor^ DO >> + type := id ; >> + ident := CurrentIdent >> + END ; % | >> + Literal % WITH CurrentFactor^ DO >> + type := lit ; >> + string := LastLiteral ; >> + IF GetSymKey(Aliases, LastLiteral)=NulName >> + THEN >> + WarnError1('no token defined for literal %s', >> LastLiteral) >> + END >> + END ; % | >> + "{" % WITH CurrentFactor^ DO >> + type := mult ; >> + expr := NewExpression() ; >> + CurrentExpression := expr ; >> + END ; % >> + Expression "}" | >> + "[" % WITH CurrentFactor^ DO >> + type := opt ; >> + expr := NewExpression() ; >> + CurrentExpression := expr ; >> + END ; % >> + Expression "]" | >> + "(" % WITH CurrentFactor^ DO >> + type := sub ; >> + expr := NewExpression() ; >> + CurrentExpression := expr ; >> + END ; % >> + Expression ")" =: >> + >> +Statement := % VAR i: IdentDesc ; % >> + Ident >> + % VAR p: ProductionDesc ; % >> + % p := FindDefinition(CurrentIdent^.name) ; >> + IF p=NIL >> + THEN >> + p := NewProduction() >> + ELSE >> + IF NOT ((p^.statement=NIL) OR (p^.statement^.expr=NIL)) >> + THEN >> + WarnError1('already declared rule %s', >> CurrentIdent^.name) >> + END >> + END ; >> + i := CurrentIdent ; % >> + ":=" >> + % VAR e: ExpressionDesc ; % >> + % e := NewExpression() ; >> + CurrentExpression := e ; % >> + % VAR s: StatementDesc ; % >> + % s := NewStatement() ; >> + WITH s^ DO >> + ident := i ; >> + expr := e >> + END ; % >> + Expression >> + % p^.statement := s ; % >> + "=:" =: >> + >> +Defs := "special" Special | "token" Token | "error" ErrorProcedures | >> + "tokenfunc" TokenProcedure | "symfunc" SymProcedure =: >> +ExtBNF := "BNF" { Production } "FNB" =: >> +Main := Header Decls Footer Rules =: >> +Header := "%" "module" StartModName =: >> +Decls := "%" "declaration" DoDeclaration =: >> +Footer := "%" "module" EndModName =: >> + >> +First := "first" "{" { LitOrTokenOrIdent >> + % WITH CurrentSetDesc^ DO >> + next := TailProduction^.first ; >> + END ; >> + TailProduction^.first := CurrentSetDesc >> + % >> + } "}" =: >> +Follow := "follow" "{" { LitOrTokenOrIdent >> + % WITH CurrentSetDesc^ DO >> + next := >> TailProduction^.followinfo^.follow ; >> + END ; >> + TailProduction^.followinfo^.follow := >> CurrentSetDesc >> + % >> + } "}" =: >> +LitOrTokenOrIdent := Literal % CurrentSetDesc := NewSetDesc() ; >> + WITH CurrentSetDesc^ DO >> + type := litel ; >> + string := LastLiteral ; >> + END ; >> + % | >> + '<' CollectTok '>' | >> + Ident % CurrentSetDesc := NewSetDesc() ; >> + WITH CurrentSetDesc^ DO >> + type := idel ; >> + ident := CurrentIdent ; >> + END ; >> + % =: >> + >> +Literal := '"' CollectLiteral '"' | >> + "'" CollectLiteral "'" =: >> + >> +CollectTok := % CurrentSetDesc := NewSetDesc() ; >> + WITH CurrentSetDesc^ DO >> + type := tokel ; >> + string := GetCurrentToken() ; >> + END ; >> + IF NOT ContainsSymKey(Values, GetCurrentToken()) >> + THEN >> + AddEntry(Values, GetCurrentToken(), LargestValue) ; >> + AddEntry(ReverseValues, Name(LargestValue), >> GetCurrentToken()) ; >> + AddEntry(Aliases, GetCurrentToken(), GetCurrentToken()) ; >> + AddEntry(ReverseAliases, GetCurrentToken(), >> GetCurrentToken()) ; >> + INC(LargestValue) >> + END ; >> + AdvanceToken() ; % =: >> + >> +CollectLiteral := % LastLiteral := GetCurrentToken() ; >> + AdvanceToken ; % =: >> + >> +DefineToken := % AddEntry(Aliases, LastLiteral, GetCurrentToken()) ; >> + AddEntry(ReverseAliases, GetCurrentToken(), LastLiteral) ; >> + AddEntry(Values, GetCurrentToken(), LargestValue) ; >> + AddEntry(ReverseValues, Name(LargestValue), >> GetCurrentToken()) ; >> + INC(LargestValue) ; >> + AdvanceToken ; % =: >> + >> +Token := Literal DefineToken =: >> + >> +ErrorProcedures := Literal % ErrorProcArray := LastLiteral % >> + Literal % ErrorProcString := LastLiteral % =: >> +TokenProcedure := Literal % TokenTypeProc := LastLiteral % =: >> +SymProcedure := Literal % SymIsProc := LastLiteral % =: >> + >> +Production := Statement =: >> +Expression := % VAR t1, t2: TermDesc ; >> + e : ExpressionDesc ; % >> + % e := CurrentExpression ; >> + t1 := NewTerm() ; >> + CurrentTerm := t1 ; % >> + Term % e^.term := t1 ; % >> + { "|" % t2 := NewTerm() ; >> + CurrentTerm := t2 % >> + Term % t1^.next := t2 ; >> + t1 := t2 % } =: >> + >> +Term := % VAR t1: TermDesc ; f1, f2: FactorDesc ; % >> + % CurrentFactor := NewFactor() ; >> + f1 := CurrentFactor ; >> + t1 := CurrentTerm ; % >> + Factor % t1^.factor := f1 ; >> + f2 := NewFactor() ; >> + CurrentFactor := f2 % >> + { Factor % f1^.next := f2 ; >> + f1 := f2 ; >> + f2 := NewFactor() ; >> + CurrentFactor := f2 ; % } >> + =: >> + >> +FNB >> + >> +EOFEOF >> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/tools-src/calcpath >> --- /dev/null 2022-08-24 16:22:16.888000070 +0100 >> +++ gcc-git-devel-modula2/gcc/m2/tools-src/calcpath 2022-10-07 >> 20:21:18.682097332 +0100 >> @@ -0,0 +1,51 @@ >> +#!/bin/sh >> + >> +# calcpath return a path which is $1/$2/$3 when $2 is relative and $2/$3 if >> absolute. >> + >> +# Copyright (C) 2021-2022 Free Software Foundation, Inc. >> +# Contributed by Gaius Mulley <gaius.mul...@southwales.ac.uk>. >> +# >> +# This file is part of GNU Modula-2. >> +# >> +# GNU Modula-2 is free software; you can redistribute it and/or modify it >> under >> +# the terms of the GNU General Public License as published by the Free >> +# Software Foundation; either version 3, or (at your option) any later >> +# version. >> +# >> +# GNU Modula-2 is distributed in the hope that it will be useful, but >> WITHOUT ANY >> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or >> +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >> +# for more details. >> +# >> +# You should have received a copy of the GNU General Public License along >> +# with gm2; see the file COPYING. If not, write to the Free Software >> +# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. >> *) >> + >> + >> +Usage () { >> + echo "Usage: calcpath pathcomponent1 pathcomponent2 subdir" >> + echo -n " if pathcomponent1 is relative then >> pathcomponent1/pathcomponet2/subdir is" >> + echo " returned" >> + echo " otherwise pathcomponet2/subdir is returned" >> + echo " the path is checked for legality in subdir." >> +} >> + >> + >> +if [ $# -eq 3 ]; then >> + if [ "$(echo $2 | cut -b 1)" = "." ] ; then >> + # relative path >> + the_path=$1/$2/$3 >> + else >> + the_path=$2/$3 >> + fi >> + cd $3 >> + if realpath ${the_path} > /dev/null ; then >> + echo ${the_path} >> + else >> + echo "calcpath: error ${the_path} is not a valid path in >> subdirectory $3" 1>&2 >> + exit 1 >> + fi >> +else >> + Usage >> + exit 1 >> +fi >> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/tools-src/makeSystem >> --- /dev/null 2022-08-24 16:22:16.888000070 +0100 >> +++ gcc-git-devel-modula2/gcc/m2/tools-src/makeSystem 2022-10-07 >> 20:21:18.682097332 +0100 >> @@ -0,0 +1,108 @@ >> +#!/bin/sh >> + >> +# makeSystem creates a target SYSTEM.def using the appropriate dialect >> template. >> + >> +# Copyright (C) 2008-2022 Free Software Foundation, Inc. >> +# Contributed by Gaius Mulley <gaius.mul...@southwales.ac.uk>. >> +# >> +# This file is part of GNU Modula-2. >> +# >> +# GNU Modula-2 is free software; you can redistribute it and/or modify it >> under >> +# the terms of the GNU General Public License as published by the Free >> +# Software Foundation; either version 3, or (at your option) any later >> +# version. >> +# >> +# GNU Modula-2 is distributed in the hope that it will be useful, but >> WITHOUT ANY >> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or >> +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >> +# for more details. >> +# >> +# You should have received a copy of the GNU General Public License along >> +# with gm2; see the file COPYING. If not, write to the Free Software >> +# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. >> *) >> + >> + >> +Usage () { >> + echo "Usage: makesystem dialectflag SYSTEM.def SYSTEM.mod librarypath >> compiler" >> +} >> + >> +if [ $# -lt 6 ] ; then >> + Usage >> + exit 1 >> +fi >> + >> +DIALECT=$1 >> +SYSTEMDEF=$2 >> +SYSTEMMOD=$3 >> +LIBRARY=$4 >> +COMPILER=$5 >> +OUTPUTFILE=$6 >> + >> +if [ "$COMPILER" = "" ] ; then >> + echo "parameter 5 of makeSystem is incorrect, GM2_FOR_TARGET was unset" >> + exit 1 >> +fi >> + >> +if [ "$DIALECT" != "-fiso" -a "$DIALECT" != "-fpim" ] ; then >> + Usage >> + echo "dialect must be -fiso or -fpim" >> + exit 1 >> +fi >> + >> +displayExportedTypes () { >> + n=1 >> + c=0 >> + for i in ${types} ; do >> + if [ $n -eq 1 ] ; then >> + n=0 >> + echo -n " " >> ${OUTPUTFILE} >> + fi >> + echo -n "$i, " >> ${OUTPUTFILE} >> + if [ $c -eq 4 ] ; then >> + echo " " >> ${OUTPUTFILE} >> + n=1 >> + c=0 >> + fi >> + c=`expr $c + 1` >> + done >> + echo " " >> ${OUTPUTFILE} >> +} >> + >> +displayBuiltinTypes () { >> + for i in ${types} ; do >> + echo " $i ; " >> ${OUTPUTFILE} >> + done >> +} >> + >> +displayStart () { >> + sed -e "1,/@SYSTEM_DATATYPES@/!d" < ${SYSTEMDEF} | \ >> + sed -e "/@SYSTEM_DATATYPES@/d" >> ${OUTPUTFILE} >> +} >> + >> +displayMiddle () { >> + sed -e "1,/@SYSTEM_DATATYPES@/d" < ${SYSTEMDEF} | \ >> + sed -e "1,/@SYSTEM_TYPES@/!d" | \ >> + sed -e "/@SYSTEM_TYPES@/d" >> ${OUTPUTFILE} >> +} >> + >> +displayEnd () { >> + sed -e "1,/@SYSTEM_TYPES@/d" < ${SYSTEMDEF} >> ${OUTPUTFILE} >> +} >> + >> +MINIMAL="-fno-scaffold-main -fno-scaffold-dynamic -fno-scaffold-static >> -fno-m2-plugin" >> + >> +rm -f ${OUTPUTFILE} >> +if ${COMPILER} ${DIALECT} ${LIBRARY} ${MINIMAL} \ >> + -c -fdump-system-exports ${SYSTEMMOD} -o /dev/null 2>&1 > >> /dev/null ; then >> + types=`${COMPILER} ${DIALECT} ${LIBRARY} ${MINIMAL} -fno-m2-plugin -c >> -fdump-system-exports ${SYSTEMMOD} -o /dev/null | cut -f5 -d' '` >> + touch ${OUTPUTFILE} >> + displayStart >> + displayExportedTypes >> + displayMiddle >> + displayBuiltinTypes >> + displayEnd >> +else >> + ${COMPILER} ${DIALECT} ${LIBRARY} ${MINIMAL} \ >> + -c -fdump-system-exports ${SYSTEMMOD} -o /dev/null >> + exit $? >> +fi >> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/tools-src/README >> --- /dev/null 2022-08-24 16:22:16.888000070 +0100 >> +++ gcc-git-devel-modula2/gcc/m2/tools-src/README 2022-10-07 >> 20:21:18.682097332 +0100 >> @@ -0,0 +1,3 @@ >> +This directory contains miscellaneous scripts and programs (mklink.c) >> +to allow for bootstrap linking and creating library documentation from >> +sources. >> \ No newline at end of file >> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/tools-src/mklink.c >> --- /dev/null 2022-08-24 16:22:16.888000070 +0100 >> +++ gcc-git-devel-modula2/gcc/m2/tools-src/mklink.c 2022-10-07 >> 20:21:18.682097332 +0100 >> @@ -0,0 +1,810 @@ >> +/* mklink.c creates startup code and the link command line. >> + >> +Copyright (C) 2000-2022 Free Software Foundation, Inc. >> +Contributed by Gaius Mulley <ga...@glam.ac.uk>. >> + >> +This file is part of GNU Modula-2. >> + >> +GNU Modula-2 is free software; you can redistribute it and/or modify >> +it under the terms of the GNU General Public License as published by >> +the Free Software Foundation; either version 3, or (at your option) >> +any later version. >> + >> +GNU Modula-2 is distributed in the hope that it will be useful, but >> +WITHOUT ANY WARRANTY; without even the implied warranty of >> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> +General Public License for more details. >> + >> +You should have received a copy of the GNU General Public License >> +along with GNU Modula-2; see the file COPYING3. If not see >> +<http://www.gnu.org/licenses/>. */ >> + >> + >> +#include "config.h" >> +#include "system.h" >> + >> +#define MAX_FILE_NAME 8192 >> +#define MAXSTACK 4096 >> +#define STDIN 0 >> +#define STDOUT 1 >> +#define ENDOFILE ((char)-1) >> +#define ERROR(X) \ >> + (fprintf (stderr, "%s:%d error %s\n", __FILE__, __LINE__, X) \ >> + && (fflush (stderr))) >> +#define DEBUG(X) \ >> + ((Debug) && (fprintf (stderr, "%s\n", X) && (fflush (stderr)))) >> + >> +#if !defined(TRUE) >> +#define TRUE (1 == 1) >> +#endif >> + >> +#if !defined(FALSE) >> +#define FALSE (1 == 0) >> +#endif >> + >> +typedef struct functlist >> +{ >> + char *functname; >> + struct functlist *next; >> +} functList; >> + >> +/* Prototypes. */ >> + >> +static void ParseFileLinkCommand (void); >> +static void ParseFileStartup (void); >> +static void ParseFile (char *Name); >> +static void ParseComments (void); >> +static void CopyUntilEof (void); >> +static void CopyUntilEol (void); >> +static int IsSym (char *s); >> +static int SymIs (char *s); >> +static int FindString (char *String); >> +static void GetNL (void); >> +static char GetChar (void); >> +static void ResetBuffer (void); >> +static int GetSingleChar (char *ch); >> +static int InRange (int Element, unsigned int Min, unsigned int Max); >> +static char PutChar (char ch); >> +static int IsSpace (char ch); >> +static void SkipSpaces (void); >> +static void SkipText (void); >> +static void SilentSkipSpaces (void); >> +static void SilentSkipText (void); >> +static void PushBack (char *s); >> +static int IsDigit (char ch); >> +static void GetName (char *Name); >> +static void OpenOutputFile (void); >> +static void CloseFile (void); >> +static void FindSource (char *Name); >> +static void CopyUntilEolInto (char *Buffer); >> +static void FindObject (char *Name); >> +static int IsExists (char *Name); >> + >> +/* Global variables. */ >> + >> +static char *NameOfFile = NULL; >> +static const char *NameOfMain = "main"; >> +static int StackPtr = 0; >> +static char Stack[MAXSTACK]; >> +static int CurrentFile = STDIN; >> +static int OutputFile; >> +static int LinkCommandLine = FALSE; >> +static int ProfilePCommand = FALSE; >> +static int ProfilePGCommand = FALSE; >> +static int ExitNeeded = TRUE; >> +static char *libraries = NULL; >> +static char *args = NULL; >> +static functList *head = NULL; >> +static functList *tail = NULL; >> +static int langC = FALSE; /* FALSE = C++, TRUE = C. */ >> + >> +/* addLibrary - adds libname to the list of libraries to be linked. */ >> + >> +static void >> +addLibrary (char *libname) >> +{ >> + if (libraries == NULL) >> + libraries = strdup (libname); >> + else >> + { >> + char *old = libraries; >> + char *newlib >> + = (char *)malloc (strlen (libname) + strlen (libraries) + 1 + 1); >> + strcpy (newlib, libraries); >> + strcat (newlib, " "); >> + strcat (newlib, libname); >> + libraries = newlib; >> + free (old); >> + } >> +} >> + >> +/* addGccArg - adds arg to the list of gcc arguments. */ >> + >> +static void >> +addGccArg (char *arg) >> +{ >> + if (args == NULL) >> + args = strdup (arg); >> + else >> + { >> + char *old = args; >> + char *newarg = (char *)malloc (strlen (old) + strlen (arg) + 1 + 1); >> + strcpy (newarg, old); >> + strcat (newarg, " "); >> + strcat (newarg, arg); >> + args = newarg; >> + free (old); >> + } >> +} >> + >> +int >> +main (int argc, char *argv[]) >> +{ >> + int i; >> + >> + if (argc >= 3) >> + { >> + if (strcmp (argv[1], "-l") == 0) >> + LinkCommandLine = TRUE; >> + else if (strcmp (argv[1], "-s") == 0) >> + LinkCommandLine = FALSE; >> + else >> + { >> + fprintf (stderr, "Usage: mklink (-l|-s) [--langc|--langc++] >> [--pg|-p] " >> + "[--lib library] [--main name] [--exit] --name " >> + "filename <modulelistfile>\n"); >> + fprintf (stderr, " must supply -l or -s option\n"); >> + exit (1); >> + } >> + ProfilePCommand = FALSE; >> + ProfilePGCommand = FALSE; >> + i = 2; >> + while (i < argc - 1) >> + { >> + if (strcmp (argv[i], "--langc++") == 0) >> + langC = FALSE; >> + else if (strcmp (argv[i], "--langc") == 0) >> + langC = TRUE; >> + else if (strncmp (argv[i], "-f", 2) == 0) >> + addGccArg (argv[i]); >> + else if (strcmp (argv[i], "--pg") == 0) >> + ProfilePGCommand = TRUE; >> + else if (strcmp (argv[i], "-p") == 0) >> + ProfilePCommand = TRUE; >> + else if (strcmp (argv[i], "--exit") == 0) >> + ExitNeeded = FALSE; >> + else if (strcmp (argv[i], "--lib") == 0) >> + { >> + i++; >> + addLibrary (argv[i]); >> + } >> + else if (strcmp (argv[i], "--main") == 0) >> + { >> + i++; >> + NameOfMain = argv[i]; >> + } >> + else if (strcmp (argv[i], "--name") == 0) >> + { >> + i++; >> + NameOfFile = argv[i]; >> + } >> + i++; >> + } >> + ParseFile (argv[i]); >> + } >> + else >> + { >> + fprintf (stderr, "Usage: mklink (-l|-s) [--gcc|--g++] [--pg|-p] >> [--lib " >> + "library] [--main name] [--exit] --name filename " >> + "<modulelistfile>\n"); >> + exit (1); >> + } >> + if (NameOfFile == NULL) >> + { >> + fprintf (stderr, "mklink must have a --name argument\n"); >> + fprintf (stderr, "Usage: mklink (-l|-s) [--gcc|--g++] [--pg|-p] >> [--lib " >> + "library] [--main name] [--exit] --name filename " >> + "<modulelistfile>\n"); >> + exit (1); >> + } >> + exit (0); >> +} >> + >> +/* ParseFile - parses the input file and generates the output file. */ >> + >> +static void >> +ParseFile (char *Name) >> +{ >> + FindSource (Name); >> + OpenOutputFile (); >> + if (LinkCommandLine) >> + ParseFileLinkCommand (); >> + else >> + ParseFileStartup (); >> + CloseFile (); >> +} >> + >> +/* ParseFileLinkCommand - generates the link command. */ >> + >> +static void >> +ParseFileLinkCommand (void) >> +{ >> + char name[MAX_FILE_NAME]; >> + char *s = NULL; >> + char *l = NULL; >> + char *c = NULL; >> + >> + s = getenv ("CC"); >> + if (s == NULL) >> + { >> + if (langC) >> + printf ("gcc -g "); >> + else >> + printf ("g++ -g "); >> + } >> + else >> + printf ("%s -g ", s); >> + >> + if (args != NULL) >> + printf ("%s ", args); >> + >> + l = getenv ("LDFLAGS"); >> + if (l != NULL) >> + printf ("%s ", l); >> + >> + c = getenv ("CFLAGS"); >> + if (c != NULL) >> + printf ("%s ", c); >> + >> + if (ProfilePGCommand) >> + printf (" -pg"); >> + else if (ProfilePCommand) >> + printf (" -p"); >> + >> + while (PutChar (GetChar ()) != (char)EOF) >> + { >> + CopyUntilEolInto (name); >> +#if defined(XENIX) >> + name[10] = (char)0; /* truncate object file name. */ >> +#endif >> + if ((strlen (name) > 0) && (name[0] != '#')) >> + FindObject (name); >> + } >> + printf (" %s\n", libraries); >> +} >> + >> +/* FindObject - searches the M2PATH variable to find the object file. >> + If it finds the object file it prints it to stdout otherwise it >> + writes an error on stderr. */ >> + >> +static void >> +FindObject (char *Name) >> +{ >> + char m2search[4096]; >> + char m2path[4096]; >> + char name[4096]; >> + char exist[4096]; >> + int s, p; >> + >> + if (getenv ("M2PATH") == NULL) >> + strcpy (m2path, "."); >> + else >> + strcpy (m2path, getenv ("M2PATH")); >> + >> + snprintf (name, sizeof (name), "%s.o", Name); >> + p = 0; >> + while (m2path[p] != (char)0) >> + { >> + s = 0; >> + while ((m2path[p] != (char)0) && (m2path[p] != ' ')) >> + { >> + m2search[s] = m2path[p]; >> + s++; >> + p++; >> + } >> + if (m2path[p] == ' ') >> + p++; >> + m2search[s] = (char)0; >> + snprintf (exist, sizeof (exist), "%s/%s", m2search, name); >> + if (IsExists (exist)) >> + { >> + printf (" %s", exist); >> + return; >> + } >> + } >> + fprintf (stderr, "cannot find %s\n", name); >> +} >> + >> +/* IsExists - returns true if a file, Name, exists. It returns false >> + otherwise. */ >> + >> +static int >> +IsExists (char *Name) >> +{ >> + struct stat buf; >> + >> + return (stat (Name, &buf) == 0); >> +} >> + >> +/* add_function - adds a name to the list of functions, in order. */ >> + >> +void >> +add_function (char *name) >> +{ >> + functList *p = (functList *)malloc (sizeof (functList)); >> + p->functname = (char *)malloc (strlen (name) + 1); >> + strcpy (p->functname, name); >> + >> + if (head == NULL) >> + { >> + head = p; >> + tail = p; >> + p->next = NULL; >> + } >> + else >> + { >> + tail->next = p; >> + tail = p; >> + tail->next = NULL; >> + } >> +} >> + >> +static void >> +GenerateInitCalls (functList *p) >> +{ >> + while (p != NULL) >> + { >> + printf (" _M2_%s_init (argc, argv, envp);\n", p->functname); >> + p = p->next; >> + } >> +} >> + >> +static void >> +GenerateFinishCalls (functList *p) >> +{ >> + if (p->next != NULL) >> + GenerateFinishCalls (p->next); >> + printf (" _M2_%s_finish (argc, argv, envp);\n", p->functname); >> +} >> + >> +static void >> +GeneratePrototypes (functList *p) >> +{ >> + while (p != NULL) >> + { >> + if (langC) >> + { >> + printf ("extern void _M2_%s_init (int argc, char *argv[], char >> *envp[]);\n", >> + p->functname); >> + printf ("extern void _M2_%s_finish (int argc, char *argv[], char >> *envp[]);\n", >> + p->functname); >> + } >> + else >> + { >> + printf ("extern \"C\" void _M2_%s_init (int argc, char *argv[], >> char *envp[]);\n", >> + p->functname); >> + printf ("extern \"C\" void _M2_%s_finish (int argc, char *argv[], >> char *envp[]);\n", >> + p->functname); >> + } >> + p = p->next; >> + } >> +} >> + >> +/* ParseFileStartup - generates the startup code. */ >> + >> +static void >> +ParseFileStartup (void) >> +{ >> + char name[MAX_FILE_NAME]; >> + functList *p; >> + >> + while (PutChar (GetChar ()) != (char)EOF) >> + { >> + CopyUntilEolInto (name); >> + if ((strlen (name) > 0) && (strcmp (name, "mod_init") != 0) >> + && (name[0] != '#')) >> + add_function (name); >> + } >> + GeneratePrototypes (head); >> + printf ("extern"); >> + if (!langC) >> + printf (" \"C\""); >> + printf (" void _exit(int);\n"); >> + >> + printf ("\n\nint %s(int argc, char *argv[], char *envp[])\n", NameOfMain); >> + printf ("{\n"); >> + GenerateInitCalls (head); >> + GenerateFinishCalls (head); >> + if (ExitNeeded) >> + printf (" _exit(0);\n"); >> + printf (" return(0);\n"); >> + printf ("}\n"); >> +} >> + >> +/* OpenOutputFile - shut down stdout and open the new mod_init.c */ >> + >> +static void >> +OpenOutputFile (void) >> +{ >> + if (strcmp (NameOfFile, "-") != 0) >> + { >> + if (close (STDOUT) != 0) >> + { >> + ERROR ("Unable to close stdout"); >> + exit (1); >> + } >> + OutputFile = creat (NameOfFile, 0666); >> + if (OutputFile != STDOUT) >> + { >> + ERROR ("Expected that the file descriptor should be 1"); >> + } >> + } >> +} >> + >> +/* CloseFile - flush and close the file. */ >> + >> +static void >> +CloseFile (void) >> +{ >> +#if 0 >> + fflush(stdout); >> + if (close(STDOUT) != 0) { >> + ERROR("Unable to close our output file"); exit(1); >> + } >> +#endif >> +} >> + >> +/* CopyUntilEof - copies from the current input marker until ENDOFILE >> + is reached. */ >> + >> +static void >> +CopyUntilEof (void) >> +{ >> + char ch; >> + >> + while ((ch = GetChar ()) != ENDOFILE) >> + putchar (ch); >> +} >> + >> +/* CopyUntilEol - copies from the current input marker until '\n' is >> + reached. */ >> + >> +static void >> +CopyUntilEol (void) >> +{ >> + char ch; >> + >> + while (((ch = GetChar ()) != '\n') && (ch != (char)EOF)) >> + putchar (ch); >> + if (ch == '\n') >> + putchar (ch); >> +} >> + >> +/* CopyUntilEolInto - copies from the current input marker until '\n' >> + is reached into a Buffer. */ >> + >> +static void >> +CopyUntilEolInto (char *Buffer) >> +{ >> + char ch; >> + int i = 0; >> + >> + while (((ch = GetChar ()) != '\n') && (ch != (char)EOF)) >> + { >> + Buffer[i] = ch; >> + i++; >> + } >> + if ((ch == '\n') || (ch == (char)EOF)) >> + Buffer[i] = (char)0; >> +} >> + >> +/* IsSym - returns true if string, s, was found in the input stream. >> + The input stream is uneffected. */ >> + >> +static int >> +IsSym (char *s) >> +{ >> + int i = 0; >> + >> + while ((s[i] != (char)0) && (s[i] == PutChar (GetChar ()))) >> + { >> + GetChar (); >> + i++; >> + } >> + if (s[i] == (char)0) >> + { >> + PushBack (s); >> + /* found s in input string. */ >> + return (TRUE); >> + } >> + else >> + { >> + /* push back the characters we have scanned. */ >> + if (i > 0) >> + { >> + do >> + { >> + i--; >> + PutChar (s[i]); >> + } >> + while (i > 0); >> + } >> + return (FALSE); >> + } >> +} >> + >> +/* SymIs - returns true if string, s, was found in the input stream. >> + The token s is consumed from the input stream. */ >> + >> +static int >> +SymIs (char *s) >> +{ >> + int i = 0; >> + >> + while ((s[i] != (char)0) && (s[i] == PutChar (GetChar ()))) >> + { >> + GetChar (); >> + i++; >> + } >> + if (s[i] == (char)0) >> + { >> + /* found s in input string. */ >> + return (TRUE); >> + } >> + else >> + { >> + /* push back the characters we have scanned. */ >> + if (i > 0) >> + { >> + do >> + { >> + i--; >> + PutChar (s[i]); >> + } >> + while (i > 0); >> + } >> + return (FALSE); >> + } >> +} >> + >> +/* FindString - keeps on reading input until a string, String, is >> + matched. If end of file is reached then FALSE is returned, otherwise >> + TRUE is returned. */ >> + >> +static int >> +FindString (char *String) >> +{ >> + int StringIndex = 0; >> + int Found = FALSE; >> + int eof = FALSE; >> + char ch; >> + >> + while ((!Found) && (!eof)) >> + { >> + if (String[StringIndex] == (char)0) >> + /* must have found string. */ >> + Found = TRUE; >> + else >> + { >> + ch = GetChar (); >> + eof = (ch == ENDOFILE); >> + if (ch == String[StringIndex]) >> + StringIndex++; >> + else >> + StringIndex = 0; >> + } >> + } >> + return (Found); >> +} >> + >> +/* GetNL - keeps on reading input from until a new line is found. */ >> + >> +static void >> +GetNL (void) >> +{ >> + char ch; >> + >> + while ((ch = GetChar ()) != '\n') >> + putchar (ch); >> + putchar ('\n'); >> +} >> + >> +/* GetChar - returns the current character in input. */ >> + >> +static char >> +GetChar (void) >> +{ >> + char ch; >> + >> + if (StackPtr > 0) >> + { >> + StackPtr--; >> + return (Stack[StackPtr]); >> + } >> + else >> + { >> + if (GetSingleChar (&ch)) >> + return (ch); >> + else >> + return (ENDOFILE); >> + } >> +} >> + >> +#define MAXBUF 0x1000 >> +static int Pointer = 0; >> +static int AmountRead = 0; >> +static char Buffer[MAXBUF]; >> + >> +/* ResetBuffer - resets the buffer information to an initial state. */ >> + >> +static void >> +ResetBuffer (void) >> +{ >> + StackPtr = 0; >> + Pointer = 0; >> + AmountRead = 0; >> +} >> + >> +/* GetSingleChar - gets a single character from input. TRUE is >> + returned upon success. */ >> + >> +static int >> +GetSingleChar (char *ch) >> +{ >> + if (Pointer == AmountRead) >> + { >> + AmountRead = read (CurrentFile, &Buffer, MAXBUF); >> + if (AmountRead < 0) >> + AmountRead = 0; >> + Pointer = 0; >> + } >> + if (Pointer == AmountRead) >> + { >> + *ch = ENDOFILE; >> + return (FALSE); >> + } >> + else >> + { >> + *ch = Buffer[Pointer]; >> + Pointer++; >> + return (TRUE); >> + } >> +} >> + >> +/* InRange - returns true if Element is within the range Min..Max. */ >> + >> +static int >> +InRange (int Element, unsigned int Min, unsigned int Max) >> +{ >> + return ((Element >= Min) && (Element <= Max)); >> +} >> + >> +/* PutChar - pushes a character back onto input. This character is >> + also returned. */ >> + >> +static char >> +PutChar (char ch) >> +{ >> + if (StackPtr < MAXSTACK) >> + { >> + Stack[StackPtr] = ch; >> + StackPtr++; >> + } >> + else >> + { >> + ERROR ("Stack overflow in PutChar"); >> + } >> + return (ch); >> +} >> + >> +/* IsSpace - returns true if character, ch, is a space. */ >> + >> +static int >> +IsSpace (char ch) >> +{ >> + return ((ch == ' ') || (ch == '\t')); >> +} >> + >> +/* SkipSpaces - eats up spaces in input. */ >> + >> +static void >> +SkipSpaces (void) >> +{ >> + while (IsSpace (PutChar (GetChar ()))) >> + putchar (GetChar ()); >> +} >> + >> +/* SilentSkipSpaces - eats up spaces in input. */ >> + >> +static void >> +SilentSkipSpaces (void) >> +{ >> + char ch; >> + >> + while (IsSpace (PutChar (GetChar ()))) >> + ch = GetChar (); /* throw away character. */ >> +} >> + >> +/* SkipText - skips ascii text, it does not skip white spaces. */ >> + >> +static void >> +SkipText (void) >> +{ >> + while (!IsSpace (PutChar (GetChar ()))) >> + putchar (GetChar ()); >> +} >> + >> +/* SilentSkipText - skips ascii text, it does not skip white spaces. */ >> + >> +static void >> +SilentSkipText (void) >> +{ >> + char ch; >> + >> + while (!IsSpace (PutChar (GetChar ()))) >> + ch = GetChar (); /* throw away character. */ >> +} >> + >> +/* PushBack - pushes a string, backwards onto the input stack. */ >> + >> +static void >> +PushBack (char *s) >> +{ >> + int i; >> + >> + i = strlen (s); >> + while (i > 0) >> + { >> + i--; >> + PutChar (s[i]); >> + } >> +} >> + >> +/* IsDigit - returns true if a character, ch, is a decimal digit. */ >> + >> +static int >> +IsDigit (char ch) >> +{ >> + return (((ch >= '0') && (ch <= '9'))); >> +} >> + >> +/* GetName - returns the next name found. */ >> + >> +static void >> +GetName (char *Name) >> +{ >> + int i; >> + char ch; >> + >> + SkipSpaces (); >> + ch = GetChar (); >> + i = 0; >> + while (!IsSpace (ch)) >> + { >> + Name[i] = ch; >> + i++; >> + ch = GetChar (); >> + } >> + Name[i] = '\0'; >> +} >> + >> +/* FindSource - open source file on StdIn. */ >> + >> +static void >> +FindSource (char *Name) >> +{ >> + if (close (STDIN) != 0) >> + { >> + ERROR ("close on STDIN failed"); >> + } >> + CurrentFile = open (Name, O_RDONLY); >> + if (CurrentFile < 0) >> + { >> + perror ("failed to open file"); >> + exit (1); >> + } >> + if (CurrentFile != STDIN) >> + { >> + ERROR ("Expecting file descriptor value of 1"); >> + } >> +} >> diff -ruw /dev/null gcc-git-devel-modula2/gcc/m2/tools-src/def2texi.py >> --- /dev/null 2022-08-24 16:22:16.888000070 +0100 >> +++ gcc-git-devel-modula2/gcc/m2/tools-src/def2texi.py 2022-10-07 >> 20:21:18.682097332 +0100 >> @@ -0,0 +1,423 @@ >> +#!/usr/bin/env python3 >> + >> +# def2texi.py creates texi library documentation for all exported >> procedures. >> +# Contributed by Gaius Mulley <gaius.mul...@southwales.ac.uk>. >> + >> +# Copyright (C) 2000-2022 Free Software Foundation, Inc. >> +# This file is part of GNU Modula-2. >> +# >> +# GNU Modula-2 is free software; you can redistribute it and/or modify >> +# it under the terms of the GNU General Public License as published by >> +# the Free Software Foundation; either version 3, or (at your option) >> +# any later version. >> +# >> +# GNU Modula-2 is distributed in the hope that it will be useful, >> +# but WITHOUT ANY WARRANTY; without even the implied warranty of >> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> +# GNU General Public License for more details. >> +# >> +# You should have received a copy of the GNU General Public License >> +# along with GNU Modula-2; see the file COPYING. If not, write to the >> +# Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA >> +# 02110-1301, USA. >> +# >> + >> +import sys >> +import os >> +import glob >> +import getopt >> + >> +libraryClassifications = [['gm2-libs','Base libraries', >> + 'Basic M2F compatible libraries'], >> + ['gm2-libs-pim','PIM and Logitech 3.0 Compatible', >> + 'PIM and Logitech 3.0 compatible libraries'], >> + ['gm2-libs-coroutines','PIM coroutine support', >> + 'PIM compatible process support'], >> + ['gm2-libs-iso','M2 ISO Libraries', >> + 'ISO defined libraries']] >> + >> +def initState (): >> + global inVar, inType, inConst >> + inVar, inType, inConst = False, False, False >> + >> + >> +# >> +# displayLibraryClass - displays a node for a library directory and invokes >> +# a routine to summarize each module >> +# >> + >> +def displayLibraryClass(): >> + global buildDir, up >> + previous = "" >> + >> + next=libraryClassifications[1][1] >> + i = 0 >> + l = libraryClassifications[i] >> + >> + while True: >> + print("@node " + l[1] + ", " + next + ", " + previous + ", " + up) >> + print("@section " + l[1]) >> + print("") >> + displayModules(l[1], l[0], buildDir, sourceDir) >> + print("") >> + print("@c >> ---------------------------------------------------------------------") >> + previous = l[1] >> + i += 1 >> + if i == len(libraryClassifications): >> + break >> + l = libraryClassifications[i] >> + if i+1 == len(libraryClassifications): >> + next = "" >> + else: >> + next = libraryClassifications[i+1][1] >> + >> +# >> +# displayMenu - displays the top level menu for library documentation >> +# >> + >> +def displayMenu(): >> + print("@menu") >> + for l in libraryClassifications: >> + print("* " + l[1] + "::" + l[2]) >> + print("@end menu") >> + >> + print("\n") >> + print("@c >> =====================================================================") >> + print("\n") >> + >> + >> +# >> +# removeInitialComments - removes any (* *) at the top of the definition >> module >> +# >> + >> +def removeInitialComments (file, line): >> + while (str.find(line, "*)") == -1): >> + line = file.readline() >> + >> +# >> +# removeFields - removes Author/Date/Last edit/SYSTEM/Revision fields from >> a comment within the start >> +# of a definition module >> +# >> + >> +def removeFields (file, line): >> + while (str.find(line, "*)") == -1): >> + if (str.find(line, "Author") != -1) and (str.find(line, ":") != -1): >> + line = file.readline() >> + elif (str.find(line, "Last edit") != -1) and (str.find(line, ":") >> != -1): >> + line = file.readline() >> + elif (str.find(line, "LastEdit") != -1) and (str.find(line, ":") != >> -1): >> + line = file.readline() >> + elif (str.find(line, "Last update") != -1) and (str.find(line, ":") >> != -1): >> + line = file.readline() >> + elif (str.find(line, "Date") != -1) and (str.find(line, ":") != -1): >> + line = file.readline() >> + elif (str.find(line, "Title") != -1) and (str.find(line, ":") != >> -1): >> + line = file.readline() >> + elif (str.find(line, "Revision") != -1) and (str.find(line, ":") != >> -1): >> + line = file.readline() >> + elif (str.find(line, "System") != -1) and (str.find(line, ":") != >> -1) and (str.find(line, "Description:") == -1): >> + line = file.readline() >> + elif (str.find(line, "SYSTEM") != -1) and (str.find(line, ":") != >> -1) and (str.find(line, "Description:") == -1): >> + line = file.readline() >> + else: >> + print(str.replace(str.replace(str.rstrip(line), >> + "{", "@{"), "}", "@}")) >> + line = file.readline() >> + print(str.rstrip(line)) >> + >> + >> +# >> +# checkIndex >> +# >> + >> +def checkIndex (line): >> + global inVar, inType, inConst >> + >> + words = str.split(line) >> + procedure = "" >> + if (len(words)>1) and (words[0] == "PROCEDURE"): >> + inConst = False >> + inType = False >> + inVar = False >> + if (words[1] == "__BUILTIN__") and (len(words)>2): >> + procedure = words[2] >> + else: >> + procedure = words[1] >> + >> + if (len(line)>1) and (line[0:2] == '(*'): >> + inConst = False >> + inType = False >> + inVar = False >> + elif line == "VAR": >> + inConst = False >> + inVar = True >> + inType = False >> + return >> + elif line == "TYPE": >> + inConst = False >> + inType = True >> + inVar = False >> + return >> + elif line == "CONST": >> + inConst = True >> + inType = False >> + inVar = False >> + >> + if inVar: >> + words = str.split(line, ',') >> + for word in words: >> + word = str.lstrip(word) >> + if word != "": >> + if str.find(word, ':') == -1: >> + print("@findex " + word + " (var)") >> + elif len(word)>0: >> + var = str.split(word, ':') >> + if len(var)>0: >> + print("@findex " + var[0] + " (var)") >> + >> + if inType: >> + words = str.lstrip(line) >> + if str.find(words, '=') != -1: >> + word = str.split(words, "=") >> + if (len(word[0])>0) and (word[0][0] != '_'): >> + print("@findex " + str.rstrip(word[0]) + " (type)") >> + else: >> + word = str.split(words) >> + if (len(word)>1) and (word[1] == ';'): >> + # hidden type >> + if (len(word[0])>0) and (word[0][0] != '_'): >> + print("@findex " + str.rstrip(word[0]) + " (type)") >> + >> + if inConst: >> + words = str.split(line, ';') >> + for word in words: >> + word = str.lstrip(word) >> + if word != "": >> + if str.find(word, '=') != -1: >> + var = str.split(word, '=') >> + if len(var)>0: >> + print("@findex " + var[0] + " (const)") >> + >> + if procedure != "": >> + name = str.split(procedure, "(") >> + if name[0] != "": >> + proc = name[0] >> + if proc[-1] == ";": >> + proc = proc[:-1] >> + if proc != "": >> + print("@findex " + proc) >> + >> + >> +# >> +# parseDefinition >> +# >> + >> +def parseDefinition (dir, source, build, file, needPage): >> + print("") >> + f = open(findFile(dir, build, source, file), 'r') >> + initState() >> + line = f.readline() >> +# while (str.find(line, "(*") != -1): >> + while (str.find(line, "(*") != -1): >> + removeInitialComments(f, line) >> + line = f.readline() >> + >> + while (str.find(line, "DEFINITION") == -1): >> + line = f.readline() >> + >> + print("@example") >> + print(str.rstrip(line)) >> + line = f.readline() >> + if len(str.rstrip(line)) == 0: >> + print(str.replace(str.replace(str.rstrip(line), >> + "{", "@{"), "}", "@}")) >> + line = f.readline() >> + if (str.find(line, "(*") != -1): >> + removeFields(f, line) >> + else: >> + print(str.rstrip(line)) >> + else: >> + print(str.rstrip(line)) >> + >> + line = f.readline() >> + while line: >> + line = str.rstrip(line) >> + checkIndex(line) >> + print(str.replace(str.replace(line, "{", "@{"), "}", "@}")) >> + line = f.readline() >> + print("@end example") >> + if needPage: >> + print("@page") >> + f.close() >> + >> +def parseModules (up, dir, build, source, listOfModules): >> + previous = "" >> + i = 0 >> + if len(listOfModules)>1: >> + next = dir + "/" + listOfModules[1][:-4] >> + else: >> + next = "" >> + >> + while i<len(listOfModules): >> + print("@node " + dir + "/" + listOfModules[i][:-4] + ", " + next + >> ", " + previous + ", " + up) >> + print("@subsection " + dir + "/" + listOfModules[i][:-4]) >> + parseDefinition(dir, source, build, listOfModules[i], True) >> + print("\n") >> + previous = dir + "/" + listOfModules[i][:-4] >> + i = i + 1 >> + if i+1<len(listOfModules): >> + next = dir + "/" + listOfModules[i+1][:-4] >> + else: >> + next = "" >> + >> + >> +# >> +# doCat - displays the contents of file, name, to stdout >> +# >> + >> +def doCat (name): >> + file = open(name, 'r') >> + line = file.readline() >> + while line: >> + print(str.rstrip(line)) >> + line = file.readline() >> + file.close() >> + >> + >> +# >> +# moduleMenu - generates a simple menu for all definition modules >> +# in dir >> +# >> + >> +def moduleMenu (dir, build, source): >> + print("@menu") >> + listOfFiles = [] >> + if os.path.exists(os.path.join(source, dir)): >> + listOfFiles += os.listdir(os.path.join(source, dir)) >> + if os.path.exists(os.path.join(source, dir)): >> + listOfFiles += os.listdir(os.path.join(build, dir)) >> + listOfFiles = list(dict.fromkeys(listOfFiles).keys()) >> + listOfFiles.sort() >> + for file in listOfFiles: >> + if foundFile(dir, build, source, file): >> + if (len(file)>4) and (file[-4:] == '.def'): >> + print("* " + dir + "/" + file[:-4] + "::" + file) >> + print("@end menu") >> + print("\n") >> + >> + >> +# >> +# checkDirectory - returns True if dir exists in either build or source. >> +# >> + >> +def checkDirectory (dir, build, source): >> + if os.path.isdir(build) and os.path.exists(os.path.join(build, dir)): >> + return True >> + elif os.path.isdir(source) and os.path.exists(os.path.join(source, >> dir)): >> + return True >> + else: >> + return False >> + >> + >> +# >> +# foundFile - return True if file is found in build/dir/file or >> source/dir/file. >> +# >> + >> +def foundFile (dir, build, source, file): >> + name = os.path.join(os.path.join(build, dir), file) >> + if os.path.exists(name): >> + return True >> + name = os.path.join(os.path.join(source, dir), file) >> + if os.path.exists(name): >> + return True >> + return False >> + >> + >> +# >> +# findFile - return the path to file searching in build/dir/file first >> then source/dir/file. >> +# >> + >> +def findFile (dir, build, source, file): >> + name1 = os.path.join(os.path.join(build, dir), file) >> + if os.path.exists(name1): >> + return name1 >> + name2 = os.path.join(os.path.join(source, dir), file) >> + if os.path.exists(name2): >> + return name2 >> + print("file cannot be found in either " + name1 + " or " + name2) >> + os.sys.exit(1) >> + >> + >> +# >> +# displayModules - walks though the files in dir and parses >> +# definition modules and includes README.texi >> +# >> + >> +def displayModules(up, dir, build, source): >> + if checkDirectory(dir, build, source): >> + if foundFile(dir, build, source, "README.texi"): >> + doCat(findFile(dir, build, source, "README.texi")) >> + >> + moduleMenu(dir, build, source) >> + listOfFiles = [] >> + if os.path.exists(os.path.join(source, dir)): >> + listOfFiles += os.listdir(os.path.join(source, dir)) >> + if os.path.exists(os.path.join(source, dir)): >> + listOfFiles += os.listdir(os.path.join(build, dir)) >> + listOfFiles = list(dict.fromkeys(listOfFiles).keys()) >> + listOfFiles.sort() >> + listOfModules = [] >> + for file in listOfFiles: >> + if foundFile(dir, build, source, file): >> + if (len(file)>4) and (file[-4:] == '.def'): >> + listOfModules += [file] >> + listOfModules.sort() >> + parseModules(up, dir, build, source, listOfModules) >> + else: >> + print("directory " + dir + " not found in either " + build + " or " >> + source) >> + >> + >> +def displayCopyright (): >> + print("@c Copyright (C) 2000-2022 Free Software Foundation, Inc.") >> + print("@c This file is part of GNU Modula-2.") >> + print(""" >> +@c Permission is granted to copy, distribute and/or modify this document >> +@c under the terms of the GNU Free Documentation License, Version 1.2 or >> +@c any later version published by the Free Software Foundation. >> +""") >> + >> +def Usage(): >> + print("def2texi.py [-h][-bbuilddir][-uupnode][-ffilename]") >> + >> +def collectArgs(): >> + buildDir="." >> + sourceDir="." >> + filename="" >> + up="" >> + try: >> + optlist, list = getopt.getopt(sys.argv[1:],':hb:f:s:u:') >> + except getopt.GetoptError: >> + Usage() >> + os.sys.exit(1) >> + for opt in optlist: >> + if opt[0] == '-h': >> + Usage() >> + if opt[0] == '-b': >> + buildDir = opt[1] >> + if opt[0] == '-f': >> + filename = opt[1] >> + if opt[0] == '-s': >> + sourceDir = opt[1] >> + if opt[0] == '-u': >> + up = opt[1] >> + return buildDir, sourceDir, filename, up >> + >> + >> +buildDir, sourceDir, filename, up = collectArgs() >> + >> +if filename == "": >> + displayCopyright() >> + displayMenu() >> + displayLibraryClass() >> +else: >> + parseDefinition('.', sourceDir, buildDir, filename, False)