diff --git a/uppbox/UppBuilder/Make.hpp b/uppbox/UppBuilder/Make.hpp new file mode 100644 index 000000000..2461d940d --- /dev/null +++ b/uppbox/UppBuilder/Make.hpp @@ -0,0 +1,251 @@ +#include + +String ParseCustomStep(const String& s){ + String cmd; + for(const char* c=~s;*c;c++){ + if(c[0]=='\\' && c[1]=='\"') continue; + if(strncmp(c,"$(PATH)",7)==0){ + cmd+="$$f"; + c+=6; + } else if(strncmp(c,"$(DIR)",6)==0){ + cmd+="`dirname $$f`"; + c+=5; + } else if(strncmp(c,"$(FILE)",7)==0){ + cmd+="`basename $$f`"; + c+=6; + } else if(strncmp(c,"$(TITLE)",8)==0){ + cmd+="`basename $$f | sed 's/[.][^.]*$//'`"; + c+=7; + } else if(strncmp(c,"$(OUTDIR)",9)==0){ + cmd+="$(BIN)/"; + c+=8; + } else + cmd+=*c; +// $(INCLUDE),$(!) etc. not implemented yet + } + return cmd; +} + +String CustomRule(String rule, const String& pkg){ + String ext=ReadValue(rule); + String cmd=ParseCustomStep(ReadValue(rule)); + //ignore last part for simplicity + if (cmd.IsEmpty() || ext.IsEmpty()) + return ""; + if (ext=="pre-link") + return " $E cd $("+pkg+"_src) &&" + "echo \" Applying custom build pre-link step " + "(warning: this is an experimental feature)\"; " + +cmd+";\n"; + if (ext=="post-link") + return " $E cd $("+pkg+"_src) &&" + "echo \" Applying custom build post-link step " + "(warning: this is an experimental feature)\"; " + +cmd+";\n"; + return " $E cd $("+pkg+"_src) && for f in *"+ext+"; " + "do echo \" Applying custom build step on $$f " + "(warning: this is an experimental feature)\"; " + +cmd+"; done;\n"; +} + +void Parser::Process(){ + String uppout=GetEnv("OUT","/tmp/_out"); + String makefile=uppout+"/Makefile"; + FILE* mf=fopen(makefile,"w"); + if(!mf){ + printf("Failed to open file %s\n", ~makefile); + exit(1); + } + + fprintf(mf, "# This is an automatically generated makefile for %s package\n" + "# You should never need to modify it...\n", ~main); + + bool dep = GetEnv("DEPS","0")=="1"; + bool color = GetEnv("COLOR","0")=="1"; + String includes; + Vector inc; + Split(GetEnv("INCPATHS"),inc); + for(int i=0; i lpaths; + Split(GetEnv("LIBPATHS"),lpaths); + for(int i=0; itm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); + + fprintf(mf, "OUT:=%s\n" + "BIN:=%s\n" + "CFLAGS:=%s\n" + "CXXFLAGS:=%s\n" + "SPEEDFLAGS:=%s\n" + "SIZEFLAGS:=%s\n" + "LDFLAGS:=%s\n" + "CC:=%s\n" + "CXX:=%s\n" + "AR:=%s\n" + "MKDIRP:=%s\n" + "E:=%s\n" + "M:=%s\n" + "C:=%s\n" + "B:=%s\n" + "N:=%s\n" + "mc=$M \" Compiling $C$<$N\"\n" + "ma=$M \"=> $BCreating archive$N $C$@$N\"\n" + "cc=$E $(CC) -c -x c %s $< -o $@ $(CPPFLAGS) %s\n" + "cxx=$E $(CXX) -c -x c++ %s $< -o $@ $(CPPFLAGS) %s\n" + "includes:=%s\n" + "LIBPATHS:=%s\n" + "default: build\n" + ".PHONY:build clean createdirs custom default\n\n", + ~uppout, ~GetEnv("BIN","$(OUT)/bin"), + ~GetEnv("CFLAGS","-O2"), + ~GetEnv("CXXFLAGS","$(CFLAGS)"), + ~GetEnv("SPEEDFLAGS","-O3 -ffunction-sections -fdata-sections"), + ~GetEnv("SIZEFLAGS","-Os -finline-limit=20 -ffunction-sections -fdata-sections"), + ~GetEnv("LDFLAGS","-Wl,--gc-sections -Wl,-s -Wl,-O,2"), + ~GetEnv("CC","$(CC)"), ~GetEnv("CXX","$(CXX)"), + ~GetEnv("AR","ar -src"), ~GetEnv("MKDIRP","mkdir -p"), + GetEnv("ECHO","0")=="1"?"":"@", + GetEnv("SILENT","0")=="1"?"@true":(color?"@echo -e":"@echo"), + color?(const char*)("\\e[3"+GetEnv("HIGHLIGHT","4")+"m"):"", + color?"\\e[1m":"", color?"\\e[0m":"", + dep?"-MMD":"", date, dep?"-MMD":"", + date, ~includes, ~libpaths); + String icpps, archives, prelink, postlink, custom; + Vector dirs; + dirs.Add("$(BIN)"); + for(int i=0;i pflags; + + String opt; + //we add the internal includes twice, to fix the case with relative paths... isn't there a better solution? + opt=EvalVector(pkgs[i].include,i,"-I"); + opt+=EvalVector(pkgs[i].include,i,"-I$("+pkg+"_src)/"); + opt+=EvalVector(pkgs[i].option,i,""); + for(int j=0;j $(%s_out)/%s.cpp\n" + " $E $(CXX) -c -x c++ $(%s_out)/%s.cpp -o $@ $(CPPFLAGS) $(CXXFLAGS)\n", + ~pkg, ~f.name, ~pkg, ~f.name, ~pkg, ~f.name, ~pkg, ~f.name); + objlist+=" $("+pkg+"_out)/"+f.name+".o"; + continue; + } + String ext,fopt; + if(f.lang=="c++") + opt="$(CXXFLAGS) "; + else if(f.lang=="c") + opt="$(CFLAGS) "; + if(pkgs[i].opt==SPEED) ext=".speed.o"; + else if(pkgs[i].opt==SIZE) ext=".size.o"; + else{ + if(f.opt==SPEED) ext=".speed.o"; + if(f.opt==SIZE) ext=".size.o"; + else ext=".o"; + } + if(ext==".speed.o") + fopt+="$(SPEEDFLAGS)"; + else if(ext==".size.o") + fopt+="$(SIZEFLAGS)"; + String fn="$("+pkg+"_out)/" + f.name + ext; + if(dep){ + String dep = uppout + "/" + fdir + "/" + f.name + ext; + dep[dep.GetCount()-1]='d'; + dep=LoadFile(dep); + if(dep.GetCount()) + fprintf(mf, "%s", ~dep); + else + fprintf(mf, "%s: $("+pkg+"_src)/%s\n", ~fn, ~f.name); + } else { + fprintf(mf, "%s: $("+pkg+"_src)/%s\n", ~fn, ~f.name); + } + fprintf(mf," $(mc)\n" + " $(%s) %s $(%s_opt)\n", + ~f.lang, ~fopt, ~pkg); + + if(f.name.Mid(f.name.GetCount()-4)=="icpp") + icpps+=" "+fn; + else + objlist+=" "+fn; + } + fprintf(mf,"%s_custom:\n", ~pkgs[i].name); + for(int j=0;j $@ + +$(OUT)/brc.sh: $(thisfile) + @$m "Extracting brc parser..." + +$e [ -d $(OUT) ] || $(MKDIRP) $(OUT) + +$e $(TIME) sed -n 's/^#~//p;' $< | base64 -d | gzip -d > $@ + +$(OUT)/color.sh: $(thisfile) + @$m "Extracting colorizer script..." + +$e [ -d $(OUT) ] || $(MKDIRP) $(OUT) + +$e $(TIME) sed -n 's/^#%//p;' $< | base64 -d | gzip -d > $@ + +build: do-build + $e for pkg in $(PKG); do \ + if [ "$(RUN)" = "1" ]; then \ + for target in "$(TARGET)" "$(BIN)/$(TARGET)" "$(BIN)/$$pkg"; do \ + [ -f "$$target" ] && break; \ + done; \ + [ -e "$$target" ] && { $m "Running $$target"; } && $$target; \ + fi; \ + done + +simulate: $(OUT)/Makefile + +$e for pkg in $(PKG) ; do \ + $m Parsing package $$pkg ... && \ + $(pass) $(OUT)/parser $$pkg && \ + $m Building package $$pkg ... && \ + $(MAKE) -nf $(OUT)/Makefile; \ + done + +help: + $e sed '/^$$/{s/.*//;q;}' $(thisfile); + +clean: + +$e for pkg in $(PKG); do \ + $m Parsing package $$pkg... && \ + $(pass) $(OUT)/parser $$pkg && \ + $m Cleaning package $$pkg && \ + $(MAKE) -f $(OUT)/Makefile clean; \ + done + +dist-clean: + @$m Deleting $(OUT) ... + $e rm -rf $(OUT) + +parser-clean: + @$m Deleting parser files ... + $e rm -f $(OUT)/parser $(OUT)/parser.cpp + +.SUFFIXES: + +.PHONY: all help simulate clean dist-clean parser-clean \ + build do-build no-package-specified + diff --git a/uppbox/UppBuilder/Parser.cpp b/uppbox/UppBuilder/Parser.cpp new file mode 100644 index 000000000..486775e54 --- /dev/null +++ b/uppbox/UppBuilder/Parser.cpp @@ -0,0 +1,638 @@ +#include +#include +#include +#include +#include +#include + +template +inline void NEVER(T s){ + if(s){ + fprintf(stderr,"ERROR: Something that should never happened has happened...\n"); + exit(1); + } +}; + +template +class Vector{ + int size,alloc; + T* p; +public: + Vector():size(0), alloc(0), p(0) {Resize(2);} + ~Vector() {Resize(0);} + inline int GetCount()const {return size;} + inline T& operator[](int n) {return p[n];} + inline const T& operator[](int n) const {return p[n];} + T& Add(){ + if(size>=alloc) + Resize(2*alloc); + return *(new(p+size++) T); + } + T& Add(const T& x) { return Add()=x; } + T& AddUnique(const T& v){ + int pos=Find(v); + if(pos>=0) return p[pos]; + return Add(v); + } + int Find(const T& v) const{ + for(int i=0;ilen){ + for(int i=len;i~T(); + size=len; + } + p = (T*)realloc(p,len*sizeof(T)); + alloc=len; + } +private: + Vector& operator=(const Vector& v){} +}; + +class String { + char* p; +public: + String() : p(strdup("")) {} + String(const String& s) : p(strdup(s.p)){} + String(const char* s) : p(strdup(s)) {} + ~String() {free(p);} + + char& operator[](const int n) const {return p[n];} + bool IsEmpty() const {return *p == 0;} + const char* operator~() const {return p;} + operator const char*() const {return p;} + String& operator=(const String& s) {return operator=(s.p);} + bool operator==(const char* s) const {return !strcmp(p, s);} + bool operator==(const String& s) const {return !strcmp(p, s.p);} + void Clear() {free(p); p = strdup("");} + int GetCount() const {return strlen(p);} + String& operator+=(const String& s){ + const int lenp = strlen(p); + const int lens = strlen(s.p) + 1; + p = static_cast(realloc(p, lenp + lens)); + NEVER(!p); + memmove(p+lenp, s.p, lens); + return *this; + } + String& operator+=(char s){ + const int lenp = strlen(p); + p = static_cast(realloc(p, lenp + 2)); + NEVER(!p); + p[lenp] = s; + p[lenp+1] = 0; + return *this; + } + String& operator=(const char* s){ + if (p != s) { + char *copy = strdup(s); + free(p); + p = copy; + } + return *this; + } + int Compare(const char* s, int len=-1) const { + return len?strncmp(p,s,len):strcmp(p,s); + } + int FindLast(const char c) const { + for(int i=strlen(p)-1;i>=0;i--) + if(p[i]==c) return i; + return -1; + } + int Find(const char* s) const { + int lens=strlen(s); + int lenp=strlen(p); + for(int i=0;ilength && length>0) + len = length; + + String s; + free(s.p); + s.p = static_cast(malloc(len+1)); + NEVER(!s.p); + memcpy(s.p, p + start, len); + s.p[len] = '\0'; + return s; + } + + friend String operator+(const String& lhs, const String& rhs); + friend int operator<(const String& lhs, const String& rhs); +}; +inline String operator+(const String& lhs, const String& rhs){ + return String(lhs) += rhs; +} +inline int operator<(const String& lhs, const String& rhs){ + return lhs.Compare(~rhs); +} + +String ReadValue(String& s,char delim1 = ',',char delim2 = ','){ + if(s=="") return ""; + String r; + int skip=0; + while((s[skip]==delim1 || s[skip] == delim2 || s[skip]<=32) && s[skip]!=0) + skip++; + s = s.Mid(skip); + bool q=false; + if(s[0]=='\"'){ + s = s.Mid(1); + q = true; + } + const char* c = s; + for(; *c; c++){ + if(*c==delim1 || *c==delim2 || (q && *c=='\"') && c[-1] != '\\') break; + if(*c<=(q?0:32)) continue; + r += *c; + } + if(q) c++; + s = c; + return r; +}; + +bool Consume(String& s,const char* section){ + int len=strlen(section); + if(s.Compare(section,len)==0){ + s = s.Mid(len); + return true; + } + return false; +}; + +enum Opt{NONE, SPEED, SIZE}; +enum OptState { UNKNOWN, NO, YES }; + +struct File{ + Opt opt; + String name, lang; + File():opt(NONE){}; +}; + +bool IsSource(File& f){ + int pos=f.name.FindLast('.'); + if(!pos) + return false; + String ext = f.name.Mid(pos+1); + for(int i=0;i& v) { + if(Consume(s,key)) { + if(s[0]==' ') + s = s.Mid(1); + String when; + if(s[0]=='('){ + when=s; + int len = 0; + int lvl = 0; + for(const char* c=when; *c; c++) { + len++; + if(*c == '(') lvl++; + else if(*c == ')'){ + lvl--; + if(lvl == 0) break; + } + } + when = s.Mid(0,len); + s = s.Mid(len); + } + do { + OptItem& m=v.Add(); + m.when = when; + m.item = ReadValue(s,','); + Slashes(m.item); + }while(s[0] == ','); + return true; + } + return false; +}; + +String BaseName(const String& s){ + int pos=s.FindLast('/'); + if(!pos) + return s; + return s.Mid(pos+1); +}; + +String DirName(const String& s){ + int pos=s.FindLast('/'); + if(!pos) + return ""; + return s.Mid(0,pos); +}; + +inline String LoadFile(const String& fn){ + String r; + char b[1000]; + FILE* f=fopen(~fn,"r"); + if(!f) return ""; + int n=0; + while(!feof(f)){ + n+=fread(b,1,1000,f); + r+=b; + //this is a hack, correct implementation would not need it + r=r.Mid(0,n); + } + return r; +} + +inline String GetEnv(const char* n,const char* s=""){ + String p("UPP_"); + p+=n; + const char* r=getenv(p); + return r?r:s; +}; + +struct Upp{ + String name,description,dir; + Opt opt; + Vector option, link, library, addflags, target, uses, include, custom; + Vector accepts, cfgk, cfgv, flags; + Vector files; + + Upp() : opt(NONE){}; + Upp(const String& package) : name(package), opt(NONE){}; + Upp(const String& package,const Vector& nests) + : opt(NONE) {Load(package,nests);} + bool operator==(const Upp& u)const {return name==u.name;} + Upp& operator=(const Upp& u){NEVER(true); return *this;} + String GetClause(FILE* f){ + String r; + int l=0; + bool q=false; + while(1){ + int c = fgetc(f); + if(c==EOF || (!q && c==';')) break; + if(c<=32){ + if(!r.IsEmpty() && r[r.GetCount()-1]!=' ') + r += ' '; + continue; + } else + if (c == '\"' && l != '\\') { + q=!q; + } + l = c; + r += c; + } + return r; + }; + Upp& Load(const String& package,const Vector& nests){ + name=package; + char temp[FILENAME_MAX]; + String cwd = getcwd(temp, FILENAME_MAX); + cwd += "/"; + String fn; + FILE* f(NULL); + for(int i=0; i& v){ + while(s.GetCount()) v.AddUnique(ReadValue(s,' ')); +} + +String FlagDir(const Vector& v){ + Vector r; + //simple insertion sort + r.Resize(v.GetCount()); + for(int i=0;i=0 && r[i].Compare(c)>0) { + r[i+1]=r[i]; + i--; + } + r[i+1]=c; + } + String s=r[0]; + for(int i=1;i pkgs; + String main; +public: + Vector nests, flags, dflags, libs, linkopts; + static inline bool IsId(int c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9'); + } + bool sMatchFlag(String& s,int pkg){ + if(Consume(s,"!")) + return !sMatchFlag(s,pkg); + if(Consume(s,"(")) { + bool b = sMatchOr(s,pkg); + Consume(s,")"); + return b; + } + if(s.IsEmpty()) + return true; + int len=0; + while(IsId(s[len])) + len++; + String id = s.Mid(0,len); + s = s.Mid(len); + + if(flags.Find(id)>=0) return true; + for(int j=0;j=0) && dflags.Find(id)>=0) + return true; + if(pkg==0&&id=="MAIN") return true; + return false; + } + + bool sMatchAnd(String& s,int pkg){ + bool b = sMatchFlag(s,pkg); + while( IsId(s[0]) || s[0]=='!' || s[0]=='(' || Consume(s,"&&") || Consume(s,"&")) + b = sMatchFlag(s,pkg) && b; + return b; + } + + bool sMatchOr(String& s,int pkg){ + bool b = sMatchAnd(s,pkg); + while(Consume(s,"||") || Consume(s,"|")) + b = sMatchFlag(s,pkg) || b; + return b; + } + + bool EvalOpt(const OptItem& opt,int pkg){ + if(opt.state!=UNKNOWN) + return opt.state==YES; + String s; + for(const char* c = opt.when; *c; c++) + if(*c > ' ') s += *c; + if(s=="()"){ + opt.state=YES; + return true; + } + bool b = sMatchOr(s,pkg); + if(!s.IsEmpty()){ + fprintf(stderr, "Error: Invalid WHEN string: %s\n",~opt.when); + exit(1); + } + opt.state=b?YES:NO; + return b; + } + void GetDeps(const String& pkg){ + if(pkgs.Find(Upp(pkg))>=0) + return; + Upp& added = pkgs.Add().Load(pkg, nests); + Vector u; + for(int i=0;i& v,int pkg,const String& prefix){ + String r; + for(int i=0;i= 0 && n < pkgs[0].cfgk.GetCount()) + p = pkgs[0].cfgv[n]; + if(p) + Split(p,flags); + p="Using flags"; + for(int i=0; i dflags; + for(int i=0; i=0) + pkgs[i].flags.Add(dflags[j]); + for(int j=0;j remflags; + for(int j=0;j=0) continue; + pkgs[i].flags.Add(flags[j]); + } + } + } + void EvalOpts(){ + String optimize=GetEnv("OPT"); + for(int i=0;i output.c + +set -e +cd "`dirname $1`" +f="`basename $1`" + +tmp="`mktemp -d brc_XXXXXX`" +sed 's/[(),]/ /g;s/\r//' $f > $tmp/preparsed + +toBin() { + case $2 in + ZIP) obj=$tmp/obj.gz; cat "$1" | gzip -9 > $obj ;; + BZ2) obj=$tmp/obj.bz2; cat "$1" | bzip2 -9 > $obj ;; + *) obj="$1" ;; + esac + hexdump -e '"\t" 16/1 "%i, " "\n"' $obj | sed '$s/[ ,]\+$/, 0/g' + len="`cat $obj | wc -c`" +} + +BINARY() { + echo "static char $1_[] = {" + toBin "$2" $3 + echo "};" + echo "char *$1 = $1_;" + echo "int $1_length = $len;"; +} + +BINARY_MASK() { + c=0 + for file in $2; do + BINARY_ARRAY $1 $c $file $3 + c=$(( $c + 1 )) + files="$files\n\t\"$file\"," + done + echo -e "char *bin_all_files[] = {$files\n};" +} + +BINARY_ARRAY() { + echo "static char $1_$2[] = {" + toBin "$3" $4 + echo "};" + [ -z "`echo $arrays | grep $1`" ] && arrays="$1 $arrays" + echo "$1_$2 $len" >> $tmp/len +} + +. $tmp/preparsed | tee $tmp/out + +for a in $arrays; do + c="`grep -c $a'_[0-9]\+' $tmp/out`" + echo "int $a""_count = $c;" + echo "int $a""_length[] = {" + n=0 + while [ $n -lt $c ]; do + sed -n "/$a""_$n"' /s/.* \([0-9]*\)/\t\1,/p' $tmp/len + n=$(( $n + 1 )) + done + echo "};" + + echo "char *$a[] = { " + grep -o $a'_[0-9]\+' $tmp/out | sed 's/^/\t/;s/$/,/;' + echo " };" +done + +rm -r $tmp diff --git a/uppbox/UppBuilder/color.sh b/uppbox/UppBuilder/color.sh new file mode 100644 index 000000000..6fe55eb3d --- /dev/null +++ b/uppbox/UppBuilder/color.sh @@ -0,0 +1,14 @@ +#!/bin/sh +s='s/error:/\x1B[1;31m&\x1B[0m/ig; +s/warning:/\x1B[1;35m&\x1B[0m/ig; +s/note:/\x1B[1;32m&\x1B[0m/ig; +s/info:/\x1B[1;32m&\x1B[0m/ig;' +# redirection magic makes the sed command work on stdout +# as well as on stderr, without mixing them up +f="`mktemp -t status.XXXXXX`" +{ { { + $@ +} ; echo $? > $f; } 3>&1 1>&2 2>&3 | sed "$s"; } 3>&1 1>&2 2>&3 | sed "$s" +read ret < $f +rm -f $f +exit $ret diff --git a/uppbox/UppBuilder/init b/uppbox/UppBuilder/init new file mode 100644 index 000000000..65268c8aa --- /dev/null +++ b/uppbox/UppBuilder/init @@ -0,0 +1,3 @@ +#ifndef _UppBuilder_icpp_init_stub +#define _UppBuilder_icpp_init_stub +#endif diff --git a/uppbox/UppBuilder/src.tpp/Misc$en-us.tpp b/uppbox/UppBuilder/src.tpp/Misc$en-us.tpp new file mode 100644 index 000000000..3507f5c49 --- /dev/null +++ b/uppbox/UppBuilder/src.tpp/Misc$en-us.tpp @@ -0,0 +1,45 @@ +topic "miscellaneous structs"; +[ $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9; $$1,0#37138531426314131252341829483380:structitem] +[l288;2 $$2,0#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:codeitem] +[{_} +[s1;:File`:`:struct: [@(0.0.255) struct]_[* File]&] +[s2;%% Class holding information about file that should be compiled.&] +[s3; &] +[s4; &] +[s5;:File`:`:opt: Opt_[* opt]&] +[s2;%% Speed or size optimization flag&] +[s3; &] +[s4; &] +[s5;:File`:`:name: [_^String^ String]_[* name]&] +[s2;%% Filename, as specified in .upp file&] +[s3; &] +[s4; &] +[s5;:File`:`:lang: [_^String^ String]_[* lang]&] +[s2;%% Programming language, one of cxx, c, brc, guessed by extension.&] +[s3; &] +[s4; &] +[s3; &] +[s0; &] +[s3; &] +[s1;:OptItem`:`:struct: [@(0.0.255) struct]_[* OptItem]&] +[s2;%% Class holding any information from .upp file that has WHEN +clause.&] +[s0;%% &] +[s4; &] +[s5;:OptItem`:`:when: [_^String^ String]_[* when]&] +[s2;%% When clause&] +[s3; &] +[s4; &] +[s5;:OptItem`:`:item: [_^String^ String]_[* item]&] +[s2;%% The value&] +[s3; &] +[s4; &] +[s5;:OptItem`:`:state: [@(0.0.255) mutable]_OptState_[* state]&] +[s2;%% UNKNOWN if the clause wasn`'t evaluated yet, otherwise YES +or NO, depending on the evaluation result.&] +[s3; &] +[s0;%% ] \ No newline at end of file diff --git a/uppbox/UppBuilder/src.tpp/Parser$en-us.tpp b/uppbox/UppBuilder/src.tpp/Parser$en-us.tpp new file mode 100644 index 000000000..ba44a9517 --- /dev/null +++ b/uppbox/UppBuilder/src.tpp/Parser$en-us.tpp @@ -0,0 +1,31 @@ +topic "class Parser"; +[ $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9; $$1,0#37138531426314131252341829483380:structitem] +[l288;2 $$2,0#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:codeitem] +[{_} +[s1;:Parser`:`:class: [@(0.0.255) class]_[* Parser]&] +[s2;%% Main class that does all the work: loads the main package and +all its dependencies, evaluates the contents and outputs the +results. The output writer is interchangeable to allow generating +information to various build systems.&] +[s3; &] +[s4; &] +[s5;:Parser`:`:Parser`(const char`*`): [* Parser]([@(0.0.255) const]_[@(0.0.255) char`*]_[*@3 m +ainpkg])&] +[s2;%% Constructor, the parameter [%-*@3 mainpkg] specifies which package +should be parsed, everything else is determined from [^topic`:`/`/UppBuilder`/srcdoc`/environment`$en`-us^ e +nvironment variables]&] +[s3;%% &] +[s4; &] +[s5;:Parser`:`:Process`(`): [@(0.0.255) void]_[* Process]()&] +[s2;%% The output function, called when everything is parsed. It +can access all the information gathered in the parsing stage +in order to do whatever necessary to build the package. This +function is supplied by backend via macro definition, so it can +do exactly what the backend needs, e.g. generate makefile or +even call the compiler itself. &] +[s3; &] +[s0;%% ] \ No newline at end of file diff --git a/uppbox/UppBuilder/src.tpp/String$en-us.tpp b/uppbox/UppBuilder/src.tpp/String$en-us.tpp new file mode 100644 index 000000000..81e353f97 --- /dev/null +++ b/uppbox/UppBuilder/src.tpp/String$en-us.tpp @@ -0,0 +1,112 @@ +topic "class String"; +[ $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9; $$1,0#37138531426314131252341829483380:structitem] +[l288;2 $$2,0#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:codeitem] +[{_} +[s1;:String`:`:class: [@(0.0.255) class]_[* String]&] +[s2;%% Class implementing a very basic String. The idea behind reimplementing +such basic thing is to avoid including a huge portion of U`+`+/STL, +which slows down compilation and also add dependencies.&] +[s3; &] +[s4; &] +[s5;:String`:`:String`(`): [* String]()&] +[s2;%% Default constructor&] +[s3; &] +[s4; &] +[s5;:String`:`:String`(const String`&`): [* String]([@(0.0.255) const]_[* String][@(0.0.255) `& +]_[*@3 s])&] +[s5;:String`:`:String`(const char`*`): [* String]([@(0.0.255) const]_[@(0.0.255) char`*]_[*@3 s +])&] +[s2;%% Copy constructors&] +[s3;%% &] +[s4; &] +[s5;:String`:`:`~String`(`): [@(0.0.255) `~][* String]()&] +[s2;%% Destructor&] +[s3; &] +[s4; &] +[s5;:String`:`:operator`[`]`(const int`)const: [@(0.0.255) char`&]_[* operator`[`]]([@(0.0.255) c +onst]_[@(0.0.255) int]_[*@3 n])_[@(0.0.255) const]&] +[s2;%% Returns [%-*@3 n]th character&] +[s3;%% &] +[s4; &] +[s5;:String`:`:IsEmpty`(`)const: [@(0.0.255) bool]_[* IsEmpty]()_[@(0.0.255) const]&] +[s2;%% Returns true if the String is empty&] +[s3; &] +[s4; &] +[s5;:String`:`:operator`~`(`)const: [@(0.0.255) const]_[@(0.0.255) char`*]_[* operator`~]() +_[@(0.0.255) const]&] +[s2;%% Returns pointer to internal char`* representation, similar +to std`::string.c`_str()&] +[s3; &] +[s4; &] +[s5;:String`:`:operator const char`*`(`)const: [* operator_const_char`*]()_[@(0.0.255) co +nst]&] +[s2;%% Converts String to const char`*&] +[s3; &] +[s4; &] +[s5;:String`:`:operator`=`(const String`&`): [_^String^ String][@(0.0.255) `&]_[* operator`= +]([@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 s])&] +[s5;:String`:`:operator`=`(const char`*`): [_^String^ String][@(0.0.255) `&]_[* operator`=]( +[@(0.0.255) const]_[@(0.0.255) char`*]_[*@3 s])&] +[s2;%% Assignment operators&] +[s3;%% &] +[s4; &] +[s5;:String`:`:operator`=`=`(const char`*`)const: [@(0.0.255) bool]_[* operator`=`=]([@(0.0.255) c +onst]_[@(0.0.255) char`*]_[*@3 s])_[@(0.0.255) const]&] +[s5;:String`:`:operator`=`=`(const String`&`)const: [@(0.0.255) bool]_[* operator`=`=]([@(0.0.255) c +onst]_[_^String^ String][@(0.0.255) `&]_[*@3 s])_[@(0.0.255) const]&] +[s2;%% Compares string with [%-*@3 s].&] +[s3; &] +[s4; &] +[s5;:String`:`:Clear`(`): [@(0.0.255) void]_[* Clear]()&] +[s2;%% Empties the String&] +[s3; &] +[s4; &] +[s5;:String`:`:GetCount`(`)const: [@(0.0.255) int]_[* GetCount]()_[@(0.0.255) const]&] +[s2;%% Returns number of characters stored&] +[s3; &] +[s4; &] +[s5;:String`:`:operator`+`=`(const String`&`): [_^String^ String][@(0.0.255) `&]_[* operato +r`+`=]([@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 s])&] +[s5;:String`:`:operator`+`=`(char`): [_^String^ String][@(0.0.255) `&]_[* operator`+`=]([@(0.0.255) c +har]_[*@3 s])&] +[s2;%% Adds [%-*@3 s] at the end of the String&] +[s3; &] +[s4; &] +[s5;:String`:`:Compare`(const char`*`,int`)const: [@(0.0.255) int]_[* Compare]([@(0.0.255) c +onst]_[@(0.0.255) char`*]_[*@3 s], [@(0.0.255) int]_[*@3 len][@(0.0.255) `=`-][@3 1])_[@(0.0.255) c +onst]&] +[s2;%% Compares the string to [%-*@3 s]. If [%-*@3 len] > 0, then only +first [%-*@3 len] characters is considered.&] +[s3;%% &] +[s4; &] +[s5;:String`:`:FindLast`(const char`)const: [@(0.0.255) int]_[* FindLast]([@(0.0.255) const +]_[@(0.0.255) char]_[*@3 c])_[@(0.0.255) const]&] +[s2;%% Find last occurrence of character [%-*@3 c].&] +[s4; &] +[s5;:String`:`:Find`(const char`*`)const: [@(0.0.255) int]_[* Find]([@(0.0.255) const]_[@(0.0.255) c +har`*]_[*@3 s])_[@(0.0.255) const]&] +[s2;%% Find first occurrence of string [%-*@3 s].&] +[s3;%% &] +[s4; &] +[s5;:String`:`:Mid`(const int`,const int`)const: [_^String^ String]_[* Mid]([@(0.0.255) con +st]_[@(0.0.255) int]_[*@3 start], [@(0.0.255) const]_[@(0.0.255) int]_[*@3 length][@(0.0.255) `= +`-][@3 1])_[@(0.0.255) const]&] +[s2;%% Returns a substring starting at [%-*@3 start]. If [%-*@3 length] +> 0 the returned string si truncated to the [%-*@3 length] characters.&] +[s3;%% &] +[s4; &] +[s5;:operator`+`(const String`&`,const String`&`): [_^String^ String]_[* operator`+]([@(0.0.255) c +onst]_[_^String^ String][@(0.0.255) `&]_[*@3 lhs], [@(0.0.255) const]_[_^String^ String][@(0.0.255) `& +]_[*@3 rhs])&] +[s2;%% Concatenates [%-*@3 lhs] and [%-*@3 rhs].&] +[s3;%% &] +[s4; &] +[s5;:operator`<`(const String`&`,const String`&`): [@(0.0.255) int]_[* operator<]([@(0.0.255) c +onst]_[_^String^ String][@(0.0.255) `&]_[*@3 lhs], [@(0.0.255) const]_[_^String^ String][@(0.0.255) `& +]_[*@3 rhs])&] +[s2;%% Compares [%-*@3 lhs] and [%-*@3 rhs].&] +[s0;%% ] \ No newline at end of file diff --git a/uppbox/UppBuilder/src.tpp/Upp$en-us.tpp b/uppbox/UppBuilder/src.tpp/Upp$en-us.tpp new file mode 100644 index 000000000..ff3634a12 --- /dev/null +++ b/uppbox/UppBuilder/src.tpp/Upp$en-us.tpp @@ -0,0 +1,19 @@ +topic "struct Upp"; +[ $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9; $$1,0#37138531426314131252341829483380:structitem] +[l288;2 $$2,0#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:codeitem] +[{_} +[s1;:Upp`:`:struct: [@(0.0.255) struct]_[* Upp]&] +[s2;%% Struct representing all data found in .upp file&] +[s3; &] +[s4; &] +[s5;:Upp`:`:Load`(const String`&`,const Vector``&`): [_^Upp^ Upp][@(0.0.255) `&]_ +[* Load]([@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 package],[@(0.0.255) const +]_[_^Vector^ Vector]<[_^String^ String]>`&_[*@3 nests])&] +[s2;%% Finds [%-*@3 package] in [%-*@3 nests] and reads all information +from its .upp file&] +[s3;%% &] +[s0;%% ] \ No newline at end of file diff --git a/uppbox/UppBuilder/src.tpp/Vector$en-us.tpp b/uppbox/UppBuilder/src.tpp/Vector$en-us.tpp new file mode 100644 index 000000000..1005e4a0a --- /dev/null +++ b/uppbox/UppBuilder/src.tpp/Vector$en-us.tpp @@ -0,0 +1,63 @@ +topic "class Vector"; +[ $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9; $$1,0#37138531426314131252341829483380:structitem] +[l288;2 $$2,0#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:codeitem] +[{_} +[s1;:noref: [@(0.0.255) template]_<[@(0.0.255) class]_[*@4 T]>&] +[s1;:Vector`:`:class: [@(0.0.255) class]_[* Vector]&] +[s2;%% Class template implementing a very basic Vector container. +The idea behind reimplementing such basic thing is to avoid including +a huge portion of U`+`+/STL, which slows down compilation and +also add dependencies.&] +[s4; &] +[s5;:Vector`:`:Vector`(`): [* Vector]()&] +[s2;%% Default constructor&] +[s3; &] +[s4; &] +[s5;:Vector`:`:`~Vector`(`): [@(0.0.255) `~][* Vector]()&] +[s2;%% Destructor&] +[s3; &] +[s4; &] +[s5;:Vector`:`:GetCount`(`)const: [@(0.0.255) int]_[* GetCount]()[@(0.0.255) const]&] +[s2;%% Returns the number of elements stored&] +[s3; &] +[s4; &] +[s5;:Vector`:`:operator`[`]`(int`): [*@4 T][@(0.0.255) `&]_[* operator`[`]]([@(0.0.255) int]_ +[*@3 n])&] +[s2;%% Returns reference to element stored at [%-*@3 n]th position&] +[s3;%% &] +[s4; &] +[s5;:Vector`:`:operator`[`]`(int`)const: [@(0.0.255) const]_[*@4 T][@(0.0.255) `&]_[* operato +r`[`]]([@(0.0.255) int]_[*@3 n])_[@(0.0.255) const]&] +[s2;%% Returns const reference to element stored at [%-*@3 n]th position&] +[s3;%% &] +[s4; &] +[s5;:Vector`:`:Add`(`): [*@4 T][@(0.0.255) `&]_[* Add]()&] +[s2;%% Adds default constructed element at the end of the vector&] +[s3; &] +[s4; &] +[s5;:Vector`:`:Add`(const T`&`): [*@4 T][@(0.0.255) `&]_[* Add]([@(0.0.255) const]_[*@4 T][@(0.0.255) `& +]_[*@3 x])&] +[s2;%% Adds an element copy constructed from [%-*@3 x] at the end of +the vector&] +[s3;%% &] +[s4; &] +[s5;:Vector`:`:AddUnique`(const T`&`): [*@4 T][@(0.0.255) `&]_[* AddUnique]([@(0.0.255) const +]_[*@4 T][@(0.0.255) `&]_[*@3 v])&] +[s2;%% Adds element [%-*@3 v] at the end of the vector if it doesn`'t +exist already&] +[s3;%% &] +[s4; &] +[s5;:Vector`:`:Find`(const T`&`)const: [@(0.0.255) int]_[* Find]([@(0.0.255) const]_[*@4 T][@(0.0.255) `& +]_[*@3 v])_[@(0.0.255) const]&] +[s2;%% Returns position of [%-*@3 v] in the vector, or `-1 if not present&] +[s3;%% &] +[s4; &] +[s5;:Vector`:`:Resize`(int`): [@(0.0.255) void]_[* Resize]([@(0.0.255) int]_[*@3 len])&] +[s2;%% Allocates memory for [%-*@3 len] fields. If the vector is longer, +it is truncated.&] +[s3;%% &] +[s0;%% ] \ No newline at end of file diff --git a/uppbox/UppBuilder/src.tpp/global$en-us.tpp b/uppbox/UppBuilder/src.tpp/global$en-us.tpp new file mode 100644 index 000000000..2a0c6d634 --- /dev/null +++ b/uppbox/UppBuilder/src.tpp/global$en-us.tpp @@ -0,0 +1,53 @@ +topic "global functions"; +[ $$0,0#00000000000000000000000000000000:Default] +[H6;0 $$1,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$2,0#37138531426314131252341829483370:codeitem] +[l288;2 $$3,0#27521748481378242620020725143825:desc] +[0 $$4,0#96390100711032703541132217272105:end] +[i448;a25;kKO9; $$5,0#37138531426314131252341829483380:structitem] +[{_} +[s2;:NEVER`(T`): [@(0.0.255) template]_<[@(0.0.255) class]_[*@4 T]>_[@(0.0.255) void]_[* NEVER]( +[*@4 T]_[*@3 s])&] +[s3;%% Safely terminates the parser when [%-*@3 s] evaluates to true. +Used to end the execution in case of nonrecoverable state.&] +[s4;%% &] +[s1; &] +[s2;:Slashes`(String`&`): [@(0.0.255) void]_[* Slashes]([_^String^ String][@(0.0.255) `&]_[*@3 s +])&] +[s3;%% Converts all backslashes in [%-*@3 s] to forward slashes.&] +[s4;%% &] +[s1; &] +[s2;:BaseName`(const String`&`): [_^String^ String]_[* BaseName]([@(0.0.255) const]_[_^String^ S +tring][@(0.0.255) `&]_[*@3 s])&] +[s3;%% Returns everything after last `'/`' character in [%-*@3 s].&] +[s4;%% &] +[s1; &] +[s2;:DirName`(const String`&`): [_^String^ String]_[* DirName]([@(0.0.255) const]_[_^String^ S +tring][@(0.0.255) `&]_[*@3 s])&] +[s3;%% Returns everything before last `'/`' character in [%-*@3 s].&] +[s4;%% &] +[s1; &] +[s2;:LoadFile`(const String`&`): [_^String^ String]_[* LoadFile]([@(0.0.255) const]_[_^String^ S +tring][@(0.0.255) `&]_[*@3 fn])&] +[s3;%% Loads content of file [%-*@3 fn] into string.&] +[s4;%% &] +[s1; &] +[s2;:GetEnv`(const char`*`,const char`*`): [_^String^ String]_[* GetEnv]([@(0.0.255) const]_ +[@(0.0.255) char`*]_[*@3 n],[@(0.0.255) const]_[@(0.0.255) char`*]_[*@3 s][@(0.0.255) `=]`"`" +)&] +[s3;%% Reads environment variable UPP`_[%-*@3 n], if no such variable +is found then [%-*@3 s] is returned.&] +[s4;%% &] +[s1; &] +[s2;:Split`(String`,Vector``&`): [@(0.0.255) void]_[* Split]([_^String^ String]_[*@3 s +],[_^Vector^ Vector]<[_^String^ String]>`&_[*@3 v])&] +[s3;%% Splits string [%-*@3 s] at spaces and adds each chunk into vector +[%-*@3 v].&] +[s4;%% &] +[s1; &] +[s2;:FlagDir`(const Vector``&`): [_^String^ String]_[* FlagDir]([@(0.0.255) const]_ +[_^Vector^ Vector]<[_^String^ String]>`&_[*@3 v])&] +[s3;%% Sorts contents of [%-*@3 v] alphabetically and concatenates +it into string with `'.`' as delimiters&] +[s4;%% &] +[s0;%% ] \ No newline at end of file diff --git a/uppbox/UppBuilder/srcdoc.tpp/TODO$en-us.tpp b/uppbox/UppBuilder/srcdoc.tpp/TODO$en-us.tpp new file mode 100644 index 000000000..0e0b96024 --- /dev/null +++ b/uppbox/UppBuilder/srcdoc.tpp/TODO$en-us.tpp @@ -0,0 +1,18 @@ +topic "TODO list"; +[ $$0,0#00000000000000000000000000000000:Default] +[{_}%EN-US +[s0; Parser:&] +[s0;i150;O0; Finish custom build steps support&] +[s0;i150;O0; Separate parsing from output&] +[s0;i150;O0; Pretify (remove useless variables, remove DBGs, ...)&] +[s0;i150;O0; Add comments&] +[s0;i150;O0; Extend interactive mode&] +[s0; &] +[s0; Generated makefile:&] +[s0;i150;O0; Simplify and shorten&] +[s0; &] +[s0; Ideas for future:&] +[s0;i150;O0; Shell backend `- building without make&] +[s0;i150;O0; other common build systems `- cmake, scons, waf, ...&] +[s0;i150;O0; BLITZ support&] +[s0; ] \ No newline at end of file diff --git a/uppbox/UppBuilder/srcdoc.tpp/deps$en-us.tpp b/uppbox/UppBuilder/srcdoc.tpp/deps$en-us.tpp new file mode 100644 index 000000000..144fbf634 --- /dev/null +++ b/uppbox/UppBuilder/srcdoc.tpp/deps$en-us.tpp @@ -0,0 +1,46 @@ +topic "Dependencies"; +[2 $$0,0#00000000000000000000000000000000:Default] +[l288;i1120;a17;O9;~~~.1408;2 $$1,0#10431211400427159095818037425705:param] +[a83;*R6 $$2,5#31310162474203024125188417583966:caption] +[H4;b83;*4 $$3,5#07864147445237544204411237157677:title] +[i288;O9;C2 $$4,6#40027414424643823182269349404212:item] +[b42;a42;2 $$5,5#45413000475342174754091244180557:text] +[l288;b17;a17;2 $$6,6#27521748481378242620020725143825:desc] +[l321;C@5;1 $$7,7#20902679421464641399138805415013:code] +[b2503;2 $$8,0#65142375456100023862071332075487:separator] +[*@(0.0.255)2 $$9,0#83433469410354161042741608181528:base] +[C2 $$10,0#37138531426314131251341829483380:class] +[l288;a17;*1 $$11,11#70004532496200323422659154056402:requirement] +[i417;b42;a42;O9;~~~.416;2 $$12,12#10566046415157235020018451313112:tparam] +[b167;C2 $$13,13#92430459443460461911108080531343:item1] +[i288;a42;O9;C2 $$14,14#77422149456609303542238260500223:item2] +[*@2$(0.128.128)2 $$15,15#34511555403152284025741354420178:NewsDate] +[l321;*C$7;2 $$16,16#03451589433145915344929335295360:result] +[l321;b83;a83;*C$7;2 $$17,17#07531550463529505371228428965313:result`-line] +[l160;*C+117 $$18,5#88603949442205825958800053222425:package`-title] +[2 $$19,0#53580023442335529039900623488521:gap] +[C2 $$20,20#70211524482531209251820423858195:class`-nested] +[b50;2 $$21,21#03324558446220344731010354752573:Par] +[{_}%EN-US +[s3; Dependencies&] +[s5; &] +[s5; The Makefile produced by this package when MAKE flag is specified +aims to be as universal as possible, however it still depends +on couple programs:&] +[s5;i150;O0; make `- should POSIX compatible (see [^http`:`/`/pubs`.opengroup`.org`/onlinepubs`/009695399`/utilities`/make`.html^ h +ttp://pubs.opengroup.org/onlinepubs/009695399/utilities/make.html]), +GNU make and remake were tested&] +[s5;i150;O0; sed `- again POSIX compatible (see [^http`:`/`/pubs`.opengroup`.org`/onlinepubs`/009695399`/utilities`/sed`.html^ h +ttp://pubs.opengroup.org/onlinepubs/009695399/utilities/sed.html])&] +[s5;i150;O0; gzip&] +[s5;i150;O0; base64&] +[s5; Additionaly, for projects using BRC files:&] +[s5;i150;O0; grep&] +[s5;i150;O0; hexdump&] +[s5;i150;O0; bzip2 (only for BRC files that contain bzip2 compressed +resources)&] +[s5;i150;O0; couple standard utilities found on any system: dirname, +basename, mktemp and tee&] +[s5; &] +[s5; ... and of course a compiler (GCC and Clang tested), ar and +linker to build the executables] \ No newline at end of file diff --git a/uppbox/UppBuilder/srcdoc.tpp/environment$en-us.tpp b/uppbox/UppBuilder/srcdoc.tpp/environment$en-us.tpp new file mode 100644 index 000000000..58aa95493 --- /dev/null +++ b/uppbox/UppBuilder/srcdoc.tpp/environment$en-us.tpp @@ -0,0 +1,80 @@ +topic "Environment variables"; +[ $$0,0#00000000000000000000000000000000:Default] +[{_}%EN-US +[s0; The parser is influenced by several environment variables. &] +[s0; &] +[s0; Parser:&] +[ {{2738:1920:5342h1;^ [s0; [* Variable]] +:: [s0; [* Default]] +:: [s0; [* Meaning]] +:: [s0; UPP`_NESTS] +:: [s0; uppsrc bazaar reference tutorial examples] +:: [s0; Where to look for packages] +:: [s0; UPP`_FLAGS] +:: [s0; GCC GUI] +:: [s0; Build flags, same meaning as in theide] +:: [s0; UPP`_PLATFORM] +:: [s0; POSIX LINUX] +:: [s0; Additional flags describing platform] +:: [s0; UPP`_OPT] +:: [s0; ] +:: [s0; SPEED or SIZE to build optimized for speed or size respectively] +:: [s0; UPP`_USEMAINCFG] +:: [s0; 1] +:: [s0; Whether to add flags from based on mainconfig section (1`-based +index) or 0 to disable this feature] +:: [s0; UPP`_INTERACTIVE] +:: [s0; 0] +:: [s0; Whether the parser can ask for some ]}}&] +[s0; &] +[s0; &] +[s0; Make backend:&] +[ {{2451:4582:2967h1;^ [s0; [* Variable]] +:: [s0; [* Default]] +::= [s0; [* Meaning]] +::^ [s0; UPP`_OUT] +:: [s0; /tmp/`_out] +::=|14 [s0; See explanation of corresponding variables in Makefile.in ] +::^ [s0; UPP`_BIN] +:: [s0; `$(OUT)/bin] +::= [s0;%- ] +::^ [s0; UPP`_CFLAGS] +:: [s0; `-O2] +::= [s0;%- ] +::^ [s0; UPP`_CXXFLAGS] +:: [s0; `$(CFLAGS)] +::= [s0;%- ] +::^ [s0; UPP`_LDFLAGS] +:: [s0; `-Wl,`-`-gc`-sections `-Wl,`-s `-Wl,`-O,2] +::= [s0;%- ] +::^ [s0; UPP`_SPEEDFLAGS] +:: [s0; `-O3 `-ffunction`-sections `-fdata`-sections] +::= [s0;%- ] +::^ [s0; UPP`_SIZEFLAGS] +:: [s0; `-Os `-finline`-limit`=20 `-ffunction`-sections `-fdata`-sections] +::= [s0;%- ] +::^ [s0; UPP`_INCPATHS] +:: [s0; ] +::= [s0;%- ] +::^ [s0; UPP`_LIBPATHS] +:: [s0; ] +::= [s0;%- ] +::^ [s0; UPP`_CXX] +:: [s0; `$(CXX)] +::= [s0;%- ] +::^ [s0; UPP`_CC] +:: [s0; `$(CC)] +::= [s0;%- ] +::^ [s0; UPP`_AR] +:: [s0; ar `-src] +::= [s0;%- ] +::^ [s0; UPP`_DEPS] +:: [s0; 0] +::= [s0;%- ] +::^ [s0; UPP`_ECHO] +:: [s0; 0] +::= [s0;%- ] +::^ [s0; UPP`_SILENT] +:: [s0; 0] +::= [s0;%- ]}}&] +[s0; ] \ No newline at end of file diff --git a/uppbox/UppBuilder/update.sh b/uppbox/UppBuilder/update.sh new file mode 100644 index 000000000..190184f83 --- /dev/null +++ b/uppbox/UppBuilder/update.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# This script compresses the parser and embeds it into +# the Makefile, using Makefile.in template + +echo Updating Makefile + +# output file can be overriden by MAKEFILE_OUT variable +[ "$MAKEFILE_OUT" ] || MAKEFILE_OUT="/tmp/Makefile" + +{ + cat Makefile.in + + echo '### PARSER CODE (gzipped and base64 encoded) ###' + { + #we perform the '#include' first + sed '/#include PROCESS/,$d' Parser.cpp + cat Make.hpp + sed '1,/#include PROCESS/d' Parser.cpp + } | gzip -9 | base64 -w74 | sed 's/.*/#:&/;' + + echo '### BRC parser (gzipped and base64 encoded) ###' + cat brc.sh | gzip -9 | base64 -w74 | sed 's/.*/#~&/;' + + echo '### Colorizer (gzipped and base64 encoded) ###' + cat color.sh | gzip -9 | base64 -w74 | sed 's/.*/#%&/;' +} > "$MAKEFILE_OUT" + +# little trick to ensure Makefile is always "rebuild" +sh -c 'sleep 2 && touch Makefile.in'& + +exit 0 # comment this line out to see compression statistics + +stat() { + printf "%s %5i -> %5i %3i -> %3i\n" "$1"\ + `cat $2 | wc -c` `grep $3 "$MAKEFILE_OUT" | wc -c` \ + `cat $2 | wc -l` `grep $3 "$MAKEFILE_OUT" | wc -l` +} + +echo "Compression info:" +printf "%s%12s%14s\n" "File " bytes lines +stat "Parser " Parser.cpp '^#:' +stat "Brc parser" brc.sh '^#~' +stat "Colorizer " color.sh '^#%' +stat "Total " "Parser.cpp brc.sh color.sh" '^#[%~:]' +stat "Makefile " Makefile.in '^'