Running milltask (or gcode interp) without python?

More
4 years 9 months ago #230963 by mungkie

You never really answered why you want to remove python.
I would ask the same question if someone wanted to get rid of c or c++ too.

What is you ultimate goal here?
 
Ultimately eternal life by evolving into pure coherent controlled energy. image missing /media/kunena/emoticons/cool.png

I really find that difficult to answer without wasting even more time though.
I suppose this maybe due to efficiency of language or information transfer, in the begining it has to be put into words.

I supose the main factors in messing with this python thing is newtons first and thermal S.

I am not trying to start a fork tongue, but it seemed trying to compile python for my system was a huge amount more work than trying to get linuxcnc to work with python stripped out. I am probably wrong, and this is just a hobby project so will probably be dumped in the trash in a few weeks or days depending on stuff?

Obviously you know what you are talking about and are hoping to get me to find a solution using python, unfortunately I am trying to find a solution without using python (I think that means no dependency on python is part of the ultimate goal).

I know everything is complicated and linuxcnc is a pretty large codebase and I know I don't understand it properly, and unfortunately every new addition adds more complexity, sometimes with people reimplementing wheels that are already in the system only because they did not understand what had already been implemented, sometimes people implementing things suboptimally becuase it was the only way that could be seen to easily get what was required.

Anyways thanks for trying to help cmorely, I am probably going to mess around with things a bit more and see what I can misunderstand or learn.Bababadalgharaghtakamminarronnkonnbronntonnerronntuonnthunntrovarrhounawnskawntoohoohoordenenthurnuk


 

Please Log in or Create an account to join the conversation.

More
4 years 9 months ago #230999 by cakeslob
Well, what ever you reasons are, and without knowing what im talking about, I will go out on a limb and say you probably cant. I base this answer solely on what I have read from grotius. I dont know how to use a computer, but I know grotius knows how. He has some kind of issue with the python involved with linuxcnc, so he has been working on something sans python, i think it was something realtime related, but most of the things he says are too complicated for me to understand. So without knowing what Im talking about I will assume you cannot run lcnc without python.
I recommend reading through his threads on the forum, and checking out his github page

forum.linuxcnc.org/47-hal-examples/43333-hal-core?start=0

github.com/grotius-cnc/hal-core

Please Log in or Create an account to join the conversation.

More
4 years 9 months ago #231012 by cmorley
I asked the question because it sounded like an XY question.
en.wikipedia.org/wiki/XY_problem

