From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by sourceware.org (Postfix) with ESMTPS id B76233858C83 for ; Fri, 14 Oct 2022 12:10:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B76233858C83 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-x42a.google.com with SMTP id bu30so7244960wrb.8 for ; Fri, 14 Oct 2022 05:10:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:user-agent:message-id :in-reply-to:date:references:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=CwwJ+FC1U6vhEf1pwPG2lgmSfJeo6wyZFVINUO4E4KY=; b=f5Jbp1lunUmfRRSqFIZUaoXPDy2Vk8wB+HDHsSLaPsi1MqY+MoG2Ol8Iwdgb5ucw3E 2NB6KAUGzkQmd/BFqzm3+W9y9QUDwSxr8bs0YUd0r6DiS3dqlZ/EzbSkYwvi72WPIpkG jbOVe4yHANlZPxCMwMUVWdrclIVCVSFjpmmo8mKv2eLckABeAMerzevr+T6TOndhgNuu lwzHyYAOXpTZhGlzd2RWXXFH8xXR/7beneHe6tI3s5ebsyITXgbfJ1e078Uj3Snh0XbX WGaj4tNCSFj1zMoYY/SBsUoKNmySyIqXGhAGYzQu9tQrjDGkBzQVJo8zZcM9AtoA9QBu 0CWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:user-agent:message-id :in-reply-to:date:references:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=CwwJ+FC1U6vhEf1pwPG2lgmSfJeo6wyZFVINUO4E4KY=; b=ZA/aJo+UP5POvxHjOuc00PgVfXfPxJtAxjSzIx+4gB4SCyOIjHIpnl1pd+3Iw+KYgU EhQCyEeI711P0cetNua1HHHhfLNsLQah/itcaqVlW2nCyBZWU/QCW8nJR+lirt3DzGWB OXOmbecfRTHRZUYaWFjE65W+/4gjOHNXFvRPjVj5PNSkxRRHUQYAF8o3G40Dx4bet0oW kpjxIvcWyNjVsej/Ymev1oepCU0canrRmY9NlcCDqjVgm+GsXm2btz0QpLwRXrj6Xij3 V3RMSOhR/WQ3y+dUfW8+WZEq0Ltc0ByLGgGmuklQegKGGMMKYku35b3mxkvl+FQ9isCy gGiw== X-Gm-Message-State: ACrzQf2FAykeVkMBcAZK6cwiUMA8G/2+ehFHlT0XN82iWr3zGuk+y6KU UFun1igdTXvxkao6j0PDKKTtDlbFT9o= X-Google-Smtp-Source: AMsMyM5PjHiRWrn+vIcqvvvUgerUQjLOkpYZkJjzZtT715krrZqdvfQHb6DjrBWbKfqR+jp4eyqPEA== X-Received: by 2002:adf:e192:0:b0:232:3648:776d with SMTP id az18-20020adfe192000000b002323648776dmr3250703wrb.698.1665749439365; Fri, 14 Oct 2022 05:10:39 -0700 (PDT) Received: from lancelot ([195.147.220.46]) by smtp.gmail.com with ESMTPSA id z10-20020a05600c0a0a00b003a2f2bb72d5sm10065452wmp.45.2022.10.14.05.10.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Oct 2022 05:10:38 -0700 (PDT) Received: from gaius by lancelot with local (Exim 4.94.2) (envelope-from ) id 1ojJWL-002EOj-5a; Fri, 14 Oct 2022 13:10:33 +0100 From: Gaius Mulley To: Martin =?utf-8?Q?Li=C5=A1ka?= Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] 16/19 modula2 front end: bootstrap and documentation tools References: <11f42175-8e23-5da3-6a13-6172039bfca2@suse.cz> Date: Fri, 14 Oct 2022 13:10:33 +0100 In-Reply-To: <11f42175-8e23-5da3-6a13-6172039bfca2@suse.cz> ("Martin =?utf-8?Q?Li=C5=A1ka=22's?= message of "Thu, 13 Oct 2022 11:12:16 +0200") Message-ID: <87k052ppvq.fsf@debian> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,URI_LONG_REPEAT autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Martin Li=C5=A1ka 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 trans= ition > 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 t= o document > it in https://gcc.gnu.org/codingconventions.html under a new Python secti= on). > 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<----= =20 >> 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 =3D 60 >> + >> + >> +# >> +# visitDir - call func for each file below, dir, matching extension, e= xt. >> +# >> + >> +def visitDir (dir, ext, func): >> + listOfFiles =3D os.listdir(dir) >> + listOfFiles.sort() >> + for file in listOfFiles: >> + if os.path.isfile(os.path.join(dir, file)): >> + l =3D len(ext) >> + if (len(file)>l) and (file[-l:] =3D=3D 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)=3D=3D5: >> + year =3D 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 =3D lines[n] >> + c =3D i.find('Copyright (C) ')+len('Copyright (C)') >> + outfile.write(i[:c]) >> + d =3D i[c:].split() >> + start =3D c >> + seenDate =3D True >> + years =3D [] >> + while seenDate: >> + if d =3D=3D []: >> + n +=3D 1 >> + i =3D lines[n] >> + d =3D i[2:].split() >> + else: >> + e =3D d[0] >> + punctuation =3D "" > > Please unify "" and '', you only apostrophes. > >> + if len(d)=3D=3D1: >> + d =3D [] >> + else: >> + d =3D d[1:] >> + >> + if c>maxLineLength: >> + outfile.write('\n') >> + outfile.write(leader1) >> + outfile.write(leader2) >> + outfile.write(' '*(start-2)) >> + c =3D start >> + >> + if isYear(e): >> + if (e[-1]=3D=3D'.') or (e[-1]=3D=3D','): >> + punctuation =3D e[-1] >> + e =3D e[:-1] >> + else: >> + punctuation =3D "" >> + else: >> + seenDate =3D False >> + if seenDate: >> + if not (e in years): >> + c +=3D len(e) + len(punctuation) >> + outfile.write(' ') >> + outfile.write(e) >> + outfile.write(punctuation) >> + years +=3D [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 =3D open(file, 'r').readlines() >> + if len(l)>20: >> + outfile =3D open('tmptidy', 'w') > > use 'with open(...) as outfile:' > https://docs.python.org/3/reference/compound_stmts.html#the-with-statement >=20=20=20=20 > >> + n =3D 0 >> + for i in l: >> + if i.find('Copyright (C)')>=3D0: >> + outfile, n =3D handleCopyright(outfile, l, n, leader1, = leader2) >> + outfile.writelines(l[n:]) >> + outfile.close() >> + print("-> mv tmptidy", file) >> + command =3D "mv tmptidy %s" % file >> + os.system(command) > > shutil.move > >> + return >> + else: >> + outfile.write(l[n]) >> + n +=3D 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 >> +#=20 >> +# boilerplate.py utility to rewrite the boilerplate with new dates. >> +#=20 >> +# Copyright (C) 2018-2022 Free Software Foundation, Inc. >> +# Contributed by Gaius Mulley . >> +#=20 >> +# This file is part of GNU Modula-2. >> +#=20 >> +# 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. >> +#=20 >> +# 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. >> +#=20 >> +# You should have received a copy of the GNU General Public License >> +# along with GNU Modula-2; see the file COPYING3. If not see >> +# . >> +# >> +import sys >> +import os >> +import glob >> +import sys, getopt, string >> +import datetime >> + >> +forceGPL3x, forceGPL3 =3D False, False >> +doModify, verbose =3D True, False, >> +multiFilemode, updateAll, forceCheck =3D False, False, False >> + >> +summaryGiven, contributedBy, outputName =3D "", "", "-" >> +errorCount =3D 0 >> +startDir =3D "." >> +seenFiles =3D [] >> + >> + >> +# >> +# printf - keeps C programmers happy :-) >> +# >> + >> +def printf (fmt, *args): >> + print(str (fmt) % args, end=3D' ') >> + >> +# >> +# error - issue an error message. >> +# >> + >> +def error (fmt, *args): >> + global errorCount >> + >> + print(str (fmt) % args, end=3D' ') >> + errorCount +=3D 1 >> + >> + >> +def haltOnError (): >> + if errorCount > 0: >> + os.sys.exit (1) >> + >> + >> +def basename (f): >> + b =3D f.split ("/") >> + return b[-1] >> + >> + >> +# >> +# analyseComment - >> +# >> + >> +def analyseComment (text, f): >> + start_date, end_date, contribution, summary, lic =3D None, None, No= ne, None, None >> + if text.find ("Copyright ISO/IEC") > 0: >> + lic =3D "BSISO" >> + now =3D datetime.datetime.now () >> + for d in range (1984, now.year+1): >> + if text.find (str (d)) > 0: >> + if start_date =3D=3D None: >> + start_date =3D str (d) >> + end_date =3D 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 =3D "GPL" >> + elif text.find ("GNU Lesser General") > 0: >> + lic =3D "LGPL" >> + if text.find ("version 2.1") > 0: >> + lic +=3D "v2.1" >> + elif text.find ("version 2") > 0: >> + lic +=3D "v2" >> + elif text.find ("version 3") > 0: >> + lic +=3D "v3" >> + if text.find ("GCC Runtime Library Exception") > 0: >> + lic +=3D "x" >> + now =3D datetime.datetime.now () >> + for d in range (1984, now.year+1): >> + if text.find (str (d)) > 0: >> + if start_date =3D=3D None: >> + start_date =3D str (d) >> + end_date =3D str (d) >> + if text.find ("ontributed by") > 0: >> + i =3D text.find ("ontributed by") >> + i +=3D len ("ontributed by") >> + j =3D text.index (". ", i) >> + contribution =3D text[i:j] >> + if text.find (basename (f)) > 0: >> + i =3D text.find (basename (f)) >> + j =3D text.find (". ", i) >> + if j < 0: >> + error ('summary of the file does not finish with a "."') >> + summary =3D text[i:] >> + else: >> + summary =3D text[i:j] >> + return start_date, end_date, contribution, summary, lic >> + >> + >> +# >> +# analyseHeader - >> +# >> + >> +def analyseHeader (f, start, end): >> + text =3D "" >> + if end =3D=3D None: >> + for count, l in enumerate (open (f, "r").readlines ()): >> + parts =3D l.split (start) >> + if len (parts) > 1: >> + line =3D start.join (parts[1:]) >> + line =3D line.rstrip () >> + line =3D line.lstrip () > > line =3D line.strip() > >> + text +=3D " " >> + text +=3D line >> + elif (l.rstrip () !=3D "") and (len (parts[0]) > 0): >> + return analyseComment (text, f), count >> + else: >> + inComment =3D False >> + for count, l in enumerate (open (f, "r").readlines ()): > > 'r' is default > >> + while l !=3D "": >> + l =3D l.strip () >> + l =3D l.rstrip () >> + if inComment: >> + text +=3D " " >> + pos =3D l.find (end) > > better use https://docs.python.org/3/library/stdtypes.html?highlight=3Dpa= rtition#str.partition > >> + if pos >=3D 0: >> + text +=3D l[:pos] >> + l =3D l[pos:] >> + inComment =3D False >> + else: >> + text +=3D l >> + l =3D "" >> + else: >> + pos =3D l.find (start) >> + if (pos >=3D 0) and (len (l) > len (start)): >> + before =3D l[:pos] >> + before =3D before.rstrip () >> + before =3D before.lstrip () >> + if before !=3D "": >> + return analyseComment (text, f), count >> + l =3D l[pos + len (start):] >> + inComment =3D True >> + elif (l !=3D "") and (l =3D=3D end): >> + l =3D "" >> + 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 =3D sentence.rstrip () >> + if (len (sentence) > 0) and (sentence[-1] !=3D "."): >> + return sentence + "." >> + return sentence >> + >> + >> +GPLv3 =3D """ >> +%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 >> +. >> +""" >> + >> +GPLv3x =3D """ >> +%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 >> +. >> +""" >> + >> +LGPLv3 =3D """ >> +%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 . >> +""" >> + >> +BSISO =3D """ >> +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 =3D { "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 =3D=3D "BSISO": >> + # non gpl but freely distributed for the implementation of = a compiler >> + text =3D templates[lic] % (dates) >> + text =3D text.rstrip () >> + else: >> + summary =3D summary.lstrip () >> + contribution =3D contribution.lstrip () >> + summary =3D addStop (summary) >> + contribution =3D addStop (contribution) >> + if magic !=3D None: >> + fo.write (magic) >> + fo.write ("\n") >> + text =3D templates[lic] % (summary, dates, contribution) >> + text =3D text.rstrip () >> + if end =3D=3D None: >> + text =3D text.split ("\n") >> + for line in text: >> + fo.write (start) >> + fo.write (" ") >> + fo.write (line) >> + fo.write ("\n") >> + else: >> + text =3D 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 =3D=3D "#" and end =3D=3D 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, cont= ribution, summary, gpl): >> + if start_date =3D=3D end_date: >> + dates =3D start_date >> + else: >> + dates =3D "%s-%s" % (start_date, end_date) >> + return writeTemplate (fo, magic, start, end, dates, contribution, s= ummary, gpl) >> + >> + >> +def rewriteFile (f, magic, start, end, start_date, end_date, contributi= on, summary, gpl, lines): >> + l =3D open (f, "r").readlines ()[lines:] >> + text =3D "".join (l) >> + if outputName =3D=3D "-": >> + fo =3D sys.stdout >> + else: >> + fo =3D open (f, "w") >> + fo =3D writeBoilerPlate (fo, magic, start, end, start_date, end_dat= e, contribution, summary, gpl) >> + fo.write (text) >> + fo.flush () >> + if outputName !=3D "-": >> + fo.close () >> + >> + >> +# >> +# handleHeader - keep reading lines of file, f, looking for start, end >> +# sequences and comments inside. The comments are chec= ked >> +# for: date, contribution, summary >> +# >> + >> +def handleHeader (f, magic, start, end): >> + global date, contribution, summary, doModify, forceCheck, errorCount >> + >> + errorCount =3D 0 >> + [start_date, end_date, contribution, summary, lic], lines =3D anal= yseHeader (f, start, end) >> + if lic =3D=3D 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 !=3D None) and (end_date !=3D None): >> + if start_date =3D=3D end_date: >> + printf ("dates =3D %s\n", start_date) >> + else: >> + printf ("dates =3D %s-%s\n", start_date, end_date) >> + if summary !=3D None: >> + printf ("summary: %s\n", summary) >> + if contribution !=3D None: >> + printf ("contribution: %s\n", contribution) >> + if start_date =3D=3D 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 fil= e\n", f) >> + if contribution =3D=3D None: >> + if contributedBy =3D=3D "": >> + error ("%s:1:no contribution found in the GPL at the to= p of the file\n", f) >> + else: >> + contribution =3D contributedBy >> + if summary =3D=3D None: >> + if summaryGiven =3D=3D "": >> + error ("%s:1:no single line summary found in the GPL at= the top of the file\n", f) >> + else: >> + summary =3D summaryGiven >> + if errorCount =3D=3D 0: >> + now =3D datetime.datetime.now () >> + if doModify: >> + if lic =3D=3D "BSISO": >> + # don't change the BS ISO license! >> + pass >> + elif forceGPL3x: >> + lic =3D "GPLv3x" >> + elif forceGPL3: >> + lic =3D "GPLv3" >> + rewriteFile (f, magic, start, end, start_date, str (now.yea= r), 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 li= ne for magic number. >> +# >> + >> +def inTidy (f): >> + first =3D open (f, "r").readlines ()[0] >> + if (len (first) > 0) and (first[:2] =3D=3D "#!"): >> + # magic number found, use this >> + handleHeader (f, first, "#", None) >> + else: >> + handleHeader (f, None, "#", None) >> + >> + >> +# >> +# doVisit - >> +# >> + >> +def doVisit (args, dirname, names): >> + global outputName >> + func, extension =3D args >> + for f in names: >> + if len (f) > len (extension) and f[-len (extension):] =3D=3D ex= tension: >> + # print os.path.join (dirname, f) >> + outputName =3D 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(extensio= n):] =3D=3D extension): > > Path(...).stem again would be better. > >> + fullpath =3D os.path.join (dirName, fname) >> + outputName =3D fullpath >> + # printf ("outputName =3D %s\n", outputName) >> + if not (fullpath in seenFiles): >> + seenFiles +=3D [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 =3D 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 o= n the command line).") >> + print(" -c a string which will be used as the contrib= ution line.") >> + print(" -s a string which will be used as the summary= line.") >> + print(" -f force a check to insist that the contribut= ion, 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 e= xtensions (.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, outputN= ame, verbose, startDir, doModify, forceGPL3, forceGPL3x, summaryGiven >> + try: >> + optlist, l =3D getopt.getopt (sys.argv[1:],':c:dfgho:r:s:uvxN') >> + except getopt.GetoptError: >> + usage (1) >> + for opt in optlist: >> + if opt[0] =3D=3D '-c': >> + contributedBy =3D opt[1] >> + if opt[0] =3D=3D '-s': >> + summaryGiven =3D opt[1] >> + if opt[0] =3D=3D '-d': >> + debugging =3D True >> + if opt[0] =3D=3D '-f': >> + forceCheck =3D True >> + if opt[0] =3D=3D '-g': >> + forceGPL3 =3D True >> + if opt[0] =3D=3D '-x': >> + forceGPL3x =3D True >> + if opt[0] =3D=3D '-h': >> + usage () >> + if opt[0] =3D=3D '-r': >> + multiFilemode =3D True >> + startDir =3D opt[1] >> + if opt[0] =3D=3D '-o': >> + outputName =3D opt[1] >> + if opt[0] =3D=3D '-u': >> + updateAll =3D True >> + if opt[0] =3D=3D '-v': >> + verbose =3D True >> + if opt[0] =3D=3D '-N': >> + doModify =3D False >> + if l =3D=3D []: >> + 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):] =3D=3D 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 =3D handleArguments () >> + if multiFilemode: >> + findFiles () >> + elif i =3D=3D 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.6= 82097332 +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=3D$1 >> +PPGDST=3D$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" =3D "-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 :=3D 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 ':=3D' lbecomestok >> +token '=3D:' 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 :=3D "%" "rules" { Defs } ExtBNF =3D: >> + >> +Special :=3D Ident >> + % VAR p: ProductionDesc ; % >> + % p :=3D NewProduction() ; >> + p^.statement :=3D NewStatement() ; >> + p^.statement^.followinfo^.calcfollow :=3D TRUE ; >> + p^.statement^.followinfo^.epsilon :=3D false ; >> + p^.statement^.followinfo^.reachend :=3D false ; >> + p^.statement^.ident :=3D CurrentIdent ; >> + p^.statement^.expr :=3D NIL ; >> + p^.firstsolved :=3D TRUE ; >> + p^.followinfo^.calcfollow :=3D TRUE ; >> + p^.followinfo^.epsilon :=3D false ; >> + p^.followinfo^.reachend :=3D false % >> + First Follow [ "epsilon" % p^.statement^.followinfo^.epsi= lon :=3D true ; (* these are not used - but they are displayed when debug= ging *) >> + p^.statement^.followinfo^.reac= hend :=3D true ; >> + p^.followinfo^.epsilon :=3D t= rue ; >> + p^.followinfo^.reachend :=3D t= rue >> + % ] >> + [ Literal % p^.description :=3D LastLiteral % ] >> + =3D: >> + >> +Factor :=3D "%" Modula2Code "%" | >> + Ident % WITH CurrentFactor^ DO >> + type :=3D id ; >> + ident :=3D CurrentIdent >> + END ; % | >> + Literal % WITH CurrentFactor^ DO >> + type :=3D lit ; >> + string :=3D LastLiteral ; >> + IF GetSymKey(Aliases, LastLiteral)=3DNulName >> + THEN >> + WarnError1('no token defined for literal = %s', LastLiteral) >> + END >> + END ; % | >> + "{" % WITH CurrentFactor^ DO >> + type :=3D mult ; >> + expr :=3D NewExpression() ; >> + CurrentExpression :=3D expr ; >> + END ; % >> + Expression "}" | >> + "[" % WITH CurrentFactor^ DO >> + type :=3D opt ; >> + expr :=3D NewExpression() ; >> + CurrentExpression :=3D expr ; >> + END ; % >> + Expression "]" | >> + "(" % WITH CurrentFactor^ DO >> + type :=3D sub ; >> + expr :=3D NewExpression() ; >> + CurrentExpression :=3D expr ; >> + END ; % >> + Expression ")" =3D: >> + >> +Statement :=3D % VAR i: IdentDesc ; % >> + Ident >> + % VAR p: ProductionDesc ; % >> + % p :=3D FindDefinition(CurrentIdent^.name) ; >> + IF p=3DNIL >> + THEN >> + p :=3D NewProduction() >> + ELSE >> + IF NOT ((p^.statement=3DNIL) OR (p^.statement^.expr= =3DNIL)) >> + THEN >> + WarnError1('already declared rule %s', CurrentIde= nt^.name) >> + END >> + END ; >> + i :=3D CurrentIdent ; % >> + ":=3D" >> + % VAR e: ExpressionDesc ; % >> + % e :=3D NewExpression() ; >> + CurrentExpression :=3D e ; % >> + % VAR s: StatementDesc ; % >> + % s :=3D NewStatement() ; >> + WITH s^ DO >> + ident :=3D i ; >> + expr :=3D e >> + END ; % >> + Expression >> + % p^.statement :=3D s ; % >> + "=3D:" =3D: >> + >> +Defs :=3D "special" Special | "token" Token | "error" ErrorProced= ures | >> + "tokenfunc" TokenProcedure | "symfunc" SymProcedure =3D: >> +ExtBNF :=3D "BNF" { Production } "FNB" =3D: >> +Main :=3D Header Decls Footer Rules =3D: >> +Header :=3D "%" "module" StartModName =3D: >> +Decls :=3D "%" "declaration" DoDeclaration =3D: >> +Footer :=3D "%" "module" EndModName =3D: >> + >> +First :=3D "first" "{" { LitOrTokenOrIdent >> + % WITH CurrentSetDesc^ DO >> + next :=3D TailProduction^.first ; >> + END ; >> + TailProduction^.first :=3D CurrentSetDesc >> + % >> + } "}" =3D: >> +Follow :=3D "follow" "{" { LitOrTokenOrIdent >> + % WITH CurrentSetDesc^ DO >> + next :=3D TailProduction^.followinfo^= .follow ; >> + END ; >> + TailProduction^.followinfo^.follow :=3D = CurrentSetDesc >> + % >> + } "}" =3D: >> +LitOrTokenOrIdent :=3D Literal % CurrentSetDesc :=3D NewSetDesc() ; >> + WITH CurrentSetDesc^ DO >> + type :=3D litel ; >> + string :=3D LastLiteral ; >> + END ; >> + % | >> + '<' CollectTok '>' | >> + Ident % CurrentSetDesc :=3D NewSetDesc() ; >> + WITH CurrentSetDesc^ DO >> + type :=3D idel ; >> + ident :=3D CurrentIdent ; >> + END ; >> + % =3D: >> + >> +Literal :=3D '"' CollectLiteral '"' | >> + "'" CollectLiteral "'" =3D: >> + >> +CollectTok :=3D % CurrentSetDesc :=3D NewSetDesc() ; >> + WITH CurrentSetDesc^ DO >> + type :=3D tokel ; >> + string :=3D GetCurrentToken() ; >> + END ; >> + IF NOT ContainsSymKey(Values, GetCurrentToken()) >> + THEN >> + AddEntry(Values, GetCurrentToken(), LargestValue) ; >> + AddEntry(ReverseValues, Name(LargestValue), GetCurre= ntToken()) ; >> + AddEntry(Aliases, GetCurrentToken(), GetCurrentToken= ()) ; >> + AddEntry(ReverseAliases, GetCurrentToken(), GetCurre= ntToken()) ; >> + INC(LargestValue) >> + END ; >> + AdvanceToken() ; % =3D: >> + >> +CollectLiteral :=3D % LastLiteral :=3D GetCurrentToken() ; >> + AdvanceToken ; % =3D: >> + >> +DefineToken :=3D % AddEntry(Aliases, LastLiteral, GetCurrentToken()) ; >> + AddEntry(ReverseAliases, GetCurrentToken(), LastLiter= al) ; >> + AddEntry(Values, GetCurrentToken(), LargestValue) ; >> + AddEntry(ReverseValues, Name(LargestValue), GetCurren= tToken()) ; >> + INC(LargestValue) ; >> + AdvanceToken ; % =3D: >> + >> +Token :=3D Literal DefineToken =3D: >> + >> +ErrorProcedures :=3D Literal % ErrorProcArray :=3D LastLiteral % >> + Literal % ErrorProcString :=3D LastLiteral % =3D: >> +TokenProcedure :=3D Literal % TokenTypeProc :=3D LastLiteral % =3D: >> +SymProcedure :=3D Literal % SymIsProc :=3D LastLiteral % =3D: >> + >> +Production :=3D Statement =3D: >> +Expression :=3D % VAR t1, t2: TermDesc ; >> + e : ExpressionDesc ; % >> + % e :=3D CurrentExpression ; >> + t1 :=3D NewTerm() ; >> + CurrentTerm :=3D t1 ; % >> + Term % e^.term :=3D t1 ; % >> + { "|" % t2 :=3D NewTerm() ; >> + CurrentTerm :=3D t2 % >> + Term % t1^.next :=3D t2 ; >> + t1 :=3D t2 % } =3D: >> + >> +Term :=3D % VAR t1: TermDesc ; f1, f2: FactorDesc ; % >> + % CurrentFactor :=3D NewFactor() ; >> + f1 :=3D CurrentFactor ; >> + t1 :=3D CurrentTerm ; % >> + Factor % t1^.factor :=3D f1 ; >> + f2 :=3D NewFactor() ; >> + CurrentFactor :=3D f2 % >> + { Factor % f1^.next :=3D f2 ; >> + f1 :=3D f2 ; >> + f2 :=3D NewFactor() ; >> + CurrentFactor :=3D f2 ; % } >> + =3D: >> + >> +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 . >> +# >> +# 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 W= ITHOUT 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 alo= ng >> +# with gm2; see the file COPYING. If not, write to the Free Software >> +# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, U= SA. *) >> + >> + >> +Usage () { >> + echo "Usage: calcpath pathcomponent1 pathcomponent2 subdir" >> + echo -n " if pathcomponent1 is relative then pathcomponent1/pathcom= ponet2/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)" =3D "." ] ; then >> + # relative path >> + the_path=3D$1/$2/$3 >> + else >> + the_path=3D$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 subdire= ctory $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:1= 8.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 . >> +# >> +# 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 W= ITHOUT 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 alo= ng >> +# with gm2; see the file COPYING. If not, write to the Free Software >> +# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, U= SA. *) >> + >> + >> +Usage () { >> + echo "Usage: makesystem dialectflag SYSTEM.def SYSTEM.mod librarypat= h compiler" >> +} >> + >> +if [ $# -lt 6 ] ; then >> + Usage >> + exit 1 >> +fi >> + >> +DIALECT=3D$1 >> +SYSTEMDEF=3D$2 >> +SYSTEMMOD=3D$3 >> +LIBRARY=3D$4 >> +COMPILER=3D$5 >> +OUTPUTFILE=3D$6 >> + >> +if [ "$COMPILER" =3D "" ] ; then >> + echo "parameter 5 of makeSystem is incorrect, GM2_FOR_TARGET was un= set" >> + exit 1 >> +fi >> + >> +if [ "$DIALECT" !=3D "-fiso" -a "$DIALECT" !=3D "-fpim" ] ; then >> + Usage >> + echo "dialect must be -fiso or -fpim" >> + exit 1 >> +fi >> + >> +displayExportedTypes () { >> + n=3D1 >> + c=3D0 >> + for i in ${types} ; do >> + if [ $n -eq 1 ] ; then >> + n=3D0 >> + echo -n " " >> ${OUTPUTFILE} >> + fi >> + echo -n "$i, " >> ${OUTPUTFILE} >> + if [ $c -eq 4 ] ; then >> + echo " " >> ${OUTPUTFILE} >> + n=3D1 >> + c=3D0 >> + fi >> + c=3D`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=3D"-fno-scaffold-main -fno-scaffold-dynamic -fno-scaffold-stati= c -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=3D`${COMPILER} ${DIALECT} ${LIBRARY} ${MINIMAL} -fno-m2-plugi= n -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.68= 2097332 +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 . >> + >> +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 >> +. */ >> + >> + >> +#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 =3D=3D 1) >> +#endif >> + >> +#if !defined(FALSE) >> +#define FALSE (1 =3D=3D 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 =3D NULL; >> +static const char *NameOfMain =3D "main"; >> +static int StackPtr =3D 0; >> +static char Stack[MAXSTACK]; >> +static int CurrentFile =3D STDIN; >> +static int OutputFile; >> +static int LinkCommandLine =3D FALSE; >> +static int ProfilePCommand =3D FALSE; >> +static int ProfilePGCommand =3D FALSE; >> +static int ExitNeeded =3D TRUE; >> +static char *libraries =3D NULL; >> +static char *args =3D NULL; >> +static functList *head =3D NULL; >> +static functList *tail =3D NULL; >> +static int langC =3D FALSE; /* FALSE =3D C++, TRUE =3D C. */ >> + >> +/* addLibrary - adds libname to the list of libraries to be linked. */ >> + >> +static void >> +addLibrary (char *libname) >> +{ >> + if (libraries =3D=3D NULL) >> + libraries =3D strdup (libname); >> + else >> + { >> + char *old =3D libraries; >> + char *newlib >> + =3D (char *)malloc (strlen (libname) + strlen (libraries) + 1= + 1); >> + strcpy (newlib, libraries); >> + strcat (newlib, " "); >> + strcat (newlib, libname); >> + libraries =3D newlib; >> + free (old); >> + } >> +} >> + >> +/* addGccArg - adds arg to the list of gcc arguments. */ >> + >> +static void >> +addGccArg (char *arg) >> +{ >> + if (args =3D=3D NULL) >> + args =3D strdup (arg); >> + else >> + { >> + char *old =3D args; >> + char *newarg =3D (char *)malloc (strlen (old) + strlen (arg) + 1 = + 1); >> + strcpy (newarg, old); >> + strcat (newarg, " "); >> + strcat (newarg, arg); >> + args =3D newarg; >> + free (old); >> + } >> +} >> + >> +int >> +main (int argc, char *argv[]) >> +{ >> + int i; >> + >> + if (argc >=3D 3) >> + { >> + if (strcmp (argv[1], "-l") =3D=3D 0) >> + LinkCommandLine =3D TRUE; >> + else if (strcmp (argv[1], "-s") =3D=3D 0) >> + LinkCommandLine =3D FALSE; >> + else >> + { >> + fprintf (stderr, "Usage: mklink (-l|-s) [--langc|--langc++] [= --pg|-p] " >> + "[--lib library] [--main name] [--exit] --na= me " >> + "filename \n"); >> + fprintf (stderr, " must supply -l or -s option\n"); >> + exit (1); >> + } >> + ProfilePCommand =3D FALSE; >> + ProfilePGCommand =3D FALSE; >> + i =3D 2; >> + while (i < argc - 1) >> + { >> + if (strcmp (argv[i], "--langc++") =3D=3D 0) >> + langC =3D FALSE; >> + else if (strcmp (argv[i], "--langc") =3D=3D 0) >> + langC =3D TRUE; >> + else if (strncmp (argv[i], "-f", 2) =3D=3D 0) >> + addGccArg (argv[i]); >> + else if (strcmp (argv[i], "--pg") =3D=3D 0) >> + ProfilePGCommand =3D TRUE; >> + else if (strcmp (argv[i], "-p") =3D=3D 0) >> + ProfilePCommand =3D TRUE; >> + else if (strcmp (argv[i], "--exit") =3D=3D 0) >> + ExitNeeded =3D FALSE; >> + else if (strcmp (argv[i], "--lib") =3D=3D 0) >> + { >> + i++; >> + addLibrary (argv[i]); >> + } >> + else if (strcmp (argv[i], "--main") =3D=3D 0) >> + { >> + i++; >> + NameOfMain =3D argv[i]; >> + } >> + else if (strcmp (argv[i], "--name") =3D=3D 0) >> + { >> + i++; >> + NameOfFile =3D argv[i]; >> + } >> + i++; >> + } >> + ParseFile (argv[i]); >> + } >> + else >> + { >> + fprintf (stderr, "Usage: mklink (-l|-s) [--gcc|--g++] [--pg|-p] [= --lib " >> + "library] [--main name] [--exit] --name filename= " >> + "\n"); >> + exit (1); >> + } >> + if (NameOfFile =3D=3D 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= " >> + "\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 =3D NULL; >> + char *l =3D NULL; >> + char *c =3D NULL; >> + >> + s =3D getenv ("CC"); >> + if (s =3D=3D NULL) >> + { >> + if (langC) >> + printf ("gcc -g "); >> + else >> + printf ("g++ -g "); >> + } >> + else >> + printf ("%s -g ", s); >> + >> + if (args !=3D NULL) >> + printf ("%s ", args); >> + >> + l =3D getenv ("LDFLAGS"); >> + if (l !=3D NULL) >> + printf ("%s ", l); >> + >> + c =3D getenv ("CFLAGS"); >> + if (c !=3D NULL) >> + printf ("%s ", c); >> + >> + if (ProfilePGCommand) >> + printf (" -pg"); >> + else if (ProfilePCommand) >> + printf (" -p"); >> + >> + while (PutChar (GetChar ()) !=3D (char)EOF) >> + { >> + CopyUntilEolInto (name); >> +#if defined(XENIX) >> + name[10] =3D (char)0; /* truncate object file name. */ >> +#endif >> + if ((strlen (name) > 0) && (name[0] !=3D '#')) >> + 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") =3D=3D NULL) >> + strcpy (m2path, "."); >> + else >> + strcpy (m2path, getenv ("M2PATH")); >> + >> + snprintf (name, sizeof (name), "%s.o", Name); >> + p =3D 0; >> + while (m2path[p] !=3D (char)0) >> + { >> + s =3D 0; >> + while ((m2path[p] !=3D (char)0) && (m2path[p] !=3D ' ')) >> + { >> + m2search[s] =3D m2path[p]; >> + s++; >> + p++; >> + } >> + if (m2path[p] =3D=3D ' ') >> + p++; >> + m2search[s] =3D (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) =3D=3D 0); >> +} >> + >> +/* add_function - adds a name to the list of functions, in order. */ >> + >> +void >> +add_function (char *name) >> +{ >> + functList *p =3D (functList *)malloc (sizeof (functList)); >> + p->functname =3D (char *)malloc (strlen (name) + 1); >> + strcpy (p->functname, name); >> + >> + if (head =3D=3D NULL) >> + { >> + head =3D p; >> + tail =3D p; >> + p->next =3D NULL; >> + } >> + else >> + { >> + tail->next =3D p; >> + tail =3D p; >> + tail->next =3D NULL; >> + } >> +} >> + >> +static void >> +GenerateInitCalls (functList *p) >> +{ >> + while (p !=3D NULL) >> + { >> + printf (" _M2_%s_init (argc, argv, envp);\n", p->functname); >> + p =3D p->next; >> + } >> +} >> + >> +static void >> +GenerateFinishCalls (functList *p) >> +{ >> + if (p->next !=3D NULL) >> + GenerateFinishCalls (p->next); >> + printf (" _M2_%s_finish (argc, argv, envp);\n", p->functname); >> +} >> + >> +static void >> +GeneratePrototypes (functList *p) >> +{ >> + while (p !=3D NULL) >> + { >> + if (langC) >> + { >> + printf ("extern void _M2_%s_init (int argc, char *argv[], cha= r *envp[]);\n", >> + p->functname); >> + printf ("extern void _M2_%s_finish (int argc, char *argv[], c= har *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 *arg= v[], char *envp[]);\n", >> + p->functname); >> + } >> + p =3D p->next; >> + } >> +} >> + >> +/* ParseFileStartup - generates the startup code. */ >> + >> +static void >> +ParseFileStartup (void) >> +{ >> + char name[MAX_FILE_NAME]; >> + functList *p; >> + >> + while (PutChar (GetChar ()) !=3D (char)EOF) >> + { >> + CopyUntilEolInto (name); >> + if ((strlen (name) > 0) && (strcmp (name, "mod_init") !=3D 0) >> + && (name[0] !=3D '#')) >> + 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", NameOfM= ain); >> + 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, "-") !=3D 0) >> + { >> + if (close (STDOUT) !=3D 0) >> + { >> + ERROR ("Unable to close stdout"); >> + exit (1); >> + } >> + OutputFile =3D creat (NameOfFile, 0666); >> + if (OutputFile !=3D 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) !=3D 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 =3D GetChar ()) !=3D ENDOFILE) >> + putchar (ch); >> +} >> + >> +/* CopyUntilEol - copies from the current input marker until '\n' is >> + reached. */ >> + >> +static void >> +CopyUntilEol (void) >> +{ >> + char ch; >> + >> + while (((ch =3D GetChar ()) !=3D '\n') && (ch !=3D (char)EOF)) >> + putchar (ch); >> + if (ch =3D=3D '\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 =3D 0; >> + >> + while (((ch =3D GetChar ()) !=3D '\n') && (ch !=3D (char)EOF)) >> + { >> + Buffer[i] =3D ch; >> + i++; >> + } >> + if ((ch =3D=3D '\n') || (ch =3D=3D (char)EOF)) >> + Buffer[i] =3D (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 =3D 0; >> + >> + while ((s[i] !=3D (char)0) && (s[i] =3D=3D PutChar (GetChar ()))) >> + { >> + GetChar (); >> + i++; >> + } >> + if (s[i] =3D=3D (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 =3D 0; >> + >> + while ((s[i] !=3D (char)0) && (s[i] =3D=3D PutChar (GetChar ()))) >> + { >> + GetChar (); >> + i++; >> + } >> + if (s[i] =3D=3D (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 =3D 0; >> + int Found =3D FALSE; >> + int eof =3D FALSE; >> + char ch; >> + >> + while ((!Found) && (!eof)) >> + { >> + if (String[StringIndex] =3D=3D (char)0) >> + /* must have found string. */ >> + Found =3D TRUE; >> + else >> + { >> + ch =3D GetChar (); >> + eof =3D (ch =3D=3D ENDOFILE); >> + if (ch =3D=3D String[StringIndex]) >> + StringIndex++; >> + else >> + StringIndex =3D 0; >> + } >> + } >> + return (Found); >> +} >> + >> +/* GetNL - keeps on reading input from until a new line is found. */ >> + >> +static void >> +GetNL (void) >> +{ >> + char ch; >> + >> + while ((ch =3D GetChar ()) !=3D '\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 =3D 0; >> +static int AmountRead =3D 0; >> +static char Buffer[MAXBUF]; >> + >> +/* ResetBuffer - resets the buffer information to an initial state. */ >> + >> +static void >> +ResetBuffer (void) >> +{ >> + StackPtr =3D 0; >> + Pointer =3D 0; >> + AmountRead =3D 0; >> +} >> + >> +/* GetSingleChar - gets a single character from input. TRUE is >> + returned upon success. */ >> + >> +static int >> +GetSingleChar (char *ch) >> +{ >> + if (Pointer =3D=3D AmountRead) >> + { >> + AmountRead =3D read (CurrentFile, &Buffer, MAXBUF); >> + if (AmountRead < 0) >> + AmountRead =3D 0; >> + Pointer =3D 0; >> + } >> + if (Pointer =3D=3D AmountRead) >> + { >> + *ch =3D ENDOFILE; >> + return (FALSE); >> + } >> + else >> + { >> + *ch =3D 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 >=3D Min) && (Element <=3D Max)); >> +} >> + >> +/* PutChar - pushes a character back onto input. This character is >> + also returned. */ >> + >> +static char >> +PutChar (char ch) >> +{ >> + if (StackPtr < MAXSTACK) >> + { >> + Stack[StackPtr] =3D 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 =3D=3D ' ') || (ch =3D=3D '\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 =3D 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 =3D GetChar (); /* throw away character. */ >> +} >> + >> +/* PushBack - pushes a string, backwards onto the input stack. */ >> + >> +static void >> +PushBack (char *s) >> +{ >> + int i; >> + >> + i =3D 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 >=3D '0') && (ch <=3D '9'))); >> +} >> + >> +/* GetName - returns the next name found. */ >> + >> +static void >> +GetName (char *Name) >> +{ >> + int i; >> + char ch; >> + >> + SkipSpaces (); >> + ch =3D GetChar (); >> + i =3D 0; >> + while (!IsSpace (ch)) >> + { >> + Name[i] =3D ch; >> + i++; >> + ch =3D GetChar (); >> + } >> + Name[i] =3D '\0'; >> +} >> + >> +/* FindSource - open source file on StdIn. */ >> + >> +static void >> +FindSource (char *Name) >> +{ >> + if (close (STDIN) !=3D 0) >> + { >> + ERROR ("close on STDIN failed"); >> + } >> + CurrentFile =3D open (Name, O_RDONLY); >> + if (CurrentFile < 0) >> + { >> + perror ("failed to open file"); >> + exit (1); >> + } >> + if (CurrentFile !=3D 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 proce= dures. >> +# Contributed by Gaius Mulley . >> + >> +# 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 =3D [['gm2-libs','Base libraries', >> + 'Basic M2F compatible libraries'], >> + ['gm2-libs-pim','PIM and Logitech 3.0 Compati= ble', >> + '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 =3D False, False, False >> + >> + >> +# >> +# displayLibraryClass - displays a node for a library directory and in= vokes >> +# a routine to summarize each module >> +# >> + >> +def displayLibraryClass(): >> + global buildDir, up >> + previous =3D "" >> + >> + next=3DlibraryClassifications[1][1] >> + i =3D 0 >> + l =3D 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 =3D l[1] >> + i +=3D 1 >> + if i =3D=3D len(libraryClassifications): >> + break >> + l =3D libraryClassifications[i] >> + if i+1 =3D=3D len(libraryClassifications): >> + next =3D "" >> + else: >> + next =3D 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= ") >> + print("\n") >> + >> + >> +# >> +# removeInitialComments - removes any (* *) at the top of the definiti= on module >> +# >> + >> +def removeInitialComments (file, line): >> + while (str.find(line, "*)") =3D=3D -1): >> + line =3D 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, "*)") =3D=3D -1): >> + if (str.find(line, "Author") !=3D -1) and (str.find(line, ":") = !=3D -1): >> + line =3D file.readline() >> + elif (str.find(line, "Last edit") !=3D -1) and (str.find(line, = ":") !=3D -1): >> + line =3D file.readline() >> + elif (str.find(line, "LastEdit") !=3D -1) and (str.find(line, "= :") !=3D -1): >> + line =3D file.readline() >> + elif (str.find(line, "Last update") !=3D -1) and (str.find(line= , ":") !=3D -1): >> + line =3D file.readline() >> + elif (str.find(line, "Date") !=3D -1) and (str.find(line, ":") = !=3D -1): >> + line =3D file.readline() >> + elif (str.find(line, "Title") !=3D -1) and (str.find(line, ":")= !=3D -1): >> + line =3D file.readline() >> + elif (str.find(line, "Revision") !=3D -1) and (str.find(line, "= :") !=3D -1): >> + line =3D file.readline() >> + elif (str.find(line, "System") !=3D -1) and (str.find(line, ":"= ) !=3D -1) and (str.find(line, "Description:") =3D=3D -1): >> + line =3D file.readline() >> + elif (str.find(line, "SYSTEM") !=3D -1) and (str.find(line, ":"= ) !=3D -1) and (str.find(line, "Description:") =3D=3D -1): >> + line =3D file.readline() >> + else: >> + print(str.replace(str.replace(str.rstrip(line), >> + "{", "@{"), "}", "@}")) >> + line =3D file.readline() >> + print(str.rstrip(line)) >> + >> + >> +# >> +# checkIndex >> +# >> + >> +def checkIndex (line): >> + global inVar, inType, inConst >> + >> + words =3D str.split(line) >> + procedure =3D "" >> + if (len(words)>1) and (words[0] =3D=3D "PROCEDURE"): >> + inConst =3D False >> + inType =3D False >> + inVar =3D False >> + if (words[1] =3D=3D "__BUILTIN__") and (len(words)>2): >> + procedure =3D words[2] >> + else: >> + procedure =3D words[1] >> + >> + if (len(line)>1) and (line[0:2] =3D=3D '(*'): >> + inConst =3D False >> + inType =3D False >> + inVar =3D False >> + elif line =3D=3D "VAR": >> + inConst =3D False >> + inVar =3D True >> + inType =3D False >> + return >> + elif line =3D=3D "TYPE": >> + inConst =3D False >> + inType =3D True >> + inVar =3D False >> + return >> + elif line =3D=3D "CONST": >> + inConst =3D True >> + inType =3D False >> + inVar =3D False >> + >> + if inVar: >> + words =3D str.split(line, ',') >> + for word in words: >> + word =3D str.lstrip(word) >> + if word !=3D "": >> + if str.find(word, ':') =3D=3D -1: >> + print("@findex " + word + " (var)") >> + elif len(word)>0: >> + var =3D str.split(word, ':') >> + if len(var)>0: >> + print("@findex " + var[0] + " (var)") >> + >> + if inType: >> + words =3D str.lstrip(line) >> + if str.find(words, '=3D') !=3D -1: >> + word =3D str.split(words, "=3D") >> + if (len(word[0])>0) and (word[0][0] !=3D '_'): >> + print("@findex " + str.rstrip(word[0]) + " (type)") >> + else: >> + word =3D str.split(words) >> + if (len(word)>1) and (word[1] =3D=3D ';'): >> + # hidden type >> + if (len(word[0])>0) and (word[0][0] !=3D '_'): >> + print("@findex " + str.rstrip(word[0]) + " (type)") >> + >> + if inConst: >> + words =3D str.split(line, ';') >> + for word in words: >> + word =3D str.lstrip(word) >> + if word !=3D "": >> + if str.find(word, '=3D') !=3D -1: >> + var =3D str.split(word, '=3D') >> + if len(var)>0: >> + print("@findex " + var[0] + " (const)") >> + >> + if procedure !=3D "": >> + name =3D str.split(procedure, "(") >> + if name[0] !=3D "": >> + proc =3D name[0] >> + if proc[-1] =3D=3D ";": >> + proc =3D proc[:-1] >> + if proc !=3D "": >> + print("@findex " + proc) >> + >> + >> +# >> +# parseDefinition >> +# >> + >> +def parseDefinition (dir, source, build, file, needPage): >> + print("") >> + f =3D open(findFile(dir, build, source, file), 'r') >> + initState() >> + line =3D f.readline() >> +# while (str.find(line, "(*") !=3D -1): >> + while (str.find(line, "(*") !=3D -1): >> + removeInitialComments(f, line) >> + line =3D f.readline() >> + >> + while (str.find(line, "DEFINITION") =3D=3D -1): >> + line =3D f.readline() >> + >> + print("@example") >> + print(str.rstrip(line)) >> + line =3D f.readline() >> + if len(str.rstrip(line)) =3D=3D 0: >> + print(str.replace(str.replace(str.rstrip(line), >> + "{", "@{"), "}", "@}")) >> + line =3D f.readline() >> + if (str.find(line, "(*") !=3D -1): >> + removeFields(f, line) >> + else: >> + print(str.rstrip(line)) >> + else: >> + print(str.rstrip(line)) >> + >> + line =3D f.readline() >> + while line: >> + line =3D str.rstrip(line) >> + checkIndex(line) >> + print(str.replace(str.replace(line, "{", "@{"), "}", "@}")) >> + line =3D f.readline() >> + print("@end example") >> + if needPage: >> + print("@page") >> + f.close() >> + >> +def parseModules (up, dir, build, source, listOfModules): >> + previous =3D "" >> + i =3D 0 >> + if len(listOfModules)>1: >> + next =3D dir + "/" + listOfModules[1][:-4] >> + else: >> + next =3D "" >> + >> + while i> + 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 =3D dir + "/" + listOfModules[i][:-4] >> + i =3D i + 1 >> + if i+1> + next =3D dir + "/" + listOfModules[i+1][:-4] >> + else: >> + next =3D "" >> + >> + >> +# >> +# doCat - displays the contents of file, name, to stdout >> +# >> + >> +def doCat (name): >> + file =3D open(name, 'r') >> + line =3D file.readline() >> + while line: >> + print(str.rstrip(line)) >> + line =3D file.readline() >> + file.close() >> + >> + >> +# >> +# moduleMenu - generates a simple menu for all definition modules >> +# in dir >> +# >> + >> +def moduleMenu (dir, build, source): >> + print("@menu") >> + listOfFiles =3D [] >> + if os.path.exists(os.path.join(source, dir)): >> + listOfFiles +=3D os.listdir(os.path.join(source, dir)) >> + if os.path.exists(os.path.join(source, dir)): >> + listOfFiles +=3D os.listdir(os.path.join(build, dir)) >> + listOfFiles =3D list(dict.fromkeys(listOfFiles).keys()) >> + listOfFiles.sort() >> + for file in listOfFiles: >> + if foundFile(dir, build, source, file): >> + if (len(file)>4) and (file[-4:] =3D=3D '.def'): >> + print("* " + dir + "/" + file[:-4] + "::" + file) >> + print("@end menu") >> + print("\n") >> + >> + >> +# >> +# checkDirectory - returns True if dir exists in either build or sourc= e. >> +# >> + >> +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 =3D os.path.join(os.path.join(build, dir), file) >> + if os.path.exists(name): >> + return True >> + name =3D 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 =3D os.path.join(os.path.join(build, dir), file) >> + if os.path.exists(name1): >> + return name1 >> + name2 =3D 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 =3D [] >> + if os.path.exists(os.path.join(source, dir)): >> + listOfFiles +=3D os.listdir(os.path.join(source, dir)) >> + if os.path.exists(os.path.join(source, dir)): >> + listOfFiles +=3D os.listdir(os.path.join(build, dir)) >> + listOfFiles =3D list(dict.fromkeys(listOfFiles).keys()) >> + listOfFiles.sort() >> + listOfModules =3D [] >> + for file in listOfFiles: >> + if foundFile(dir, build, source, file): >> + if (len(file)>4) and (file[-4:] =3D=3D '.def'): >> + listOfModules +=3D [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=3D"." >> + sourceDir=3D"." >> + filename=3D"" >> + up=3D"" >> + try: >> + optlist, list =3D getopt.getopt(sys.argv[1:],':hb:f:s:u:') >> + except getopt.GetoptError: >> + Usage() >> + os.sys.exit(1) >> + for opt in optlist: >> + if opt[0] =3D=3D '-h': >> + Usage() >> + if opt[0] =3D=3D '-b': >> + buildDir =3D opt[1] >> + if opt[0] =3D=3D '-f': >> + filename =3D opt[1] >> + if opt[0] =3D=3D '-s': >> + sourceDir =3D opt[1] >> + if opt[0] =3D=3D '-u': >> + up =3D opt[1] >> + return buildDir, sourceDir, filename, up >> + >> + >> +buildDir, sourceDir, filename, up =3D collectArgs() >> + >> +if filename =3D=3D "": >> + displayCopyright() >> + displayMenu() >> + displayLibraryClass() >> +else: >> + parseDefinition('.', sourceDir, buildDir, filename, False)