If you want to make linuxcnc python-less just because, sounds fine by me - but you're not gonna get much help. Python is an important part of the project.
(I'd be happier if linuxcnc was tcl-less but some people like it.)

If you having problem compiling python libraries - you probably could get some help there.
You must be using an odd (to us) distribution.

Chris

Please Log in or Create an account to join the conversation.

More
4 years 9 months ago #231055 by mungkie
So I did not really mess much last night other than a quick check on what I had actually done to the code that I hacked.

previously I just #ifdef PYTHONO out anything that referenced python after initially trying to puzzle out what     
Code:
callmethod and Py_XDECREF
did and then thinking it was too much work to figure out so ignore it until I test.

So the test did not work and I am looking at the defines for the python 'callmethod'  below it sort of looks like it should be calling some function in an external python script, but maybe it is just changing the data in the straight_feed struct???????

I should probably ask someone in the devel mailing list, but does anyone know what "callmethod" does, I have never used CPython/PyObject and don't really want to learn so hoping a quick hack can suffice, maybe I will just try to change the  straight_feed struct which I guess is the real location of the motion position target?

I initially assumed the globals  _pos_x=x; _pos_y=y; _pos_z=z;    _pos_a=a; _pos_b=b; _pos_c=c;    _pos_u=u; _pos_v=v; _pos_w=w;
set the target?

I am guessing the string "straight_list" searches for pointer to straight_feed in some global queued_canon struct?

I will keep on messing......
Code:
#define callmethod(o, m, f, ...) PyObject_CallMethod((o), (char*)(m), (char*)(f), ## __VA_ARGS__) void STRAIGHT_FEED(int line_number,                    double x, double y, double z,                    double a, double b, double c,                    double u, double v, double w) {     _pos_x=x; _pos_y=y; _pos_z=z;     _pos_a=a; _pos_b=b; _pos_c=c;     _pos_u=u; _pos_v=v; _pos_w=w;     if(metric) { x /= 25.4; y /= 25.4; z /= 25.4; u /= 25.4; v /= 25.4; w /= 25.4; }     maybe_new_line(line_number);     if(interp_error) return; #ifdef PYTHONO     PyObject *result =         callmethod(callback, "straight_feed", "fffffffff",                             x, y, z, a, b, c, u, v, w);     if(result == NULL) interp_error ++;     Py_XDECREF(result); #endif }





 

Please Log in or Create an account to join the conversation.

More
4 years 9 months ago #232370 by mungkie
Yeah, seems I made a stupid mistake and ifdef'd some necessary sections, then confused myself with other problems.
Seems that I can run full gcode program without any python on the system (obviously no remap of codes).

Part of my other problem seems to be relevant to this thread :

forum.linuxcnc.org/24-hal-components/285...my-hal-comp?start=20

I could not see anthing in extra_link_args so I botched in something myself (I am not good at python so not sure but I post my hack below)
Code:
halcompile --lib=-lposemath --install mykinesmodule.c

the halcompile hacked code:
Code:
#!/usr/bin/python3.7 #    This is 'halcompile', a tool to write HAL boilerplate #    Copyright 2006 Jeff Epler <jepler@unpythonic.net> # #    This program 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 2 of the License, or #    (at your option) any later version. # #    This program 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 this program; if not, write to the Free Software #    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # Begin -- grammar generated by Yapps from __future__ import print_function import sys, re from yapps import runtime global extra_libs extra_libs = " " class HalScanner(runtime.Scanner):     patterns = [         ('"FALSE"', re.compile('FALSE')),         ('"TRUE"', re.compile('TRUE')),         ('"false"', re.compile('false')),         ('"true"', re.compile('true')),         ('"no"', re.compile('no')),         ('"yes"', re.compile('yes')),         ('"nofp"', re.compile('nofp')),         ('"fp"', re.compile('fp')),         ('"="', re.compile('=')),         ('":"', re.compile(':')),         ('"\\]"', re.compile('\\]')),         ('"\\["', re.compile('\\[')),         ('"if"', re.compile('if')),         ('"modparam"', re.compile('modparam')),         ('"include"', re.compile('include')),         ('"author"', re.compile('author')),         ('"license"', re.compile('license')),         ('"description"', re.compile('description')),         ('"notes"', re.compile('notes')),         ('"see_also"', re.compile('see_also')),         ('"option"', re.compile('option')),         ('"variable"', re.compile('variable')),         ('"function"', re.compile('function')),         ('"param"', re.compile('param')),         ('"pin"', re.compile('pin')),         ('";"', re.compile(';')),         ('"component"', re.compile('component')),         ('"$"', re.compile('$')),         ('//.*', re.compile('//.*')),         ('/[*](.|\n)*?[*]/', re.compile('/[*](.|\n)*?[*]/')),         ('[ \t\r\n]+', re.compile('[ \t\r\n]+')),         ('END', re.compile(';;')),         ('PARAMDIRECTION', re.compile('rw|r')),         ('PINDIRECTION', re.compile('in|out|io')),         ('TYPE', re.compile('float|bit|signed|unsigned|u32|s32')),         ('NAME', re.compile('[a-zA-Z_][a-zA-Z0-9_]*')),         ('STARREDNAME', re.compile('[*]*[a-zA-Z_][a-zA-Z0-9_]*')),         ('HALNAME', re.compile('[#a-zA-Z_][-#a-zA-Z0-9_.]*')),         ('FPNUMBER', re.compile('-?([0-9]*\\.[0-9]+|[0-9]+\\.?)([Ee][+-]?[0-9]+)?f?')),         ('NUMBER', re.compile('0x[0-9a-fA-F]+|[+-]?[0-9]+')),         ('STRING', re.compile('"(\\.|[^\\"])*"')),         ('HEADER', re.compile('<.*?>')),         ('POP', re.compile('[-()+*/:?]|&&|\\|\\||personality|==|&|!=|<<|<|<=|>>|>|>=')),         ('TSTRING', re.compile('r?"""(\\.|\\\n|[^\\"]|"(?!"")|\n)*"""')),     ]     def __init__(self, str,*args,**kw):         runtime.Scanner.__init__(self,None,{'//.*':None,'/[*](.|\n)*?[*]/':None,'[ \t\r\n]+':None,},str,*args,**kw) class Hal(runtime.Parser):     Context = runtime.Context     def File(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'File', [])         ComponentDeclaration = self.ComponentDeclaration(_context)         while self._peek('"$"', '"pin"', '"param"', '"function"', '"variable"', '"option"', '"see_also"', '"notes"', '"description"', '"license"', '"author"', '"include"', '"modparam"', context=_context) != '"$"':             Declaration = self.Declaration(_context)         self._scan('"$"', context=_context)         return True     def ComponentDeclaration(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'ComponentDeclaration', [])         self._scan('"component"', context=_context)         NAME = self._scan('NAME', context=_context)         OptString = self.OptString(_context)         self._scan('";"', context=_context)         comp(NAME, OptString);     def Declaration(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'Declaration', [])         _token = self._peek('"pin"', '"param"', '"function"', '"variable"', '"option"', '"see_also"', '"notes"', '"description"', '"license"', '"author"', '"include"', '"modparam"', context=_context)         if _token == '"pin"':             self._scan('"pin"', context=_context)             PINDIRECTION = self._scan('PINDIRECTION', context=_context)             TYPE = self._scan('TYPE', context=_context)             HALNAME = self._scan('HALNAME', context=_context)             OptArray = self.OptArray(_context)             OptSAssign = self.OptSAssign(_context)             OptPersonality = self.OptPersonality(_context)             OptString = self.OptString(_context)             self._scan('";"', context=_context)             pin(HALNAME, TYPE, OptArray, PINDIRECTION, OptString, OptSAssign, OptPersonality)         elif _token == '"param"':             self._scan('"param"', context=_context)             PARAMDIRECTION = self._scan('PARAMDIRECTION', context=_context)             TYPE = self._scan('TYPE', context=_context)             HALNAME = self._scan('HALNAME', context=_context)             OptArray = self.OptArray(_context)             OptSAssign = self.OptSAssign(_context)             OptPersonality = self.OptPersonality(_context)             OptString = self.OptString(_context)             self._scan('";"', context=_context)             param(HALNAME, TYPE, OptArray, PARAMDIRECTION, OptString, OptSAssign, OptPersonality)         elif _token == '"function"':             self._scan('"function"', context=_context)             NAME = self._scan('NAME', context=_context)             OptFP = self.OptFP(_context)             OptString = self.OptString(_context)             self._scan('";"', context=_context)             function(NAME, OptFP, OptString)         elif _token == '"variable"':             self._scan('"variable"', context=_context)             NAME = self._scan('NAME', context=_context)             STARREDNAME = self._scan('STARREDNAME', context=_context)             OptSimpleArray = self.OptSimpleArray(_context)             OptAssign = self.OptAssign(_context)             self._scan('";"', context=_context)             variable(NAME, STARREDNAME, OptSimpleArray, OptAssign)         elif _token == '"option"':             self._scan('"option"', context=_context)             NAME = self._scan('NAME', context=_context)             OptValue = self.OptValue(_context)             self._scan('";"', context=_context)             option(NAME, OptValue)         elif _token == '"see_also"':             self._scan('"see_also"', context=_context)             String = self.String(_context)             self._scan('";"', context=_context)             see_also(String)         elif _token == '"notes"':             self._scan('"notes"', context=_context)             String = self.String(_context)             self._scan('";"', context=_context)             notes(String)         elif _token == '"description"':             self._scan('"description"', context=_context)             String = self.String(_context)             self._scan('";"', context=_context)             description(String)         elif _token == '"license"':             self._scan('"license"', context=_context)             String = self.String(_context)             self._scan('";"', context=_context)             license(String)         elif _token == '"author"':             self._scan('"author"', context=_context)             String = self.String(_context)             self._scan('";"', context=_context)             author(String)         elif _token == '"include"':             self._scan('"include"', context=_context)             Header = self.Header(_context)             self._scan('";"', context=_context)             include(Header)         else: # == '"modparam"'             self._scan('"modparam"', context=_context)             NAME = self._scan('NAME', context=_context)             NAME1=NAME;             NAME = self._scan('NAME', context=_context)             OptSAssign = self.OptSAssign(_context)             OptString = self.OptString(_context)             self._scan('";"', context=_context)             modparam(NAME1, NAME, OptSAssign, OptString)     def Header(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'Header', [])         _token = self._peek('STRING', 'HEADER', context=_context)         if _token == 'STRING':             STRING = self._scan('STRING', context=_context)             return STRING         else: # == 'HEADER'             HEADER = self._scan('HEADER', context=_context)             return HEADER     def String(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'String', [])         _token = self._peek('TSTRING', 'STRING', context=_context)         if _token == 'TSTRING':             TSTRING = self._scan('TSTRING', context=_context)             return eval(TSTRING)         else: # == 'STRING'             STRING = self._scan('STRING', context=_context)             return eval(STRING)     def OptPersonality(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptPersonality', [])         _token = self._peek('"if"', '";"', 'TSTRING', 'STRING', context=_context)         if _token == '"if"':             self._scan('"if"', context=_context)             Personality = self.Personality(_context)             return Personality         else: # in ['";"', 'TSTRING', 'STRING']             return None     def Personality(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'Personality', [])         pp = []         while self._peek('NUMBER', 'POP', '"\\]"', '";"', 'TSTRING', 'STRING', context=_context) in ['NUMBER', 'POP']:             PersonalityPart = self.PersonalityPart(_context)             pp.append(PersonalityPart)         return " ".join(pp)     def PersonalityPart(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'PersonalityPart', [])         _token = self._peek('NUMBER', 'POP', context=_context)         if _token == 'NUMBER':             NUMBER = self._scan('NUMBER', context=_context)             return NUMBER         else: # == 'POP'             POP = self._scan('POP', context=_context)             return POP     def OptSimpleArray(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptSimpleArray', [])         _token = self._peek('"\\["', '";"', '"="', context=_context)         if _token == '"\\["':             self._scan('"\\["', context=_context)             NUMBER = self._scan('NUMBER', context=_context)             self._scan('"\\]"', context=_context)             return int(NUMBER)         else: # in ['";"', '"="']             return 0     def OptArray(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptArray', [])         _token = self._peek('"\\["', '"="', '"if"', '";"', 'TSTRING', 'STRING', context=_context)         if _token == '"\\["':             self._scan('"\\["', context=_context)             NUMBER = self._scan('NUMBER', context=_context)             OptArrayPersonality = self.OptArrayPersonality(_context)             self._scan('"\\]"', context=_context)             return OptArrayPersonality and (int(NUMBER), OptArrayPersonality) or int(NUMBER)         else: # in ['"="', '"if"', '";"', 'TSTRING', 'STRING']             return 0     def OptArrayPersonality(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptArrayPersonality', [])         _token = self._peek('":"', '"\\]"', context=_context)         if _token == '":"':             self._scan('":"', context=_context)             Personality = self.Personality(_context)             return Personality         else: # == '"\\]"'             return None     def OptString(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptString', [])         _token = self._peek('TSTRING', 'STRING', '";"', context=_context)         if _token == 'TSTRING':             TSTRING = self._scan('TSTRING', context=_context)             return eval(TSTRING)         elif _token == 'STRING':             STRING = self._scan('STRING', context=_context)             return eval(STRING)         else: # == '";"'             return ''     def OptAssign(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptAssign', [])         _token = self._peek('"="', '";"', context=_context)         if _token == '"="':             self._scan('"="', context=_context)             Value = self.Value(_context)             return Value;         else: # == '";"'             return None     def OptSAssign(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptSAssign', [])         _token = self._peek('"="', '"if"', '";"', 'TSTRING', 'STRING', context=_context)         if _token == '"="':             self._scan('"="', context=_context)             SValue = self.SValue(_context)             return SValue;         else: # in ['"if"', '";"', 'TSTRING', 'STRING']             return None     def OptFP(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptFP', [])         _token = self._peek('"fp"', '"nofp"', '";"', 'TSTRING', 'STRING', context=_context)         if _token == '"fp"':             self._scan('"fp"', context=_context)             return 1         elif _token == '"nofp"':             self._scan('"nofp"', context=_context)             return 0         else: # in ['";"', 'TSTRING', 'STRING']             return 1     def Value(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'Value', [])         _token = self._peek('"yes"', '"no"', '"true"', '"false"', '"TRUE"', '"FALSE"', 'NAME', 'FPNUMBER', 'NUMBER', context=_context)         if _token == '"yes"':             self._scan('"yes"', context=_context)             return 1         elif _token == '"no"':             self._scan('"no"', context=_context)             return 0         elif _token == '"true"':             self._scan('"true"', context=_context)             return 1         elif _token == '"false"':             self._scan('"false"', context=_context)             return 0         elif _token == '"TRUE"':             self._scan('"TRUE"', context=_context)             return 1         elif _token == '"FALSE"':             self._scan('"FALSE"', context=_context)             return 0         elif _token == 'NAME':             NAME = self._scan('NAME', context=_context)             return NAME         elif _token == 'FPNUMBER':             FPNUMBER = self._scan('FPNUMBER', context=_context)             return float(FPNUMBER.rstrip("f"))         else: # == 'NUMBER'             NUMBER = self._scan('NUMBER', context=_context)             return int(NUMBER,0)     def SValue(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'SValue', [])         _token = self._peek('"yes"', '"no"', '"true"', '"false"', '"TRUE"', '"FALSE"', 'NAME', 'FPNUMBER', 'NUMBER', context=_context)         if _token == '"yes"':             self._scan('"yes"', context=_context)             return "yes"         elif _token == '"no"':             self._scan('"no"', context=_context)             return "no"         elif _token == '"true"':             self._scan('"true"', context=_context)             return "true"         elif _token == '"false"':             self._scan('"false"', context=_context)             return "false"         elif _token == '"TRUE"':             self._scan('"TRUE"', context=_context)             return "TRUE"         elif _token == '"FALSE"':             self._scan('"FALSE"', context=_context)             return "FALSE"         elif _token == 'NAME':             NAME = self._scan('NAME', context=_context)             return NAME         elif _token == 'FPNUMBER':             FPNUMBER = self._scan('FPNUMBER', context=_context)             return FPNUMBER         else: # == 'NUMBER'             NUMBER = self._scan('NUMBER', context=_context)             return NUMBER     def OptValue(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptValue', [])         _token = self._peek('"yes"', '"no"', '"true"', '"false"', '"TRUE"', '"FALSE"', 'NAME', 'FPNUMBER', 'NUMBER', 'TSTRING', 'STRING', '";"', context=_context)         if _token not in ['TSTRING', 'STRING', '";"']:             Value = self.Value(_context)             return Value         elif _token == 'TSTRING':             TSTRING = self._scan('TSTRING', context=_context)             return eval(TSTRING)         elif _token == 'STRING':             STRING = self._scan('STRING', context=_context)             return eval(STRING)         else: # == '";"'             return 1     def OptSValue(self, _parent=None):         _context = self.Context(_parent, self._scanner, 'OptSValue', [])         _token = self._peek('"yes"', '"no"', '"true"', '"false"', '"TRUE"', '"FALSE"', 'NAME', 'FPNUMBER', 'NUMBER', context=_context)         SValue = self.SValue(_context)         return SValue def parse(rule, text):     P = Hal(HalScanner(text))     return runtime.wrap_error_reporter(P, rule) # End -- grammar generated by Yapps import os, sys, tempfile, shutil, getopt, time BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "..")) BINDIR = os.getenv('USER_MODULE_DIR', None) or os.path.join(BASE, "bin") sys.path.insert(0, os.path.join(BASE, "lib", "python")) MAX_USERSPACE_NAMES = 16 # for userspace (loadusr) components # NOTE: names are assigned dynamically for realtime components (loadrt) # Components that use 'personality' features statically allocate # memory based on MAX_PERSONALITIES (RTAPI_MP_ARRAY_INT) # The number can be set with the cmdline option -P|--personalities # Smaller values may be useful since the index of the personality # exported is computed modulo MAX_PERSONALITIES MAX_PERSONALITIES = 64 mp_decl_map = {'int': 'RTAPI_MP_INT', 'dummy': None} # These are symbols that comp puts in the global namespace of the C file it # creates.  The user is thus not allowed to add any symbols with these # names.  That includes not only global variables and functions, but also # HAL pins & parameters, because comp adds #defines with the names of HAL # pins & params. reserved_names = [ 'comp_id', 'fperiod', 'rtapi_app_main', 'rtapi_app_exit', 'extra_setup', 'extra_cleanup' ] def _parse(rule, text, filename=None):     global P, S     S = HalScanner(text, filename=filename)     P = Hal(S)     return runtime.wrap_error_reporter(P, rule) def parse(filename):     initialize()     f = open(filename).read()     if '\r' in f:         if require_unix_line_endings:             raise SystemExit("%s:0: Error: File contains DOS-style or Mac-style line endings." % filename)         else:             print("%s:0: Warning: File contains DOS-style or Mac-style line endings." % filename, file=sys.stderr)         f = open(filename, "rU").read()     a, b = f.split("\n;;\n", 1)     p = _parse('File', a + "\n\n", filename)     if not p: raise SystemExit(1)     if require_license:         if not finddoc('license'):             raise SystemExit("%s:0: License not specified" % filename)     return a, b dirmap = {'r': 'HAL_RO', 'rw': 'HAL_RW', 'in': 'HAL_IN', 'out': 'HAL_OUT', 'io': 'HAL_IO' } typemap = {'signed': 's32', 'unsigned': 'u32'} deprmap = {'s32': 'signed', 'u32': 'unsigned'} deprecated = ['s32', 'u32'] def initialize():     global functions, params, pins, options, comp_name, names, docs, variables     global modparams, includes     functions = []; params = []; pins = []; options = {}; variables = []     modparams = []; docs = []; includes = [];     comp_name = None     names = {} def Warn(msg, *args):     if args:         msg = msg % args     print("%s:%d: Warning: %s" % (S.filename, S.line, msg), file=sys.stderr) def Error(msg, *args):     if args:         msg = msg % args     raise runtime.SyntaxError(S.get_pos(), msg, None) def comp(name, doc):     docs.append(('component', name, doc))     global comp_name     if comp_name:         Error("Duplicate specification of component name")     comp_name = name; def description(doc):     docs.append(('descr', doc)); def license(doc):     docs.append(('license', doc)); def author(doc):     docs.append(('author', doc)); def see_also(doc):     docs.append(('see_also', doc)); def notes(doc):     docs.append(('notes', doc)); def type2type(type):     # When we start warning about s32/u32 this is where the warning goes     return typemap.get(type, type)      def checkarray(name, array):     hashes = len(re.findall("#+", name))     if array:         if hashes == 0: Error("Array name contains no #: %r" % name)         if hashes > 1: Error("Array name contains more than one block of #: %r" % name)     else:         if hashes > 0: Error("Non-array name contains #: %r" % name) def check_name_ok(name):     if name in reserved_names:         Error("Variable name %s is reserved" % name)     if name in names:         Error("Duplicate item name %s" % name) def pin(name, type, array, dir, doc, value, personality):     checkarray(name, array)     type = type2type(type)     check_name_ok(name)     docs.append(('pin', name, type, array, dir, doc, value, personality))     names[name] = None     pins.append((name, type, array, dir, value, personality)) def param(name, type, array, dir, doc, value, personality):     checkarray(name, array)     type = type2type(type)     check_name_ok(name)     docs.append(('param', name, type, array, dir, doc, value, personality))     names[name] = None     params.append((name, type, array, dir, value, personality)) def function(name, fp, doc):     check_name_ok(name)     docs.append(('funct', name, fp, doc))     names[name] = None     functions.append((name, fp)) def option(name, value):     if name in options:         Error("Duplicate option name %s" % name)     options[name] = value def variable(type, name, array, default):     check_name_ok(name)     names[name] = None     variables.append((type, name, array, default)) def modparam(type, name, default, doc):     check_name_ok(name)     names[name] = None     modparams.append((type, name, default, doc)) def include(value):     includes.append((value)) def removeprefix(s,p):     if s.startswith(p): return s[len(p):]     return s def to_hal(name):     name = re.sub("#+", lambda m: "%%0%dd" % len(m.group(0)), name)     return name.replace("_", "-").rstrip("-").rstrip(".") def to_c(name):     name = re.sub("[-._]*#+", "", name)     name = name.replace("#", "").replace(".", "_").replace("-", "_")     return re.sub("_+", "_", name) def prologue(f):     print("/* Autogenerated by %s on %s -- do not edit */" % (         sys.argv[0], time.asctime()), file=f)     print("""\ #include "rtapi.h" #ifdef RTAPI #include "rtapi_app.h" #endif #include "rtapi_string.h" #include "rtapi_errno.h" #include "hal.h" #include "rtapi_math64.h" static int comp_id; """, file=f)     for name in includes:         print("#include %s" % name, file=f)     names = {}     def q(s):         s = s.replace("\\", "\\\\")         s = s.replace("\"", "\\\"")         s = s.replace("\r", "\\r")         s = s.replace("\n", "\\n")         s = s.replace("\t", "\\t")         s = s.replace("\v", "\\v")         return '"%s"' % s     print("#ifdef MODULE_INFO", file=f)     for v in docs:         if not v: continue         v = ":".join(map(str, v))         print("MODULE_INFO(linuxcnc, %s);" % q(v), file=f)         license = finddoc('license')     if license and license[1]:         print("MODULE_LICENSE(\"%s\");" % license[1].split("\n")[0], file=f)     print("#endif // MODULE_INFO", file=f)     print("", file=f)     has_data = options.get("data")     has_array = False     has_personality = False     for name, type, array, dir, value, personality in pins:         if array: has_array = True         if isinstance(array, tuple): has_personality = True         if personality: has_personality = True     for name, type, array, dir, value, personality in params:         if array: has_array = True         if isinstance(array, tuple): has_personality = True         if personality: has_personality = True     for type, name, default, doc in modparams:         decl = mp_decl_map[type]         if decl:             print("%s %s" % (type, name), end=' ', file=f)             if default: print("= %s;" % default, file=f)             else: print(";", file=f)             print("%s(%s, %s);" % (decl, name, q(doc)), file=f)                  print("", file=f)     print("struct __comp_state {", file=f)     print("    struct __comp_state *_next;", file=f)     if has_personality:         print("    int _personality;", file=f)     for name, type, array, dir, value, personality in pins:         if array:             if isinstance(array, tuple): array = array[0]             print("    hal_%s_t *%s[%s];" % (type, to_c(name), array), file=f)         else:             print("    hal_%s_t *%s;" % (type, to_c(name)), file=f)         names[name] = 1     for name, type, array, dir, value, personality in params:         if array:             if isinstance(array, tuple): array = array[0]             print("    hal_%s_t %s[%s];" % (type, to_c(name), array), file=f)         else:             print("    hal_%s_t %s;" % (type, to_c(name)), file=f)         names[name] = 1     for type, name, array, value in variables:         if array:             print("    %s %s[%d];\n" % (type, name, array), file=f)         else:             print("    %s %s;\n" % (type, name), file=f)     if has_data:         print("    void *_data;", file=f)     print("};", file=f)     if options.get("userspace"):         print("#include <stdlib.h>", file=f)     print("struct __comp_state *__comp_first_inst=0, *__comp_last_inst=0;", file=f)          print("", file=f)     for name, fp in functions:         if name in names:             Error("Duplicate item name: %s" % name)         print("static void %s(struct __comp_state *__comp_inst, long period);" % to_c(name), file=f)         names[name] = 1     print("static int __comp_get_data_size(void);", file=f)     if options.get("extra_setup"):         print("static int extra_setup(struct __comp_state *__comp_inst, char *prefix, long extra_arg);", file=f)     if options.get("extra_cleanup"):         print("static void extra_cleanup(void);", file=f)     if not options.get("no_convenience_defines"):         print("#undef TRUE", file=f)         print("#define TRUE (1)", file=f)         print("#undef FALSE", file=f)         print("#define FALSE (0)", file=f)         print("#undef true", file=f)         print("#define true (1)", file=f)         print("#undef false", file=f)         print("#define false (0)", file=f)     print("", file=f)     if has_personality:         print("static int export(char *prefix, long extra_arg, long personality) {", file=f)     else:         print("static int export(char *prefix, long extra_arg) {", file=f)     if len(functions) > 0:         print("    char buf[HAL_NAME_LEN + 1];", file=f)     print("    int r = 0;", file=f)     if has_array:         print("    int j = 0;", file=f)     print("    int sz = sizeof(struct __comp_state) + __comp_get_data_size();", file=f)     print("    struct __comp_state *inst = hal_malloc(sz);", file=f)     print("    memset(inst, 0, sz);", file=f)     if has_data:         print("    inst->_data = (char*)inst + sizeof(struct __comp_state);", file=f)     if has_personality:         print("    inst->_personality = personality;", file=f)     if options.get("extra_setup"):         print("    r = extra_setup(inst, prefix, extra_arg);", file=f)         print("    if(r != 0) return r;", file=f)         # the extra_setup() function may have changed the personality         if has_personality:             print("    personality = inst->_personality;", file=f)     for name, type, array, dir, value, personality in pins:         if personality:             print("if(%s) {" % personality, file=f)         if array:             if isinstance(array, tuple):                 lim, cnt = array                 print("    if((%s) > (%s)) {" % (cnt, lim), file=f)                 print('        rtapi_print_msg(RTAPI_MSG_ERR,' \                                 '"Pin %s: Requested size %%d exceeds max size %%d\\n",'                                 '(int)%s, (int)%s);' % (name, cnt, lim), file=f)                 print("        return -ENOSPC;", file=f)                 print("    }", file=f)             else: cnt = array             print("    for(j=0; j < (%s); j++) {" % cnt, file=f)             print("        r = hal_pin_%s_newf(%s, &(inst->%s[j]), comp_id," % (                 type, dirmap[dir], to_c(name)), file=f)             print("            \"%%s%s\", prefix, j);" % to_hal("." + name), file=f)             print("        if(r != 0) return r;", file=f)             if value is not None:                 print("    *(inst->%s[j]) = %s;" % (to_c(name), value), file=f)             print("    }", file=f)         else:             print("    r = hal_pin_%s_newf(%s, &(inst->%s), comp_id," % (                 type, dirmap[dir], to_c(name)), file=f)             print("        \"%%s%s\", prefix);" % to_hal("." + name), file=f)             print("    if(r != 0) return r;", file=f)             if value is not None:                 print("    *(inst->%s) = %s;" % (to_c(name), value), file=f)         if personality:             print("}", file=f)     for name, type, array, dir, value, personality in params:         if personality:             print("if(%s) {" % personality, file=f)         if array:             if isinstance(array, tuple):                 lim, cnt = array                 print("    if((%s) > (%s)) {" % (cnt, lim), file=f)                 print('        rtapi_print_msg(RTAPI_MSG_ERR,' \                                 '"Parameter %s: Requested size %%d exceeds max size %%d\\n",'                                 '(int)%s, (int)%s);' % (name, cnt, lim), file=f)                 print("        return -ENOSPC;", file=f)                 print("    }", file=f)             else: cnt = array             print("    for(j=0; j < (%s); j++) {" % cnt, file=f)             print("        r = hal_param_%s_newf(%s, &(inst->%s[j]), comp_id," % (                 type, dirmap[dir], to_c(name)), file=f)             print("            \"%%s%s\", prefix, j);" % to_hal("." + name), file=f)             print("        if(r != 0) return r;", file=f)             if value is not None:                 print("    inst->%s[j] = %s;" % (to_c(name), value), file=f)             print("    }", file=f)         else:             print("    r = hal_param_%s_newf(%s, &(inst->%s), comp_id," % (                 type, dirmap[dir], to_c(name)), file=f)             print("        \"%%s%s\", prefix);" % to_hal("." + name), file=f)             if value is not None:                 print("    inst->%s = %s;" % (to_c(name), value), file=f)             print("    if(r != 0) return r;", file=f)         if personality:             print("}", file=f)     for type, name, array, value in variables:         if value is None: continue         if array:             print("    for(j=0; j < %s; j++) {" % array, file=f)             print("        inst->%s[j] = %s;" % (name, value), file=f)             print("    }", file=f)         else:             print("    inst->%s = %s;" % (name, value), file=f)     for name, fp in functions:         print("    rtapi_snprintf(buf, sizeof(buf), \"%%s%s\", prefix);"\             % to_hal("." + name), file=f)         print("    r = hal_export_funct(buf, (void(*)(void *inst, long))%s, inst, %s, 0, comp_id);" % (             to_c(name), int(fp)), file=f)         print("    if(r != 0) return r;", file=f)     print("    if(__comp_last_inst) __comp_last_inst->_next = inst;", file=f)     print("    __comp_last_inst = inst;", file=f)     print("    if(!__comp_first_inst) __comp_first_inst = inst;", file=f)     print("    return 0;", file=f)     print("}", file=f)     if options.get("count_function"):         print("static int get_count(void);", file=f)     if options.get("rtapi_app", 1):         if options.get("constructable") and not options.get("singleton"):             print("static int export_1(char *prefix, char *argstr) {", file=f)             print("    int arg = simple_strtol(argstr, NULL, 0);", file=f)             print("    return export(prefix, arg);", file=f)             print("}"   , file=f)         if not options.get("singleton") and not options.get("count_function") :             print("static int default_count=%s, count=0;" \                 % options.get("default_count", 1), file=f)             if options.get("userspace"):                 print("char *names[%d] = {0,};"%(MAX_USERSPACE_NAMES), file=f)             else:                 print("RTAPI_MP_INT(count, \"number of %s\");" % comp_name, file=f)                 print("char *names = \"\"; // comma separated names", file=f)                 print("RTAPI_MP_STRING(names, \"names of %s\");" % comp_name, file=f)         if has_personality:             init1 = str(int(options.get('default_personality', 0)))             init = ",".join([init1] * MAX_PERSONALITIES)             print("static int personality[%d] = {%s};" %(MAX_PERSONALITIES,init), file=f)             print("RTAPI_MP_ARRAY_INT(personality, %d, \"personality of each %s\");" %(MAX_PERSONALITIES,comp_name), file=f)             # Return personality value.             # If requested index exceeds MAX_PERSONALITIES, use modulo indexing and give message             print("""             static int p_value(char* cname, char *name, int idx) {                 int ans = personality[idx%%%d];                 if (idx >= %d) {             """%(MAX_PERSONALITIES,MAX_PERSONALITIES), file=f)             print("""                     if (name==NULL) {                         rtapi_print_msg(RTAPI_MSG_ERR,"%s: instance %d assigned personality=%d(=%#0x)\\n",                                         cname, idx, ans, ans);                     } else {                         rtapi_print_msg(RTAPI_MSG_ERR,"%s: name %s assigned personality=%d(=%#0x)\\n",                                         cname, name, ans, ans);                     }                 }                 return ans;             }             """, file=f)         print("int rtapi_app_main(void) {", file=f)         print("    int r = 0;", file=f)         if not options.get("singleton"):             print("    int i;", file=f)         if options.get("count_function"):             print("    int count = get_count();", file=f)         print("    comp_id = hal_init(\"%s\");" % comp_name, file=f)         print("    if(comp_id < 0) return comp_id;", file=f)         if options.get("singleton"):             if has_personality:                 print("    r = export(\"%s\", 0, personality[0]);" % \                         to_hal(removeprefix(comp_name, "hal_")), file=f)             else:                 print("    r = export(\"%s\", 0);" % \                         to_hal(removeprefix(comp_name, "hal_")), file=f)         elif options.get("count_function"):             print("    for(i=0; i<count; i++) {", file=f)             print("        char buf[HAL_NAME_LEN + 1];", file=f)             print("        rtapi_snprintf(buf, sizeof(buf), " \                                         "\"%s.%%d\", i);" % \                     to_hal(removeprefix(comp_name, "hal_")), file=f)             if has_personality:                 print("        r = export(buf, i, p_value(\"%s\", buf, i) );"%comp_name, file=f)             else:                 print("        r = export(buf, i);", file=f)             print("    }", file=f)         else:             print("    if(count && names[0]) {", file=f)             print("        rtapi_print_msg(RTAPI_MSG_ERR," \                             "\"count= and names= are mutually exclusive\\n\");", file=f)             print("        return -EINVAL;", file=f)             print("    }", file=f)             print("    if(!count && !names[0]) count = default_count;", file=f)             print("    if(count) {", file=f)             print("        for(i=0; i<count; i++) {", file=f)             print("            char buf[HAL_NAME_LEN + 1];", file=f)             print("            rtapi_snprintf(buf, sizeof(buf), " \                                         "\"%s.%%d\", i);" % \                     to_hal(removeprefix(comp_name, "hal_")), file=f)             if has_personality:                 print("            r = export(buf, i, p_value(\"%s\", buf, i) );"%comp_name, file=f)             else:                 print("            r = export(buf, i);", file=f)             print("            if(r != 0) break;", file=f)             print("       }", file=f)             print("    } else {", file=f)             if options.get("userspace"):                 print("        int max_names = sizeof(names)/sizeof(names[0]);", file=f)                 print("        for(i=0; (i < max_names) && names[i]; i++) {", file=f)                 print("            if (strlen(names[i]) < 1) {", file=f)                 print("                rtapi_print_msg(RTAPI_MSG_ERR, \"names[%d] is invalid (empty string)\\n\", i);", file=f)                 print("                r = -EINVAL;", file=f)                 print("                break;", file=f)                 print("            }", file=f)                 if has_personality:                     print("            r = export(names[i], i, p_value(\"%s\", names[i], i) );"%comp_name, file=f)                 else:                     print("            r = export(names[i], i);", file=f)                 print("            if(r != 0) break;", file=f)                 print("       }", file=f)                 print("    }", file=f)             else:                 print("        size_t i, j;", file=f)                 print("        int idx;", file=f)                 print("        char buf[HAL_NAME_LEN+1];", file=f)                 print("        const size_t length = strlen(names);", file=f)                 print("        for (i = j = idx = 0; i <= length; i++) {", file=f)                 print("            const char c = buf[j] = names[i];", file=f)                 print("            if ((c == ',') || (c == '\\0')) {", file=f)                 print("                buf[j] = '\\0';", file=f)                 if has_personality:                     print("                r = export(buf, idx, p_value(\"%s\", buf, idx) );"%comp_name, file=f)                 else:                     print("                r = export(buf, idx);", file=f)                 print("                if(r != 0) {break;}", file=f)                 print("                idx++;", file=f)                 print("                j = 0;", file=f)                 print("            } else {", file=f)                 print("                if (++j == (sizeof(buf) / sizeof(buf[0]))) {", file=f)                 print("                    buf[j - 1] = '\\0';", file=f)                 print("                    rtapi_print_msg(RTAPI_MSG_ERR,\"names: \\\"%s\\\" too long\\n\", buf);", file=f)                 print("                    r = -EINVAL;", file=f)                 print("                    break;", file=f)                 print("                }", file=f)                 print("            }", file=f)                 print("        }", file=f)                 print("    }", file=f)         if options.get("constructable") and not options.get("singleton"):             print("    hal_set_constructor(comp_id, export_1);", file=f)         print("    if(r) {", file=f)         if options.get("extra_cleanup"):             print("    extra_cleanup();", file=f)         print("        hal_exit(comp_id);", file=f)         print("    } else {", file=f)         print("        hal_ready(comp_id);", file=f)         print("    }", file=f)         print("    return r;", file=f)         print("}", file=f)         print("", file=f)         print("void rtapi_app_exit(void) {", file=f)         if options.get("extra_cleanup"):             print("    extra_cleanup();", file=f)         print("    hal_exit(comp_id);", file=f)         print("}", file=f)     if options.get("userspace"):         print("static void user_mainloop(void);", file=f)         if options.get("userinit"):             print("static void userinit(int argc, char **argv);", file=f)         if not options.get("singleton"):             print(""" int __comp_parse_count(int *argc, char **argv) {     int i;     for (i = 0; i < *argc; i ++) {         if (strncmp(argv[i], "count=", 6) == 0) {             errno = 0;             count = strtoul(&argv[i][6], NULL, 0);             for (; i+1 < *argc; i ++) {                 argv[i] = argv[i+1];             }             argv[i] = NULL;             (*argc)--;             if (errno == 0) {                 return 1;             }         }     }     return 0; } """, file=f)             print(""" int __comp_parse_names(int *argc, char **argv) {     int i;     for (i = 0; i < *argc; i ++) {         if (strncmp(argv[i], "names=", 6) == 0) {             char *p = &argv[i][6];             int j;             for (; i+1 < *argc; i ++) {                 argv[i] = argv[i+1];             }             argv[i] = NULL;             (*argc)--;             for (j = 0; j < %d; j ++) {                 names[j] = strtok(p, ",");                 p = NULL;                 if (names[j] == NULL) {                     return 1;                 }             }             return 1;         }     }     return 0; } """%MAX_USERSPACE_NAMES, file=f)         print("int argc=0; char **argv=0;", file=f)         print("int main(int argc_, char **argv_) {"    , file=f)         print("    argc = argc_; argv = argv_;", file=f)         if not options.get("singleton"):             print("    int found_count, found_names;", file=f)             print("    found_count = __comp_parse_count(&argc, argv);", file=f)             print("    found_names = __comp_parse_names(&argc, argv);", file=f)             print("    if (found_count && found_names) {", file=f)             print("        rtapi_print_msg(RTAPI_MSG_ERR, \"count= and names= are mutually exclusive\\n\");", file=f)             print("        return 1;", file=f)             print("    }", file=f)         if options.get("userinit", 0):             print("    userinit(argc, argv);", file=f)         print("", file=f)         print("    if(rtapi_app_main() < 0) return 1;", file=f)         print("    user_mainloop();", file=f)         print("    rtapi_app_exit();", file=f)         print("    return 0;", file=f)         print("}", file=f)     print("", file=f)     if not options.get("no_convenience_defines"):         print("#undef FUNCTION", file=f)         print("#define FUNCTION(name) static void name(struct __comp_state *__comp_inst, long period)", file=f)         print("#undef EXTRA_SETUP", file=f)         print("#define EXTRA_SETUP() static int extra_setup(struct __comp_state *__comp_inst, char *prefix, long extra_arg)", file=f)         print("#undef EXTRA_CLEANUP", file=f)         print("#define EXTRA_CLEANUP() static void extra_cleanup(void)", file=f)         print("#undef fperiod", file=f)         print("#define fperiod (period * 1e-9)", file=f)         for name, type, array, dir, value, personality in pins:             print("#undef %s" % to_c(name), file=f)             if array:                 if dir == 'in':                     print("#define %s(i) (0+*(__comp_inst->%s[i]))" % (to_c(name), to_c(name)), file=f)                 else:                     print("#define %s(i) (*(__comp_inst->%s[i]))" % (to_c(name), to_c(name)), file=f)             else:                 if dir == 'in':                     print("#define %s (0+*__comp_inst->%s)" % (to_c(name), to_c(name)), file=f)                 else:                     print("#define %s (*__comp_inst->%s)" % (to_c(name), to_c(name)), file=f)         for name, type, array, dir, value, personality in params:             print("#undef %s" % to_c(name), file=f)             if array:                 print("#define %s(i) (__comp_inst->%s[i])" % (to_c(name), to_c(name)), file=f)             else:                 print("#define %s (__comp_inst->%s)" % (to_c(name), to_c(name)), file=f)         for type, name, array, value in variables:             name = name.replace("*", "")             print("#undef %s" % name, file=f)             print("#define %s (__comp_inst->%s)" % (name, name), file=f)         if has_data:             print("#undef data", file=f)             print("#define data (*(%s*)(__comp_inst->_data))" % options['data'], file=f)         if has_personality:             print("#undef personality", file=f)             print("#define personality (__comp_inst->_personality)", file=f)         if options.get("userspace"):             print("#undef FOR_ALL_INSTS", file=f)             if options.get("singleton"):                 print("#define __comp_inst __comp_first_inst", file=f)                 print("#define FOR_ALL_INSTS()", file=f)             else:                 print("#define FOR_ALL_INSTS() struct __comp_state *__comp_inst; for(__comp_inst = __comp_first_inst; __comp_inst; __comp_inst = __comp_inst->_next)", file=f)     print("", file=f)     print("", file=f) def epilogue(f):     data = options.get('data')     print("", file=f)     if data:         print("static int __comp_get_data_size(void) { return sizeof(%s); }" % data, file=f)     else:         print("static int __comp_get_data_size(void) { return 0; }", file=f) INSTALL, COMPILE, PREPROCESS, DOCUMENT, INSTALLDOC, VIEWDOC, MODINC = range(7) modename = ("install", "compile", "preprocess", "document", "installdoc", "viewdoc", "print-modinc") modinc = None def find_modinc():     global modinc     if modinc: return modinc     d = os.path.abspath(os.path.dirname(os.path.dirname(sys.argv[0])))     for e in ['src', 'etc/linuxcnc', '/etc/linuxcnc', 'share/linuxcnc']:         e = os.path.join(d, e, 'Makefile.modinc')         if os.path.exists(e):             modinc = e             return e     raise SystemExit("Unable to locate Makefile.modinc") def build_usr(tempdir, filename, mode, origfilename):     binname = os.path.basename(os.path.splitext(filename)[0])     makefile = os.path.join(tempdir, "Makefile")     f = open(makefile, "w")     print("%s: %s" % (binname, filename), file=f)     print("\t$(CC) -I$(EMC2_HOME)/include -I/usr/include/linuxcnc -URTAPI -U__MODULE__ -DULAPI -Os %s -o $@ $< -Wl,-rpath,$(LIBDIR) -L$(LIBDIR) -llinuxcnchal %s" % (         options.get("extra_compile_args", ""),         options.get("extra_link_args", "")), file=f)     print("include %s" % find_modinc(), file=f)     f.close()     result = os.system("cd %s && make -S %s" % (tempdir, binname))     if result != 0:         raise SystemExit(os.WEXITSTATUS(result) or 1)     output = os.path.join(tempdir, binname)     if mode == INSTALL:         shutil.copy(output, os.path.join(BINDIR, binname))     elif mode == COMPILE:         shutil.copy(output, os.path.join(os.path.dirname(origfilename),binname)) def build_rt(tempdir, filename, mode, origfilename):     objname = os.path.basename(os.path.splitext(filename)[0] + ".o")     global extra_libs     makefile = os.path.join(tempdir, "Makefile")     f = open(makefile, "w")     print("creating temp compile dir " + tempdir )     print("obj-m += %s" % objname, file=f)     print("LDFLAGS += -L%s/lib %s " % (os.path.abspath('.'),  extra_libs) , file=f)     print("include %s" % find_modinc(), file=f)     print("EXTRA_CFLAGS += -lposemath -I%s" % os.path.abspath(os.path.dirname(origfilename)), file=f)     print("EXTRA_CFLAGS += -I%s" % os.path.abspath('.'), file=f)     f.close()     if mode == INSTALL:         target = "modules install"     else:         target = "modules"     print("cd %s && make -S %s" % (tempdir, target))     result = os.system("cd %s && make -S %s" % (tempdir, target))     if result != 0:         raise SystemExit(os.WEXITSTATUS(result) or 1)     if mode == COMPILE:         for extension in ".ko", ".so", ".o":             kobjname = os.path.splitext(filename)[0] + extension             if os.path.exists(kobjname):                 shutil.copy(kobjname, os.path.basename(kobjname))                 break         else:             raise SystemExit("Unable to copy module from temporary directory") def finddoc(section=None, name=None):     for item in docs:         if ((section == None or section == item[0]) and                 (name == None or name == item[1])): return item     return None def finddocs(section=None, name=None):     for item in docs:         if ((section == None or section == item[0]) and                 (name == None or name == item[1])):                     yield item def to_hal_man_unnumbered(s):     s = "%s.%s" % (comp_name, s)     s = s.replace("_", "-")     s = s.rstrip("-")     s = s.rstrip(".")     s = re.sub("#+", lambda m: "\\fI" + "M" * len(m.group(0)) + "\\fB", s)     # s = s.replace("-", "\\-")     return s def to_hal_man(s):     if options.get("singleton"):         s = "%s.%s" % (comp_name, s)     else:         s = "%s.\\fIN\\fB.%s" % (comp_name, s)     s = s.replace("_", "-")     s = s.rstrip("-")     s = s.rstrip(".")     s = re.sub("#+", lambda m: "\\fI" + "M" * len(m.group(0)) + "\\fB", s)     # s = s.replace("-", "\\-")     return s def document(filename, outfilename):     a, b = parse(filename)     if outfilename is None:         outfilename = os.path.splitext(filename)[0] + ".1" if options.get("userspace") else ".9"     f = open(outfilename, "w")     has_personality = False     for name, type, array, dir, value, personality in pins:         if personality: has_personality = True         if isinstance(array, tuple): has_personality = True     for name, type, array, dir, value, personality in params:         if personality: has_personality = True         if isinstance(array, tuple): has_personality = True     print(".TH %s \"%s\" \"%s\" \"LinuxCNC Documentation\" \"HAL Component\"" % (         comp_name.upper(), "1" if options.get("userspace") else "9",         time.strftime("%F")), file=f)     print(".de TQ\n.br\n.ns\n.TP \\\\$1\n..\n", file=f)     print(".SH NAME\n", file=f)     doc = finddoc('component')         if doc and doc[2]:         if '\n' in doc[2]:             firstline, rest = doc[2].split('\n', 1)         else:             firstline = doc[2]             rest = ''         print("%s \\- %s" % (doc[1], firstline), file=f)     else:         rest = ''         print("%s" % doc[1], file=f)     print(".SH SYNOPSIS", file=f)     if options.get("userspace"):         print(".B %s" % comp_name, file=f)     else:         if rest:             print(rest, file=f)         else:             print(".HP", file=f)             if options.get("singleton") or options.get("count_function"):                 if has_personality:                     print(".B loadrt %s personality=\\fIP\\fB" % comp_name, end='', file=f)                 else:                     print(".B loadrt %s" % comp_name, end='', file=f)             else:                 if has_personality:                     print(".B loadrt %s [count=\\fIN\\fB|names=\\fIname1\\fB[,\\fIname2...\\fB]] [personality=\\fIP,P,...\\fB]" % comp_name, end='', file=f)                 else:                     print(".B loadrt %s [count=\\fIN\\fB|names=\\fIname1\\fB[,\\fIname2...\\fB]]" % comp_name, end='', file=f)             for type, name, default, doc in modparams:                 print(" [%s=\\fIN\\fB]" % name, end='', file=f)             print("", file=f)             hasparamdoc = False             for type, name, default, doc in modparams:                 if doc: hasparamdoc = True             if hasparamdoc:                 print(".RS 4", file=f)                 for type, name, default, doc in modparams:                     print(".TP", file=f)                     print("\\fB%s\\fR" % name, end='', file=f)                     if default:                         print(" [default: %s]" % default, file=f)                     else:                         print("", file=f)                     print(doc, file=f)                 print(".RE", file=f)         if options.get("constructable") and not options.get("singleton"):             print(".PP\n.B newinst %s \\fIname\\fB" % comp_name, file=f)     doc = finddoc('descr')         if doc and doc[1]:         print(".SH DESCRIPTION\n", file=f)         print("%s" % doc[1], file=f)     if functions:         print(".SH FUNCTIONS", file=f)         for _, name, fp, doc in finddocs('funct'):             print(".TP", file=f)             print("\\fB%s\\fR" % to_hal_man(name), end='', file=f)             if fp:                 print(" (requires a floating-point thread)", file=f)             else:                 print("", file=f)             print(doc, file=f)     lead = ".TP"     print(".SH PINS", file=f)     for _, name, type, array, dir, doc, value, personality in finddocs('pin'):         print(lead, file=f)         print(".B %s\\fR" % to_hal_man(name), end=' ', file=f)         print(type, dir, end=' ', file=f)         if array:             sz = name.count("#")             if isinstance(array, tuple):                 print(" (%s=%0*d..%s)" % ("M" * sz, sz, 0, array[1]), end=' ', file=f)             else:                 print(" (%s=%0*d..%0*d)" % ("M" * sz, sz, 0, sz, array-1), end=' ', file=f)         if personality:             print(" [if %s]" % personality, end=' ', file=f)         if value:             print("\\fR(default: \\fI%s\\fR)" % value, file=f)         else:             print("\\fR", file=f)         if doc:             print(doc, file=f)             lead = ".TP"         else:             lead = ".TQ"     lead = ".TP"     if params:         print(".SH PARAMETERS", file=f)         for _, name, type, array, dir, doc, value, personality in finddocs('param'):             print(lead, file=f)             print(".B %s\\fR" % to_hal_man(name), end=' ', file=f)             print(type, dir, end=' ', file=f)             if array:                 sz = name.count("#")                 if isinstance(array, tuple):                     print(" (%s=%0*d..%s)" % ("M" * sz, sz, 0, array[1]), end=' ', file=f)                 else:                     print(" (%s=%0*d..%0*d)" % ("M" * sz, sz, 0, sz, array-1), end=' ', file=f)             if personality:                 print(" [if %s]" % personality, end=' ', file=f)             if value:                 print("\\fR(default: \\fI%s\\fR)" % value, file=f)             else:                 print("\\fR", file=f)             if doc:                 print(doc, file=f)                 lead = ".TP"             else:                 lead = ".TQ"     doc = finddoc('see_also')         if doc and doc[1]:         print(".SH SEE ALSO\n", file=f)         print("%s" % doc[1], file=f)     doc = finddoc('notes')         if doc and doc[1]:         print(".SH NOTES\n", file=f)         print("%s" % doc[1], file=f)     doc = finddoc('author')         if doc and doc[1]:         print(".SH AUTHOR\n", file=f)         print("%s" % doc[1], file=f)     doc = finddoc('license')         if doc and doc[1]:         print(".SH LICENSE\n", file=f)         print("%s" % doc[1], file=f) def process(filename, mode, outfilename):     tempdir = tempfile.mkdtemp()     try:         if outfilename is None:             if mode == PREPROCESS:                 outfilename = os.path.splitext(filename)[0] + ".c"             else:                 outfilename = os.path.join(tempdir,                     os.path.splitext(os.path.basename(filename))[0] + ".c")         a, b = parse(filename)         base_name = os.path.splitext(os.path.basename(outfilename))[0]         if comp_name != base_name:             raise SystemExit("Component name (%s) does not match filename (%s)" % (comp_name, base_name))         f = open(outfilename, "w")         if options.get("userinit") and not options.get("userspace"):             print("Warning: comp '%s' sets 'userinit' without 'userspace', ignoring" % filename, file=sys.stderr)         if options.get("userspace"):             if functions:                 raise SystemExit("Userspace components may not have functions")         if not pins:             raise SystemExit("Component must have at least one pin")         prologue(f)         lineno = a.count("\n") + 3         if options.get("userspace"):             if functions:                 raise SystemExit("May not specify functions with a userspace component.")             f.write("#line %d \"%s\"\n" % (lineno, filename))             f.write(b)         else:             if not functions or "FUNCTION" in b:                 f.write("#line %d \"%s\"\n" % (lineno, filename))                 f.write(b)             elif len(functions) == 1:                 f.write("FUNCTION(%s) {\n" % functions[0][0])                 f.write("#line %d \"%s\"\n" % (lineno, filename))                 f.write(b)                 f.write("}\n")             else:                 raise SystemExit("Must use FUNCTION() when more than one function is defined")         epilogue(f)         f.close()         if mode != PREPROCESS:             if options.get("userspace"):                 build_usr(tempdir, outfilename, mode, filename)             else:                 build_rt(tempdir, outfilename, mode, filename)     finally:         shutil.rmtree(tempdir) def usage(exitval=0):     print("""%(name)s: Build, compile, and install LinuxCNC HAL components Usage:            %(name)s [--compile|--preprocess|--document|--view-doc] compfile...     [sudo] %(name)s [--install|--install-doc] compfile...            %(name)s --compile --userspace cfile...     [sudo] %(name)s --install --userspace cfile...     [sudo] %(name)s --install --userspace pyfile...            %(name)s --print-modinc Option to set maximum 'personalities' items:     --personalities=integer_value   (default is %(dflt)d) """ % {'name': os.path.basename(sys.argv[0]),'dflt':MAX_PERSONALITIES})     raise SystemExit(exitval) def main():     global extra_libs     global require_license     global MAX_USERSPACE_NAMES     global MAX_PERSONALITIES     require_license = True     global require_unix_line_endings     require_unix_line_endings = False     mode = PREPROCESS     outfile = None     userspace = False     try:         opts, args = getopt.getopt(sys.argv[1:], "Uluijcpdo:h?P:",                            ['unix', 'lib=', 'install', 'compile', 'preprocess', 'outfile=',                             'document', 'help', 'userspace', 'install-doc',                             'view-doc', 'require-license', 'print-modinc',                             'personalities='])     except getopt.GetoptError:         usage(1)     for k, v in opts:         if k in ("-l", "--lib"):             extra_libs = extra_libs + " " + v             print( "-------------- " + v )         if k in ("-U", "--unix"):             require_unix_line_endings = True         if k in ("-u", "--userspace"):             userspace = True         if k in ("-i", "--install"):             mode = INSTALL         if k in ("-c", "--compile"):             mode = COMPILE         if k in ("-p", "--preprocess"):             mode = PREPROCESS         if k in ("-d", "--document"):             mode = DOCUMENT         if k in ("-j", "--install-doc"):             mode = INSTALLDOC         if k in ("-j", "--view-doc"):             mode = VIEWDOC         if k in ("--print-modinc",):             mode = MODINC         if k in ("-l", "--require-license"):             require_license = True         if k in ("-o", "--outfile"):             if len(args) != 1:                 raise SystemExit("Cannot specify -o with multiple input files")             outfile = v         if k in ("-P", "--personalities"):             try:                 MAX_PERSONALITIES = int(v)                 print("MAX_PERSONALITIES=%d"%(MAX_PERSONALITIES))             except Exception as detail:                 raise SystemExit("Bad value for -P (--personalities)=",v,"\n",detail)         if k in ("-?", "-h", "--help"):             usage(0)     if outfile and mode != PREPROCESS and mode != DOCUMENT:         raise SystemExit("Can only specify -o when preprocessing or documenting")     if mode == MODINC:         if args:             raise SystemExit(                 "Can not specify input files when using --print-modinc")         print(find_modinc())         return 0     for f in args:         try:             basename = os.path.basename(os.path.splitext(f)[0])             if f.endswith(".comp") and mode == DOCUMENT:                 document(f, outfile)                         elif f.endswith(".comp") and mode == VIEWDOC:                 tempdir = tempfile.mkdtemp()                 try:                     outfile = os.path.join(tempdir, basename + ".9")                     document(f, outfile)                     os.spawnvp(os.P_WAIT, "man", ["man", outfile])                 finally:                     shutil.rmtree(tempdir)             elif f.endswith(".comp") and mode == INSTALLDOC:                 manpath = os.path.join(BASE, "share/man/man9")                 if not os.path.isdir(manpath):                     manpath = os.path.join(BASE, "docs/man/man9")                 outfile = os.path.join(manpath, basename + ".9")                 print("INSTALLDOC", outfile)                 document(f, outfile)                         elif f.endswith(".comp"):                 process(f, mode, outfile)             elif f.endswith(".py") and mode == INSTALL:                 lines = open(f).readlines()                 if lines[0].startswith("#!"): del lines[0]                 lines[0] = "#!%s\n" % sys.executable                 outfile = os.path.join(BINDIR, basename)                 try: os.unlink(outfile)                 except os.error: pass                 open(outfile, "w").writelines(lines)                 os.chmod(outfile, 0o555)             elif f.endswith(".c") and mode != PREPROCESS:                 initialize()                 tempdir = tempfile.mkdtemp()                 try:                     shutil.copy(f, tempdir)                     if userspace:                         build_usr(tempdir, os.path.join(tempdir, os.path.basename(f)), mode, f)                     else:                         build_rt(tempdir, os.path.join(tempdir, os.path.basename(f)), mode, f)                 finally:                     print                     shutil.rmtree(tempdir)             else:                 raise SystemExit("Unrecognized file type for mode %s: %r" % (modename[mode], f))         except Exception as e:             try:                 if outfile is not None: os.unlink(outfile)             except: # os.error:                 pass             raise if __name__ == '__main__':     main() # vim:sw=4:sts=4:et

 

Please Log in or Create an account to join the conversation.

Time to create page: 0.298 seconds
Powered by Kunena Forum