text:
<file_sep>package csr;

import java.util.ArrayList;
import java.util.*;

public class CarShowroom implements Comparable<CarShowroom> {
    String nazwa;
    List<Vehicle> listapoj=new ArrayList<>();;
    int pojemnosc;
    Map<String,Integer> ilosc_modeli= new LinkedHashMap<>();

    CarShowroom(String naz, int poj) {
        nazwa=naz;
        //List<Vehicle> listapoj = new ArrayList<>();
        pojemnosc=poj;
       // Map<String,Integer> ilosc_modeli = new LinkedHashMap<>();
    }

    public void addProduct(Vehicle poj){
        int il=1;
        if(listapoj.size() == pojemnosc){
            System.err.println("Brak miejsca");
        }
        else{
            for(Vehicle storedObject: listapoj){
                if(storedObject.compareTo(poj) == 0){
                    il++;
                }
            }
            listapoj.add(poj);
            ilosc_modeli.put(poj.marka+" "+poj.model,il);

        }
    }

    public void getProduct(Vehicle poj){
        if(ilosc_modeli.get(poj.marka+" "+poj.model)>1){
            int il=ilosc_modeli.get(poj.marka+" "+poj.model);
            //il--;
            //ilosc_modeli.put(poj.marka+" "+poj.model,il);
            ilosc_modeli.replace(poj.marka+" "+poj.model,il,il--);
        }else{
            ilosc_modeli.remove(poj.marka+" "+poj.model);
        }
        listapoj.remove(poj);
    }

    public void removeProduct(Vehicle poj){
        List<Vehicle> usuniete = new ArrayList<>();
        for(Vehicle storedObject: listapoj){
            if(storedObject.compareTo(poj) == 0){
                usuniete.add(storedObject);
            }
        }
        listapoj.removeAll(usuniete);
        ilosc_modeli.remove(poj.marka+" "+poj.model);

    }

    public Vehicle search(String nazw){
        //Vehicle zwroc = new Vehicle();
        for(Vehicle storedObject: listapoj){
            if(storedObject.compare(nazw) == 0){
                //storedObject.print();
                //return storedObject.Info();
                return storedObject;
            }
        }
        return null;
    }

    public void searchPartial(String n){
        for(Vehicle storedObject: listapoj){
            if(storedObject.marka.toLowerCase().contains(n.toLowerCase()) || storedObject.model.toLowerCase().contains(n.toLowerCase())){
                storedObject.print();
            }
        }

    }

    public void countByCondition(ItemCondition s){
        System.out.println("Wyszukiwanie pojazdów z "+nazwa+" o stanie "+s);

        for(Vehicle storedObject: listapoj){
            if(storedObject.stan.equals(s)){
               storedObject.print();
            }
        }

    }

    public void summary(){
        for(Vehicle storedObject: listapoj){
            storedObject.print();
            System.out.println(ilosc_modeli.get(storedObject.marka+" "+storedObject.model));
        }
    }

    public List<String> sortByName(){
        List<Vehicle> posortowana = new ArrayList<>(listapoj);
        Collections.sort(posortowana);
        Collections.reverse(posortowana);
        List<String> nazwy = new ArrayList<>();
        for(Vehicle cos1 :posortowana){
            nazwy.add(cos1.marka+" "+cos1.model);
        }
        return nazwy;

    }

    public List<String> getauta(){
        List<Vehicle> posortowana = new ArrayList<>(listapoj);
        Collections.sort(posortowana);
        List<String> nazwy = new ArrayList<>();
        for(Vehicle cos1 :posortowana){
            nazwy.add(cos1.marka+" "+cos1.model);
        }
        return nazwy;

    }

    public List<String> sortByAmount(){
        List<String> cos = new ArrayList<>();
        ilosc_modeli.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).forEachOrdered(map -> cos.add(map.getKey()));

//        for(String cos1: cos){
//            System.out.println(cos1);
//        }
        return cos;
    }
    public List<String> sortByAmount2(){
        List<String> cos = new ArrayList<>();
        ilosc_modeli.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).forEachOrdered(map -> cos.add(map.getKey()));

        Collections.reverse(cos);
        return cos;
    }

    public void max(){
        List<String> cos = new ArrayList<>();
        ilosc_modeli.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).forEachOrdered(map -> cos.add(map.getKey()));
        System.out.println(cos.get(0)+" "+ilosc_modeli.get(cos.get(0)));
    }

    @Override
    public int compareTo(CarShowroom o) {
        return nazwa.compareTo(o.nazwa);
    }
}
<file_sep>package zad3;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class SubStrTest {
    @Test
    public void ZawieraSie() {
        SubString s =new SubString("xyz","yzxyzxyzxyzx");
        int count=s.substring();
        assertEquals(count,5);
    }

    @Test
    public void NieZawieraSie()  {
        SubString s =new SubString("xyz","xxx");
        int count=s.substring();
        assertEquals(count,-1);
    }
}
<file_sep>public class Triangle extends Figure implements Printable {

    public double a;

    public Triangle(double bok){
        a=bok;
    }

    @Override
    public double calculateArea() {
        return (a*a*Math.sqrt(3))/2;
    }

    @Override
    public double calculatePerimeter() {
        return 3*a;
    }

    @Override
    public void print() {
        System.out.println("Pole trojkatu "+calculateArea());
        System.out.println("Obwod trojkatu "+calculatePerimeter());

    }

}
<file_sep>public class Circle extends Figure implements Printable {

    public double r;

    public Circle(double pr){
        r=pr;
    }

    @Override
    public double calculateArea() {
        return Math.PI*r*r;
    }

    @Override
    public double calculatePerimeter() {
        return 2*Math.PI*r;
    }

    @Override
    public void print() {
        System.out.println("Pole kola "+calculateArea());
        System.out.println("Obwod kola "+calculatePerimeter());

    }
}
<file_sep>import java.util.Scanner;

public class Prism implements Printable{

    Figure base;
    double h;

    public Prism(double w, double b){
        System.out.println("Wybierz podstawe");
        System.out.println("1->kwadrat, 2->kolo, 3->trojkat");
        Scanner scanner = new Scanner(System.in);
        int ch = scanner.nextInt();
        switch(ch){
            case 1:
                { base = new Square(b);}
            break;
            case 2:
                { base = new Circle(b);}
            break;
            case 3:
                { base = new Triangle(b);}
            break;
            default:
                {System.out.println("Nie wybrales podstawy");
                    base = new Square(b);}
            }
        h = w;
    }

    public double Obj(){
        return (base.calculateArea()*h);
    }

    public double Pole(){
        return (2*(base.calculateArea())+(base.calculatePerimeter())*h);
    }
    @Override
    public void print() {
        System.out.println("Objetosc to "+Obj());
        System.out.println("Pole to "+Pole());

    }
}
<file_sep>package zad2;

import java.util.ArrayList;
import java.util.List;

public class Spot {
    List<Integer> a;
    int target;
    //List<Integer> dziel_target= new ArrayList<>();

    public Spot(int t ,List<Integer> tab){
        a=tab;
        target=t;
    }

    public int[] spot(){

        int[] dziel={0,0};
        List<Integer> dziel_target= new ArrayList<>();
        //SZUKANIE DZIELNIKÓW
        for(int i=1; i<target;i++){
            if(target%i==0){
                dziel_target.add(i);
                dziel_target.add(-i);
            }
        }

        List<Integer> znal = new ArrayList<>();

        for(int szuk: a){
            if(dziel_target.contains(szuk)){
                znal.add(szuk);
            }
        }

        if(znal.isEmpty()){
            System.out.println("\nNie ma dzielników");
            dziel[0]=-1;
            dziel[1]=-1;
            //return dziel;
        }
        else{
            //int dziel1=0,dziel2=0;
            for(int i: znal){
            dziel[0]=i;
                if(znal.contains(target/dziel[0])){
                    if(i==target/dziel[0]){continue;}
                    else{dziel[1] = target/dziel[0];
                        break;
                }

            }
        }
            if(dziel[1]==0){
                System.out.println("\nNie znaleziono dzielników");

            }else{
                //System.out.println("\n("+dziel1+" ; "+dziel2+")");
            }

    }
        return dziel;
}

}
<file_sep>package zad1;

public class QuickSort implements sortStrategy{

    int[] tab;

    public QuickSort(int[] t){
        tab=t;
    }

    int partition( int low, int high)
    {
        int pivot = tab[high];
        int i = (low-1),temp; // index of smaller element
        for (int j=low; j<high; j++)
        {
            // If current element is smaller than the pivot
            if (tab[j] < pivot)
            {
                i++;

                // swap arr[i] and arr[j]
                temp = tab[i];
                tab[i] = tab[j];
                tab[j] = temp;
            }
        }

        // swap arr[i+1] and arr[high] (or pivot)
        temp = tab[i+1];
        tab[i+1] = tab[high];
        tab[high] = temp;

        return i+1;
    }

    void sortquick(int low, int high)
    {
        if (low < high)
        {
            int pi = partition( low, high);

            // Recursively sort elements before
            // partition and after partition
            sortquick(low, pi-1);
            sortquick(pi+1, high);
        }
    }

    @Override
    public int[] sort() {
        sortquick(0, tab.length-1);
        return tab;
    }
}
<file_sep>package ui;
import csr.*;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class MainUI {

    private JPanel rootPanel;
    private JPanel HeadPanel;
    private JPanel CarSRPanel;
    private JPanel CarPanel;
    private JPanel FootPanel;
    private JTable SalonTable;
    private JTable carsTable;
    private JTable specif;
    private JButton removeCrB;
    private JButton removeVehicleB;
    private JButton newCrB;
    private JButton newVehicleB;
    private JLabel tytul;
    private JButton sortButton;
    private JButton sort2Button;
    String[] nazkol=new String[1];
    public JPanel getRootPanel(){
        return rootPanel;
    }

    public MainUI(CarShowroomContainer csrc){
        nazkol[0]="CarShowRooms";
        CarAbsTModel tab1 = new CarAbsTModel(csrc.getNazwy(),nazkol);
        SalonTable.setModel(tab1);
        SalonTable.getSelectionModel().addListSelectionListener(e1 ->{
            if(SalonTable.getSelectedRow() > -1){
                nazkol[0]="Cars";
                CarAbsTModel tab2 = new CarAbsTModel(csrc.getCars(SalonTable.getValueAt(SalonTable.getSelectedRow(),0).toString()),nazkol);
                carsTable.setModel(tab2);
                carsTable.getSelectionModel().addListSelectionListener(e2 ->{
                    if(carsTable.getSelectedRow() > -1) {
                        nazkol[0] ="INFO";
                        CarAbsTModel tab3= new CarAbsTModel(csrc.getSalon(SalonTable.getValueAt(SalonTable.getSelectedRow(),0).toString()).search(carsTable.getValueAt(carsTable.getSelectedRow(),0).toString()).Info(),nazkol);
                        specif.setModel(tab3);
                    }
                });
            }
        });

        DefaultTableModel dModel = new DefaultTableModel();

        removeCrB.addActionListener(e3 ->{
            String w = SalonTable.getValueAt(SalonTable.getSelectedRow(),0).toString();
            csrc.removeCenter(w);
            nazkol[0]="CarShowRooms";
            CarAbsTModel tab_rCrSR = new CarAbsTModel(csrc.getNazwy(),nazkol);
            SalonTable.setModel(tab_rCrSR);
            carsTable.setModel(dModel);

        });

        removeVehicleB.addActionListener(e4 -> {
            String ktSalon = SalonTable.getValueAt(SalonTable.getSelectedRow(),0).toString();
            String ktProdukt = carsTable.getValueAt(carsTable.getSelectedRow(),0).toString();
            csrc.getSalon(ktSalon).getProduct(csrc.getSalon(ktSalon).search(ktProdukt));
            nazkol[0]="Cars";
            CarAbsTModel tab_rV = new CarAbsTModel(csrc.getCars(SalonTable.getValueAt(SalonTable.getSelectedRow(),0).toString()),nazkol);
            carsTable.setModel(tab_rV);
            specif.setModel(dModel);
        });

        newCrB.addActionListener(e5 ->{
            String nazwa=JOptionPane.showInputDialog("Podaj nazwe:");
            int pojemnosc=Integer.parseInt(JOptionPane.showInputDialog("Podaj pojemnosc: "));
            csrc.addCenter(nazwa,pojemnosc);
            nazkol[0]="CarShowRooms";
            CarAbsTModel tab_aC = new CarAbsTModel(csrc.getNazwy(),nazkol);
            SalonTable.setModel(tab_aC);
            carsTable.setModel(dModel);
            specif.setModel(dModel);
        });

        newVehicleB.addActionListener(e6 -> {
            String mar = JOptionPane.showInputDialog("Podaj marke:");
            String mod = JOptionPane.showInputDialog("Podaj model");
            String st = JOptionPane.showInputDialog("Podaj stan:");
            double c = Double.parseDouble(JOptionPane.showInputDialog("Podaj cene:"));
            int rok = Integer.parseInt(JOptionPane.showInputDialog("Podaj rok produkcji:"));
            int prze =Integer.parseInt(JOptionPane.showInputDialog("Podaj przebieg:"));
            double sil = Double.parseDouble(JOptionPane.showInputDialog("Podaj pojemnosc silnika"));
            ItemCondition stan;
            if(st.equals("NEW")) stan=ItemCondition.NEW;
            else if(st.equals("USED")) stan=ItemCondition.USED;
            else if(st.equals("DAMAGED")) stan=ItemCondition.DAMAGED;
            else stan=ItemCondition.USED;
            Vehicle auto = new Vehicle(mar,mod, stan,c,rok,prze,sil);
            String salon = SalonTable.getValueAt(SalonTable.getSelectedRow(),0).toString();
            csrc.getSalon(salon).addProduct(auto);
            nazkol[0]="Cars";
            CarAbsTModel tab_aV = new CarAbsTModel(csrc.getCars(SalonTable.getValueAt(SalonTable.getSelectedRow(),0).toString()),nazkol);
            carsTable.setModel(tab_aV);
            specif.setModel(dModel);
        });

        sortButton.addActionListener(e7 -> {
            nazkol[0] ="CarShowRooms";
            CarAbsTModel tab_s = new CarAbsTModel(csrc.sort(),nazkol);
            SalonTable.setModel(tab_s);
            carsTable.setModel(dModel);
            specif.setModel(dModel);
        });

        sort2Button.addActionListener(e7 -> {
            String w = SalonTable.getValueAt(SalonTable.getSelectedRow(),0).toString();
            CarShowroom salon = csrc.getSalon(w);
            int rodz = Integer.parseInt(JOptionPane.showInputDialog("Podaj rodzaj sortowanie 1->Nazwa ,2->Amount:"));
            nazkol[0] ="Cars";
            CarAbsTModel tab_s2;
            if(rodz==1){  tab_s2 = new CarAbsTModel(salon.sortByName(),nazkol);}
            else{ tab_s2 = new CarAbsTModel(salon.sortByAmount2(),nazkol);}
            carsTable.setModel(tab_s2);
            specif.setModel(dModel);
        });

    }
}
<file_sep>package zad1;

import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        int n = 11111;
        int[] spod = new int[n];
        int[] opt = new int[n];
        int[] pes = new int[n];

        Random generator = new Random();

        for(int i = 0; i < n; i++){
            spod[i] = generator.nextInt(1000);
            opt[i] = i;
            pes[i] = n-i;
        }
        Scanner input = new Scanner(System.in);
        Sort st=new Sort();
        System.out.println("Prosze wybrać metode sortowania : \n1->SelectionSort 2->BubbleSort 3->MergeSort 4->QuickSort 5->HeapSort");
        try{

            int w =input.nextInt();
            switch(w){
                case 1:
                    System.out.println("Oczekiwany");
                    st.set(new SelectionSort(spod));
                    st.print(spod);
                    System.out.println("Optymistyczny");
                    st.set(new SelectionSort(opt));
                    st.print(opt);
                    System.out.println("Pesymistyczny");
                    st.set(new SelectionSort(pes));
                    st.print(pes);
                    break;
                case 2:
                    System.out.println("Oczekiwany");
                    st.set(new BubbleSort(spod));
                    st.print(spod);
                    System.out.println("Optymistyczny");
                    st.set(new BubbleSort(opt));
                    st.print(opt);
                    System.out.println("Pesymistyczny");
                    st.set(new BubbleSort(pes));
                    st.print(pes);
                    break;
                case 3:
                    System.out.println("Oczekiwany");
                    st.set(new MargeSort(spod));
                    st.print(spod);
                    System.out.println("Optymistyczny");
                    st.set(new MargeSort(opt));
                    st.print(opt);
                    System.out.println("Pesymistyczny");
                    st.set(new MargeSort(pes));
                    st.print(pes);
                    break;
                case 4:
                    System.out.println("Oczekiwany");
                    st.set(new QuickSort(spod));
                    st.print(spod);
                    System.out.println("Optymistyczny");
                    st.set(new QuickSort(opt));
                    st.print(opt);
                    System.out.println("Pesymistyczny");
                    st.set(new QuickSort(pes));
                    st.print(pes);
                    break;
                case 5:
                    System.out.println("Oczekiwany");
                    st.set(new HeapSort(spod));
                    st.print(spod);
                    System.out.println("Optymistyczny");
                    st.set(new HeapSort(opt));
                    st.print(opt);
                    System.out.println("Pesymistyczny");
                    st.set(new HeapSort(pes));
                    st.print(pes);
                    break;
                default:
                    System.out.println("Nie wybrałeś żadnej opcji\n Koniec programu");
                    System.exit(0);            }

        }catch(InputMismatchException e){
            System.out.println("Zła wartość!");
            System.exit(-1);
        }

    }
}
<file_sep>package zad4;

public class NoTripletException extends  Exception{
    public NoTripletException(String bl){super(bl);}
}
<file_sep>package zad5;

public class Clock {
    public static void main(String [] args) throws MyException{
        int[]tab1;
        int[][] tab = {
                {1, 2, 3, 4, 5},
                { 6,  7,  8,  9, 10},
                {11, 12, 13, 14, 15},
                {16, 17, 18, 19, 20},
                {21, 22, 23, 24, 25}
        };
        if(tab.length <1 || tab[0].length<1){
            throw new MyException("To nie macierz");
        }else{tab1=printClock(tab);}

        System.out.println(" ");
         for(int i=0; i < 25 ;i++){
             System.out.print(tab1[i] + " ");
         }

    }

    public static int [] printClock(int[][] tab)  {
        int n = tab.length;
        int m= tab[0].length;
        int t=0;
        int b=n-1;
        int l=0;
        int r=m-1;
        int [] cos = new int[n*m];
        int c = 0;

        while(b>=t && r>=l){
            for(int i=t; i<=b; i++){
                System.out.print(tab[i][l] + " ");
                cos[c]=tab[i][l];
                c++;
            }
            l++;
            for(int j=l;j<=r;j++){
                System.out.print(tab[b][j]+" ");
                cos[c]=tab[b][j];
                c++;
            }
            b--;
            for(int j=b;j>=t;j--){
                System.out.print(tab[j][r]+" ");
                cos[c]=tab[j][r];
                c++;
            }
            r--;
            for(int j=r;j>=l;j--){
                System.out.print(tab[t][j]+ " ");
                cos[c]=tab[t][j];
                c++;
            }
            t++;
        }
        return cos;

    }
}
<file_sep>package zad3;

public class SubString {
    String a;
    String b;

    public SubString(String a1, String b1){
        a=a1;
        b=b1;
    }

    public int substring(){

        int i=1;
        String n_a=a;
        while(!(n_a.contains(b))){

            n_a+=a;
            i++;
            if(i>100){
                System.out.println("string b nie może sie zawierać sie w wielokrotnisci a");
                i=-1;
                break;
            }
        }
        return i;
    }
}
<file_sep>public class Square extends Figure implements Printable{

    public double a;

    public Square(double bok){
        a=bok;
    }

    @Override
    public double calculateArea() {
        return a*a;
    }

    @Override
    public double calculatePerimeter() {
        return 4*a;
    }

    @Override
    public void print() {
        System.out.println("Pole kwadratu "+calculateArea());
        System.out.println("Obwod kwadratu "+calculatePerimeter());

    }
}
<file_sep>package zad2;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

public class SpotTest {
    @Test
    public void DzielTest(){ // powinien znalezc
        int target = 8;
        List<Integer> tab =new ArrayList<>();
        tab.add(1);
        tab.add(4);
        tab.add(-2);
        tab.add(-4);
        tab.add(2);
        Spot n=new Spot(target,tab);
        int[] test = n.spot();
        assertTrue(test[1]!=0);
    }

    @Test
    public void BrakDzielTest(){ //nie ma dzielników
        int target = 8;
        List<Integer> tab =new ArrayList<>();
        tab.add(1);
        tab.add(5);
        tab.add(-3);
        tab.add(-9);
        tab.add(11);
        Spot n=new Spot(target,tab);
        int[] test = n.spot();
        assertFalse(test[1]!=0);
    }
    @Test
    public void JedenDzielTest(){  //jest  jeden
        int target = 16;
        List<Integer> tab =new ArrayList<>();
        tab.add(1);
        tab.add(4);
        tab.add(-2);
        tab.add(2);
        tab.add(2);
        Spot n=new Spot(target,tab);
        int[] test = n.spot();
        assertFalse(test[1]!=0);
    }
    @Test
    public void PierwszaTest(){  //liczba pierwsza
        int target = 11;
        List<Integer> tab =new ArrayList<>();
        tab.add(1);
        tab.add(4);
        tab.add(-2);
        tab.add(2);
        tab.add(2);
        Spot n=new Spot(target,tab);
        int[] test = n.spot();
        assertTrue( test[1]!=-1);
    }
}
<file_sep>package zad1;

import org.junit.jupiter.api.Test;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertTimeout;

public class TimeTests {
    Sort strat=new Sort();
    @Test
    public void quickSortTime()  {

        int[] tab ={9,3,4,2,1,5};

        strat.set(new QuickSort(tab));
        assertTimeout(Duration.ofMillis(5),()->strat.print(tab));
    }

    @Test
    public void mergeSortTime()  {

        int[] tab ={9,3,4,2,1,5};

        strat.set(new MargeSort(tab));
        assertTimeout(Duration.ofMillis(5),()->strat.print(tab));
    }

    @Test
    public void bubbleSortTime()  {

        int[] tab ={9,3,4,2,1,5};

        strat.set(new BubbleSort(tab));
        assertTimeout(Duration.ofMillis(5),()->strat.print(tab));
    }

    @Test
    public void heapSortTime() {

        int[] tab ={9,3,4,2,1,5};

        strat.set(new HeapSort(tab));
        assertTimeout(Duration.ofMillis(5),()->strat.print(tab));
    }

    @Test
    public void selectionSortTime()  {

        int[] tab ={9,3,4,2,1,5};

        strat.set(new SelectionSort(tab));
        assertTimeout(Duration.ofMillis(5),()->strat.print(tab));
    }

}
<file_sep>package zad4;

import zad1.HeapSort;
public class Main {
    public static void main(String [] args) throws NoTripletException {
        int[] tab={-5,-7};
        HeapSort hs = new HeapSort(tab);
        tab=hs.sort();
        int suma;
        if(tab.length < 3){
            throw new NoTripletException("Za mała długość tablicy");
        }else
        {
            suma=Triplet(tab);
            System.out.println("Suma 3 największych wartości to: "+suma);
        }

    }

    public static int Triplet(int[] t){
        int suma =0;
        for(int i = t.length-3;i<t.length;i++){
            suma+=t[i];
        }

        return suma;

    }
}
<file_sep>package zad3;

public class Main {
    public static void main(String [] args){
        SubString s=new SubString("x","xxxy");
        System.out.print("Liczba powtórzeń: "+s.substring());
    }
}
<file_sep>package csr;

import java.util.*;

public class CarShowroomContainer {
    Map<String, CarShowroom> salony = new LinkedHashMap<String, CarShowroom>();
    List<CarShowroom> nazwy = new LinkedList<>();

    CarShowroomContainer(){ }

    public CarShowroom addCenter(String n, int i){
       CarShowroom salon = new CarShowroom(n,i);
        salony.put(n,salon);
        nazwy.add(salon);
        return salon;
    }

    public void removeCenter(String n){
        System.out.println("Zostanie usuniety: "+n);
        salony.remove(n);
    }

    public void findEmpty(){
        System.out.println("Pyste salony to: ");
        for(CarShowroom puste: salony.values()){
            if(puste.listapoj.size() == 0){
                System.out.println(puste.nazwa);
            }
        }
    }

    public List<String> sort(){

        List<String> nazwSort = new LinkedList<>();
       nazwy.sort(comparator);
        for(CarShowroom c: nazwy){
            nazwSort.add(c.nazwa);
            //System.out.println(nazwSort);
        }
        //System.out.println(nazwSort);

        return nazwSort;
    }

    public void summary(){
        double zapel;
        for(CarShowroom znal: salony.values()){
            zapel=znal.listapoj.size()/ (double)znal.pojemnosc;
            zapel*=100;
            System.out.println(znal.nazwa+" jest zapełniony w "+zapel+"%");
        }

    }

    public List<String> getNazwy() {
        List<String> cos = new ArrayList<>();
        salony.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.<String, CarShowroom>comparingByValue())).forEachOrdered(map -> cos.add(map.getKey()));

        return cos;

    }

    public List<String> getCars(String sal) {
        CarShowroom salon= salony.get(sal);
        List<String> cos = salon.getauta();
        //salon.ilosc_modeli.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).forEachOrdered(map -> cos.add(map.getKey()));

        return cos;

    }

    Comparator<CarShowroom> comparator=new Comparator<CarShowroom>() {
        @Override
        public int compare(CarShowroom o1, CarShowroom o2) {
            return Integer.compare(o2.listapoj.size(),o1.listapoj.size());
        }
    };

    public CarShowroom getSalon(String sal) {
        return salony.get(sal);
    }
}
<file_sep>package csr;

import java.util.ArrayList;
import java.util.List;

public class Vehicle implements Comparable<Vehicle> {
    String marka;
    String model;
    ItemCondition stan;
    double cena;
    int rok_produkcji;
    double przebieg;
    double poj_silnika;

    public Vehicle(String mar, String mo, ItemCondition st, double c, int rok, double pr, double sil){
        marka=mar;
        model=mo;
        stan=st;
        cena=c;
        rok_produkcji=rok;
        przebieg=pr;
        poj_silnika=sil;
    }

    Vehicle(){
        marka="Fiat";
        model="Uno";
        stan=ItemCondition.DAMAGED;
        cena=100;
        rok_produkcji=1998;
        przebieg=1000000;
        poj_silnika=1.0;
    }

    public void print(){
        System.out.println("Pojazd to "+marka+" "+model+" stan: "+stan);
        System.out.println("Cena to: "+cena+" Rok produkcji "+rok_produkcji+" Przebieg "+przebieg+" Pojemność "+poj_silnika);

    }

    public List<String> Info(){
        List<String> info = new ArrayList<>();
        info.add(marka+" "+model);
        info.add(String.valueOf("Stan "+stan));
        info.add(String.valueOf("Cena auta "+cena+"zł"));
        info.add(String.valueOf(rok_produkcji));
        info.add(String.valueOf("Przebieg "+przebieg));
        info.add(String.valueOf("Silnik "+poj_silnika));
        return info;

    }

    @Override
    public int compareTo(Vehicle o) {
        String nazwa1 = marka+" "+model;
        String nazwa2 = o.marka+" "+o.model;
        return nazwa1.compareTo(nazwa2);
    }

    public int compare(String nazwa_poj){
        return nazwa_poj.compareTo(marka+" "+model);
    }
}

repo_language: Java


text:
<file_sep># NGM.OpenAuthentication
Provides multiple authentication features for Orchard CMS using OpenId, OAuth, OAuth2, and AzureAD

Currently requires you to add an assembly redirect to the root Orchard web.config file:
```xml
<dependentAssembly>
   <assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="<KEY>" culture="neutral" />
	 <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
</dependentAssembly>
```

I'm working on finding a cleaner solution
<file_sep>using System;
using System.IO;
using DotNetOpenAuth.AspNet;
using DotNetOpenAuth.AspNet.Clients;
using DotNetOpenAuth.GoogleOAuth2;
using NGM.OpenAuthentication.Models;

namespace NGM.OpenAuthentication.Services.Clients
{
    public class GoogleAuthenticationClient : IExternalAuthenticationClient
    {
        public string ProviderName
        {
            get { return "Google"; }
        }

        public IAuthenticationClient Build(ProviderConfigurationRecord providerConfigurationRecord) {
            var client = new GoogleOAuth2Client(providerConfigurationRecord.ProviderIdKey, providerConfigurationRecord.ProviderSecret);

            return client;
        }
    }
}

branch_name: refs/heads/master

languages: C# Markdown

repo_language: C#


text:
<file_sep>#### Реализовано:
- Обработка пользовательского ввода при помощи событий pointer-event
- Реализованы жесты перетаскивания, пинча и свайпа
- Для корректной работы использован setPointerCapture
- Расставлены префиксы для css свойств

#### Прохождение игры:
- Дверь 2: Необходимо найти попарное соответствие символов.
Например число 5 представлено двумя разными способами, как звезда и как ладонь.
Сопоставление всех пар позволит найти путь к потерянной карте.
- Дверь 3: Карта нашлась, но к сожалению она была сильно повреждена и на ней не видно где же находится сундук.
Необходимо восстановить карту из найденных кусочков при помощи жестов зума.
- Сундук: Сундук с сокровищами найден, но он закрыт, ключ находится где то поблизости от него.
Необходимо расчистить камни и найти ключ, при помощи которого открыть сундук.
Камни очень тяжелые, связаны друг с другом и могут быть расчищены только последовательно. Кодовое слово Yandex.

<file_sep>// ===================== Пример кода первой двери =======================
/**
 * @class Door0
 * @augments DoorBase
 * @param {Number} number
 * @param {Function} onUnlock
 */
function Door0(number, onUnlock) {
    DoorBase.apply(this, arguments);

    var buttons = [
        this.popup.querySelector('.door-riddle__button_0'),
        this.popup.querySelector('.door-riddle__button_1'),
        this.popup.querySelector('.door-riddle__button_2')
    ];

    buttons.forEach(function(b) {
        b.addEventListener('pointerdown', _onButtonPointerDown.bind(this));
        b.addEventListener('pointerup', _onButtonPointerUp.bind(this));
        b.addEventListener('pointercancel', _onButtonPointerUp.bind(this));
        b.addEventListener('pointerleave', _onButtonPointerUp.bind(this));
    }.bind(this));

    function _onButtonPointerDown(e) {
        e.target.classList.add('door-riddle__button_pressed');
        checkCondition.apply(this);
    }

    function _onButtonPointerUp(e) {
        e.target.classList.remove('door-riddle__button_pressed');
    }

    /**
     * Проверяем, можно ли теперь открыть дверь
     */
    function checkCondition() {
        var isOpened = true;
        buttons.forEach(function(b) {
            if (!b.classList.contains('door-riddle__button_pressed')) {
                isOpened = false;
            }
        });

        // Если все три кнопки зажаты одновременно, то откроем эту дверь
        if (isOpened) {
            this.unlock();
        }
    }
}

// Наследуемся от класса DoorBase
Door0.prototype = Object.create(DoorBase.prototype);
Door0.prototype.constructor = DoorBase;
// END ===================== Пример кода первой двери =======================

/**
 * @class Door1
 * @augments DoorBase
 * @param {Number} number
 * @param {Function} onUnlock
 */
function Door1(number, onUnlock) {
    DoorBase.apply(this, arguments);

    // ==== Напишите свой код для открытия второй двери здесь ====

    // Сохранение списка знаков и информации о них, с содержанием привязки каждого знака попарно
    var signList = this.popup.querySelector('.door-riddle__sign-list');
    var signs = [];
    for (var i = 0; i < signList.children.length; i++) {
        var sign = this.popup.querySelector('.door-riddle__sign_' + i);
        var matchSign = this.popup.querySelector('.' + sign.dataset.match);
        sign.info = {
            startPosition: {},
            currentPosition: {},
            match: matchSign,
            pressed: false
        }
        signs.push(sign);
    }

    // Подписка на события указателя
    signs.forEach(function(s) {
        s.addEventListener('pointerdown', _onButtonPointerDown.bind(this));
        s.addEventListener('pointermove', _onButtonPointerMove.bind(this));
        s.addEventListener('pointerup', _onButtonPointerUp.bind(this));
        s.addEventListener('pointercancel', _onButtonPointerUp.bind(this));
        s.addEventListener('pointerleave', _onButtonPointerUp.bind(this));
    }.bind(this));

    // Обработчик нажатия на знак
    function _onButtonPointerDown(e) {
        var sign = e.target;
        sign.setPointerCapture(e.pointerId);
        sign.info.startPosition.X = e.pageX;
        sign.info.startPosition.Y = e.pageY;
        sign.info.currentPosition.X = e.pageX;
        sign.info.currentPosition.Y = e.pageY;
        sign.info.pressed = true;
    }

    // Обработчик перемещения указателя
    function _onButtonPointerMove(e) {
        var sign = e.target;
        if (!sign.info.pressed) {
            return;
        }

        sign.info.currentPosition.X = e.pageX;
        sign.info.currentPosition.Y = e.pageY;
        moveSign(sign);
    }

    // Обработчик отжатия указателя
    function _onButtonPointerUp(e) {
        var sign = e.target;
        if (!sign.info.pressed) {
            return;
        }
        sign.info.pressed = false;

        checkSign(sign);
        checkCondition.apply(this);
        requestAnimationFrame(function() {
            sign.style.transform = 'translate3d(0,0,0)';
            sign.style.webkitTransform = 'translate3d(0,0,0)';
        });
    }

    // Метод перемещения знака
    function moveSign(sign) {
        requestAnimationFrame(function() {
            var diffX = sign.info.currentPosition.X - sign.info.startPosition.X;
            var diffY = sign.info.currentPosition.Y - sign.info.startPosition.Y;
            sign.style.transform = 'translate3d('+ diffX +'px, '+ diffY +'px, 0px)';
            sign.style.webkitTransform = 'translate3d('+ diffX +'px, '+ diffY +'px, 0px)';
        });
    }

    // Метод проверки соответствия знака
    function checkSign(sign) {
        var signRect = sign.getBoundingClientRect();
        var matchRect = sign.info.match.getBoundingClientRect();
        if (hasIntersection(signRect, matchRect)) {
           sign.classList.add('door-riddle__sign_matched');
           sign.info.match.classList.add('door-riddle__sign_matched');
        }
    }

    // Метод, проверяющий выполнение условия попарных соответствий
    function checkCondition() {
        var allMatched = true;
        for (var i = 0; i < signs.length; i++) {
            var sign = signs[i];
            if (!sign.classList.contains('door-riddle__sign_matched')) {
                allMatched = false;
                break;
            }
        }
        if (allMatched) {
            this.unlock();
        }
    }

    // Метод пересечения двух прямоугольников
    function hasIntersection(a, b) {
        if (a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height)
            return b.top < a.top + a.height;
        else
            return false;
    }

    // ==== END Напишите свой код для открытия второй двери здесь ====
}
Door1.prototype = Object.create(DoorBase.prototype);
Door1.prototype.constructor = DoorBase;

/**
 * @class Door2
 * @augments DoorBase
 * @param {Number} number
 * @param {Function} onUnlock
 */
function Door2(number, onUnlock) {
    DoorBase.apply(this, arguments);

    // ==== Напишите свой код для открытия третей двери здесь ====

    var PINCH_SCALE_MIN = 0.9;
    var PINCH_SCALE_MAX = 1.1;
    var TARGET_SCALE = 1;

    var occurredEvents = [];    // Кэш произошедших событий Pointer Event
    var prevDiff = -1;          // Дистанция между точками при предудущем событии
    var startAngle = 0;         // Начальный угол между линией, образованной точками и осью координат

    var picBoxes = [
        this.popup.querySelector('.door-riddle__map-part_0'),
        this.popup.querySelector('.door-riddle__map-part_1'),
        this.popup.querySelector('.door-riddle__map-part_2'),
        this.popup.querySelector('.door-riddle__map-part_3')];

    var i = 0;
    picBoxes.forEach(function(picBox) {
        picBox.info = {
            curScale: 1,
            visibleScale: 0
        };
        picBox.addEventListener('pointerdown', _onButtonPointerDown.bind(this));
        picBox.addEventListener('pointermove', _onButtonPointerMove.bind(this));
        picBox.addEventListener('pointerup', _onButtonPointerUp.bind(this));
        picBox.addEventListener('pointercancel', _onButtonPointerUp.bind(this));
        picBox.addEventListener('pointerleave', _onButtonPointerUp.bind(this));
        i++;
    }.bind(this));

    // Сохрянаем контекст для вызова метода проверки открытия двери
    var checkCondition = _checkCondition.bind(this);

    function _onButtonPointerDown(e) {
        var picBox = e.target;
        picBox.setPointerCapture(e.pointerId);
        occurredEvents.push(e);

        if (occurredEvents.length == 2) {
            var curDiffX = occurredEvents[0].clientX - occurredEvents[1].clientX;
            var curDiffY = occurredEvents[0].clientY - occurredEvents[1].clientY;

            startAngle = Math.atan(curDiffY / curDiffX) * rad2deg;
            picBox.info.beginAngle = picBox.info.curAngle;
        }
    }

    function _onButtonPointerMove(e) {
        var picBox = e.target;

        // Обновляем данные о событии в кэше по его идентификатору
        for (var i = 0; i < occurredEvents.length; i++) {
            if (e.pointerId == occurredEvents[i].pointerId) {
                occurredEvents[i] = e;
                break;
            }
        }

        if (occurredEvents.length == 2) {
            // Расчитываем расстояние между точками
            var curDiffX = occurredEvents[0].clientX - occurredEvents[1].clientX;
            var curDiffY = occurredEvents[0].clientY - occurredEvents[1].clientY;
            var curDiff = Math.sqrt(Math.pow(curDiffX, 2) + Math.pow(curDiffY, 2));

            if (prevDiff > 0) {
                // Получаем текущую ширину бокса с картинкой
                var curWidth = picBox.getBoundingClientRect().width;

                // Расчет относительной велечины трансформации
                var relativeScale = 1;
                var scaleDiff = Math.abs(curDiff - prevDiff);
                if (curDiff > prevDiff) {
                    // для случая когда расстояние между точками увеличилось
                    relativeScale = (curWidth + scaleDiff) / curWidth;
                }
                else if (curDiff < prevDiff) {
                    // для случая когда расстояние между точками уменьшилось
                    relativeScale = (curWidth - scaleDiff) / curWidth;
                }

                // Расчет абсолютной величины трансформации
                picBox.info.curScale = picBox.info.curScale * relativeScale;

                // Пин при заданном масштабе
                picBox.info.visibleScale = picBox.info.curScale;
                if (picBox.info.curScale > PINCH_SCALE_MIN && picBox.info.curScale < PINCH_SCALE_MAX)
                    picBox.info.visibleScale = TARGET_SCALE;

                // Применение трансформации
                requestAnimationFrame(function() {
                    picBox.style.transform = picBox.style.webkitTransform = 'scale(' + picBox.info.visibleScale +', '+ picBox.info.visibleScale +') ';
                });
            }

            // Сохраняем дистанцию между точками для обработки следующего события перемещения
            prevDiff = curDiff;
        }
    }

    function _onButtonPointerUp(e) {
        if (occurredEvents.length == 2) {
            checkCondition();
        }

        removeEvent(e);

        // Если число точек меньше двух, сбрасываем значение предыдущего расстояние между точками
        if (occurredEvents.length < 2) {
            prevDiff = -1;
            startAngle = 0;
        }
    }

    function _checkCondition() {
        var isOpened = true;
        picBoxes.forEach(function(picBox) {
            if (picBox.info.visibleScale !== TARGET_SCALE) {
                isOpened = false;
            }
        });

        if (isOpened) {
            this.unlock();
        }
    }

    function removeEvent(e) {
        for (var i = 0; i < occurredEvents.length; i++) {
            if (occurredEvents[i].pointerId == e.pointerId) {
                occurredEvents.splice(i, 1);
                break;
            }
        }
    }

    // ==== END Напишите свой код для открытия третей двери здесь ====
}
Door2.prototype = Object.create(DoorBase.prototype);
Door2.prototype.constructor = DoorBase;

/**
 * Сундук
 * @class Box
 * @augments DoorBase
 * @param {Number} number
 * @param {Function} onUnlock
 */
function Box(number, onUnlock) {
    DoorBase.apply(this, arguments);

    // ==== Напишите свой код для открытия сундука здесь ====

    // Сохраняем список букв, с информацией о их позиции и о зависимости от др буквы
    var letterCount = 6;
    var letters = [];
    for (var i = 0; i < letterCount; i++) {
        var letter = this.popup.querySelector('.box-riddle__letter_' + i);
        var prevLetter = this.popup.querySelector('.' + letter.dataset.prev);
        letter.info = {
            startPosition: {},
            currentPosition: {},
            prev: prevLetter,
            pressed: false
        }
        letters.push(letter);
    }

    // Сохраняем объект ключа
    var key = this.popup.querySelector('.box-riddle__key');
    key.info = {
            startPosition: {},
            currentPosition: {},
            pressed: false
        }

    // Подписка букв на события указателя
    letters.forEach(function(l) {
        l.addEventListener('pointerdown', _onObjPointerDown.bind(this));
        l.addEventListener('pointermove', _onObjPointerMove.bind(this));
        l.addEventListener('pointerup', _onLetterPointerUp.bind(this));
        l.addEventListener('pointercancel', _onLetterPointerUp.bind(this));
        l.addEventListener('pointerleave', _onLetterPointerUp.bind(this));
    }.bind(this));

    // Подписка ключа на события указателя
    var key = this.popup.querySelector('.box-riddle__key');
    key.addEventListener('pointerdown', _onObjPointerDown.bind(this));
    key.addEventListener('pointermove', _onObjPointerMove.bind(this));
    key.addEventListener('pointerup', _onKeyPointerUp.bind(this));
    key.addEventListener('pointercancel', _onKeyPointerUp.bind(this));
    key.addEventListener('pointerleave', _onKeyPointerUp.bind(this));

    // Обработчик события зажатия буквы
    function _onObjPointerDown(e) {
        var obj = e.target;
        obj.setPointerCapture(e.pointerId);
        obj.info.startPosition.X = e.pageX;
        obj.info.startPosition.Y = e.pageY;
        obj.info.currentPosition.X = e.pageX;
        obj.info.currentPosition.Y = e.pageY;
        obj.info.pressed = true;
    }

    // Обработчик события перемещения буквы
    function _onObjPointerMove(e) {
        var obj = e.target;
        if (!obj.info.pressed) {
            return;
        }

        obj.info.currentPosition.X = e.pageX;
        obj.info.currentPosition.Y = e.pageY;
        moveObj(obj);
    }

    // Обработчик события отжатия буквы
    function _onLetterPointerUp(e) {
        var letter = e.target;
        if (!letter.info.pressed) {
            return;
        }
        letter.info.pressed = false;

        if (letter.info.prev !== null && !letter.info.prev.classList.contains('door-riddle__letter_swiped')) {
            requestAnimationFrame(function() {
                letter.style.transform = 'translate3d(0,0,0)';
                letter.style.webkitTransform = 'translate3d(0,0,0)';
            });
        } else {
            requestAnimationFrame(function() {
                letter.style.opacity = 0;
            });
            letter.classList.add('door-riddle__letter_swiped');
        }
    }

    // Обработчик отжатия указателя от элемента ключ
    function _onKeyPointerUp(e) {
        var key = e.target;
        if (!key.info.pressed) {
            return;
        }
        key.info.pressed = false;

        var keyRect = key.getBoundingClientRect();
        var lockerRect = this.popup.querySelector('.box-riddle__locker').getBoundingClientRect();
        if (hasIntersection(keyRect, lockerRect)) {
            this.unlock();
        }

        requestAnimationFrame(function() {
            key.style.transform = 'translate3d(0,0,0)';
            key.style.webkitTransform = 'translate3d(0,0,0)';
        });
    }

    // Перемещение объекта
    function moveObj(obj) {
        requestAnimationFrame(function() {
            var diffX = obj.info.currentPosition.X - obj.info.startPosition.X;
            var diffY = obj.info.currentPosition.Y - obj.info.startPosition.Y;
            obj.style.transform = 'translate3d('+ diffX +'px, '+ diffY +'px, 0px)';
            obj.style.webkitTransform = 'translate3d('+ diffX +'px, '+ diffY +'px, 0px)';
        });
    }

    // Пересечение прямоугольников
    function hasIntersection(a, b) {
        if (a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height)
            return b.top < a.top + a.height;
        else
            return false;
    }

    // ==== END Напишите свой код для открытия сундука здесь ====

    this.showCongratulations = function() {
        alert('Поздравляю! Игра пройдена!');
    };
}
Box.prototype = Object.create(DoorBase.prototype);
Box.prototype.constructor = DoorBase;

languages: Markdown JavaScript

repo_language: Markdown


text:
<file_sep>module Rancher
  module Api
    class Auditlog
      include Her::Model
      include Helpers::Model

      attributes :resourceId
    end
  end
end
<file_sep>module Rancher
  module Api
    class Stack
      include Her::Model
      include Helpers::Model

      belongs_to :project, foreign_key: :accountId
      has_many :services
    end
  end
end
<file_sep>module Rancher
  module Api
    VERSION = '0.8.0'.freeze
  end
end

repo_language: Ruby

repo_name: energiency/rancher-api


text:
<file_sep>// create random len array with random numbers

var randomInt = () => {
    return Math.floor(Math.random() * 10)
};

var randomIntArray = Array(randomInt()).fill(0).map(randomInt);

//display numbers on html

document.getElementsByClassName("numbers")[0].innerHTML = randomIntArray;

//correct answer

//eliminate duplicate items in the array

uniqueArray = randomIntArray.filter(function(item, pos) {
    return randomIntArray.indexOf(item) == pos;
})

//sort the array ascending order

var ascendingSort = uniqueArray.sort(function(a, b){return a-b})
var correctSort = ascendingSort.reverse();

console.log(correctSort);

//comparison with user's answer and correct answer
var compareArrays = (arr1, arr2) => {
    if (JSON.stringify(arr1) == JSON.stringify(arr2)) {
        console.log("correct")
        window.location.href = "pass.html";
    } else {
        console.log("nope")
        window.location.href = "fail.html";
    }
}

// input is array or string? whats it?
$(".btn").click(function(e){
    e.preventDefault();
   checkUserAnswer();

});

var checkUserAnswer = () => {
    var userInput = document.getElementsByClassName("input")[0].value;

    console.log(userInput);
    var inputArray = [];

    userInput.split(",").forEach(function(x) {
       let inputInteger = parseInt(x)
       inputArray.push(inputInteger);
    });

    console.log(inputArray);

    compareArrays(inputArray, correctSort)
}

// const newUser = new user(10, 10);

<file_sep>
let keywords = ["Ember", "Ruby", "Rails", "Elixir", "React"];

//for bonus make a constructor for keep failing for indivual user

// let user = class {
//     constructor(userEmail, failing){
//         this.userEmail ="";
//         this.failing = 0;
//     }
// }

$("#getStarted").click(function(e){
    //prevend from refreshing the page
    e.preventDefault();

    let userEmail = document.getElementsByName("email")[0].value;

    keywords.forEach(function(x) {
        // convert keywords to lowercase
        x = x.toLowerCase();

        let y = userEmail.indexOf(x)
        let modal = document.querySelector(".hide")
        if (y !== -1 )
           modal.className = "modal show"

    })
});

$(".boolean").click(function(e){
    e.preventDefault();
    let answer = e.target.innerText;
    console.log(answer)
   if (answer = "yes") {
    window.location.href = "challenge.html";
   }

});

repo_language: JavaScript


text:
<repo_name>jsiggy/bdd-solution<file_sep>/src/test/java/training/tdd/mat/shapes/CircleTest.java
package training.tdd.mat.shapes;

import org.junit.Test;

import static junit.framework.Assert.assertEquals;

public class CircleTest {
   @Test
   public void shouldReturnZeroForZeroRadius() {
      Shape shape = new Circle(0);

      double area = shape.area();

      assertEquals(0.0, area, 0.0001);
   }

   @Test(expected = IllegalArgumentException.class)
   public void shouldThrowExceptionForNegativeRadius() {
      new Circle(-1);
   }

   @Test
   public void shouldCalculateAreaForPositiveRadius() {
      Shape shape = new Circle(1);

      double area = shape.area();

      assertEquals(3.14, area, 0.01);
   }
}
<file_sep>/src/test/resources/acceptance/mat/AreaOfShapesAT.story
Meta:

Narrative:
As a user
I want to determine the area of all shapes placed on a board
So that I can impress my instructor

Scenario: empty board has covered area of zero
Given an empty board
When no shapes are added
Then the area of shapes on the board is 0

Scenario: determine area for board with a square
Given an empty board
When a square with a side of length 2 is added
Then the area of shapes on the board is 4

Scenario: determine area for board with a circle
Given an empty board
When a circle with a radius of length 3 is added
Then the area of shapes on the board is 28.27

Scenario: determine area for board with multiple objects
Given an empty board
When a circle with a radius of length 4 is added
And a square with a side of length 5 is added
Then the area of shapes on the board is 75.27

Scenario: determine area for board after removing an object
Given a board with a circle with radius 100 and two squares of length 10 and 5
When the circle is removed
Then the area of shapes on the board is 125

languages: Java Gherkin

repo_name: jsiggy/bdd-solution


text:
<repo_name>Roberto-Sartore/curso-PHP<file_sep>/exercicios/funcao.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			function soma($a, $b){
				$s=$a+$b;
				echo "
A soma de $a e $b é $s
";
			}
			soma(3, 4);
			soma(8, 2);
			$x=9;
			$y=15;
			soma($x, $y);

		?>

<file_sep>/exercicios/switch2.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			$est = $_GET["est"];
			switch($est){
				case 1:
				case 3:
				case 4:
				case 14:
				case 22:
				case 23:
				case 27:
					echo "Você mora na Região Norte!";
					break;
				case 2:
				case 5:
				case 6:
				case 10:
				case 15:
				case 17:
				case 18:
				case 20:
				case 26:
					echo "Você mora na Região Nordeste!";
					break;
				case 9:
				case 12:
				case 13:
				case 7:
					echo "Você mora na Região Centro-Oeste!";
					break;
				case 8:
				case 11:
				case 25:
				case 19:
					echo "Você mora na Região Sudeste!";
					break;
				case 16:
				case 21:
				case 24:
					echo "Você mora na Região Sul!";

			}
		?>

Voltar

<file_sep>/exercicios/01valor.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php

		 	$valor=$_GET["v"];
			$rq=sqrt($valor);
			echo "A Raiz de $valor é igual a $rq";

		?>

<file_sep>/exercicios/array1.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

			<?php
				# chaves personalizadas
				$v = array(3=>5, 1=>9, 0=>8,7=>7);
				unset($v[0]);
				print_r($v);

			?>

<file_sep>/exercicios/funcao2.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			echo " Passagem por valor
";
			function teste($x){
				$x=$x+2;
				echo "O valor de X é $x";
			}

			$a=3;
			teste($a);
			echo "
 O valor de A é $a";
			echo "

";
			echo "Passagem por referencia
";
			function teste1(&$x){
				$x=$x+2;
				echo "O valor de X é $x";
			}

			$a=3;
			teste1($a);
			echo "
O valor de A é $a";

		?>

<file_sep>/exercicios/media.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			$n1= isset($_GET["n1"])?$_GET["n1"]:0;
			$n2= isset($_GET["n2"])?$_GET["n2"]:0;
			$m= ($n1+$n2)/2;

			if($m >= 7){
				echo "A média é $m
";
				echo "O aluno está APROVADO!";
			}
			elseif($m >=5 && $m<7){
				echo "A média é $m
";
				echo "O aluno está em RECUPERAÇÃO!";
			}
			else{
				echo "A média é $m
";
				echo "O aluno está REPROVADO!";
			}

		?>

<file_sep>/exercicios/switch.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			$n=isset($_GET["num"])?$_GET["num"]:0;
			$o=isset($_GET["oper"])?$_GET["oper"]:1;
			switch($o){
				case 1:
					$r=$n*2;
					break;
				case 2:
					$r=($n*$n)*$n;
					break;
				case 3:
					$r=sqrt($n);

			}
		echo "O Resultado da operação solicitada foi $r</apan>";
		?>
		Voltar

<file_sep>/exercicios/tabuada.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			$n = isset($_GET["num"])?$_GET["num"]:1;
			echo "
 Mostrando a tabuada do $n
";
			$c=1;
			do{
				echo "$n X   $c =  ".($n*$c)."
";

				$c++;
			}while($c <=10);
		?>
		Voltar

<file_sep>/exercicios/aula4.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

	<?php
	$n=41;
	$no="Roberto";
	echo "$no tem $n anos. "
	?>

<file_sep>/exercicios/aula5.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Operadores aritmeticos</title>

	<?php
	$n1= $_GET["a"];
	$n2=$_GET["b"];
	echo "
 Valores recebidos: $n1 e $n2
";
	echo"A soma vale ".($n1+$n2);
	echo"
 A subtração vale ".($n1+$n2);
	echo"
 A multiplicação vale ".($n1*$n2);
	echo"
 A divisão vale ".($n1/$n2);
	echo"
 O modulo vale ".($n1%$n2);
	echo"
 A media é ".($n1+$n2)/2;
	?>

<file_sep>/exercicios/funcao3.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			function soma(){
				$p= func_get_args();
				$tot= func_num_args();
				$s= 0;
				for($i=0; $i<$tot; $i++){
					$s= $s+$p[$i];
				}
				return $s;
			}
			$r= soma(3, 5,2, 8,6 ,9);#pode ser colocado quantos elementos quiser.
			echo "A soma dos valores é $r";

		?>

<file_sep>/exercicios/aula7.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php

		$n1=$_GET["a"];
		$n2=$_GET["b"];
		$tipo=$_GET["op"];
		echo "Os valores passados foram $n1 e $n2
";
		$r=($tipo == "s")?$n1+$n2:$n1*$n2;
		echo "O resultado será $r
";
		$c=3;
		$d="3";
		$resp=$c===$d?"Sim":"Não";
		echo "As variaveis C e D são identicas? $resp
";
		$nota1=$_GET["n1"];
		$nota2=$_GET["n2"];
		$m=($nota1+$nota2)/2;
		echo "A média entre $nota1 e $nota2 é $m
 ";
		$sit=$m>=6?"Aprovado":"Reprovado";
		echo "A situação do aluno é $sit";

		?>

<file_sep>/exercicios/primo.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			$n=$_GET["num"];
			$div=0;
			for($c=1; $c<=$n; $c++){
				if($n%$c == 0){

					$div++;
				}

			}
			if($div==2){
					echo " É primo!";
				}
				else{
					echo "Não é primo";

				}

		?>
		Voltar

<file_sep>/exercicios/aula6.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

	<?php
		/* Esse exercicio pretende demonstrar o uso
		de operadores de incremento e decremento. */
		$preco=$_GET["p"];# Essa linha vai pegar o preço na url.
		echo"O preço do produto é R$ ". number_format($preco, 2, ",", ".");
		$preco += ($preco*10)/100;
		echo"
 O novo preço com 10% de aumento é R$ ".number_format($preco, 2, ",", ".");
		$atual=$_GET["aa"];//Essa linha vai pegar o ano na url.
		echo"
 O ano atual é $atual e o ano anterior é ".--$atual;

	?>

<file_sep>/exercicios/fatorial.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			$v = isset($_GET["val"])?$_GET["val"]:1;
			echo "
 Calculando o Fatorial de $v
";
			$c= $v;
			$fat = 1;
			do{
				$fat = $fat * $c;
				$c--;
			}while($c >= 1);
			echo "
 $v ! = $fat
";

		?>
		Voltar

<file_sep>/exercicios/for.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			for($i=1; $i <= 10; $i++){
				echo "$i ";
			}
			echo "
";
			for($i=10; $i >= 1; $i--){
				echo " $i ";
			}
			echo "
";
			for($i=0; $i <= 50; $i+=5){
				echo " $i ";
			}
			echo "
";
			for($i=30; $i >=0; $i-=2){
				echo "$i ";
			}
		?>

<file_sep>/exercicios/array2.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

			<?php
				# chaves associativas

				$v = array("nome"=>"Ana", "idade"=>23, "peso"=>65.5);

				foreach($v as $k =>$c){
					echo"O campo $k possui o conteudo $c
";
				}

			?>

<file_sep>/exercicios/tabuadafor2.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

		<?php
			$n=isset($_GET["num"])?$_GET["num"]:1;
			for($c=1; $c <= 10; $c++){
				$r=$n*$c;
				echo "$n X  $c =  $r
";
			}
		?>
		Voltar

<file_sep>/exercicios/matriz.php
<!doctype html>

<meta charset="utf-8">
	<link rel="stylesheet" href="_css/estilo.css"/>
<title>Documento sem título</title>

			<?php

				$m = array(array(6,4), array(4,9), array(3,2));
				$m[0] [1]=$m[2] [0];
				echo "O vetor tem". count($m)." elementos
";
				print_r($m);

			?>

<file_sep>/README.md
# curso-PHP
 exercicios curso php do curso em video

branch_name: refs/heads/main

languages: Markdown PHP

repo_name: Roberto-Sartore/curso-PHP


text:
<repo_name>zhuoyuzhu/Data-Structure-and-Algorithm-Notes<file_sep>/Data-Structure/Array-and-List/LeeCode/Q26-Remove-Duplicates-from-Sorted-Array/removeDuplicates.java

public class Solution {
    public int removeDuplicates(int[] nums) {

        int count = 0;

        for(int i=1;i<nums.length;i++){
            if(nums[i]==nums[i-1]){
                count++;
            }else{
                nums[i-count] = nums[i]; // If the two numbers are different, they are just shifted by themselves
            }
        }
        return nums.length - count;
    }
}
<file_sep>/README.md
# Data-Structure-and-Algorithm-Notes
<file_sep>/Data-Structure/Array-and-List/README.md
##Array and List Implementation
<file_sep>/Data-Structure/Array-and-List/LeeCode/Q169-Majority-Element/Sorting.java
/** Runtime: O(n log n) — Sorting: As we know more than half of the array are elements of the same value,
we can sort the array and all majority elements will be grouped into one contiguous chunk.
Therefore, the middle (n/2th) element must also be the majority element. */

import java.util.*;

public class Solution {
    public int majorityElement(int[] nums) {

        Arrays.sort(nums);
        int length = nums.length/2;
        int count = 1;
        int majority = 0;

        if(length==0){
            majority = nums[0];
        }else{
            for(int i=1;i<nums.length;i++){
              if(nums[i]==nums[i-1]){
                  count++;
                  if(count>length){
                      majority = nums[i];
                  }
              }else{
                  count = 1;
              }
            }
        }
        return majority;
    }
}
<file_sep>/Data-Structure/README.md
# Data Structure Notes
---

##Content

<file_sep>/Data-Structure/Array-and-List/Tutorial.md
##Contiguous vs Linked Data Structure

**1. Contiguously-allocated structures:**
They are composed of single slab of memory. Ex: Array, Matrix, Heap and Hash Tables

**2. Link structures:**
They are composed of distinct chunks of memory connected by pointers or reference. Ex: List, Tree and Graph adjacency lists

---

## Array vs Linked List

**1. Memory structure and allocation:**

**Array** is contiguously-allocated structure and it should be allocated at the compiling time in stack when the programmer is writing the program.

**Linked list** is link data structure which is composed of many distinct chunks of memory connected by pointers or reference and it can be allocated at running time (after executing the program). Pointer represents the address location of node(object) in memory.

**2. Access: Random/Sequential**

**Array** O(1), Because the index of each element maps directly to a particular memory address, we can randomly access the data given the index.

**Linked list** O(N), Linked List isn't efficient for searching and retrieving data because whatever item we want to access, we need to traverse through the entire linked list every time from the beginning.

**3. Insertion and Deletion:**

**Array** O(N), We have to delete/insert the element from given Location and then shift all successive elements up by 1 position

**Linked list** O(1), Linked List is simpler to insert or delete one item than contiguous Array or ArrayList(**Given we know the location of pointer**). Especially, with huge amount of data, moving pointers is much easier and faster than moving the items themselves. Because we need to shift some items within array to create new space for new coming data and it isn't memory and time efficient.

**4. Memory Requirement:**

**Array** Memory Efficient, Arrays consist purely of data, so no space is wasted with storing link or other formating information since index within array is implicit and virtual. However, we cannot adjust the size of array in the middle of a program's execution so overflow can happen for array.

**Linked list** Linked structures require extra space for storing pointer fields and data fields. But overflow in link structre will never happen unless the memory is full.

**Final Point:** Array allows better memory locality and cache performance than random pointer jumping.

---

## Array vs Linked List

They are both contiguously-allocated memory structure. However, first of all, **Array** is a fixed length data structure while **Arraylist** is a variable length Collection class. You can't change the length of array once you create it. They have similar performance in terms of getting element if you  know the index. But since **ArryList** is internlly backed by **Array** in Java, any resize operation in **ArrayList** will slow down performance as it involves creating new array and copying content from old array to new array.

In addition, another difference is that you can not use Generics along with Array, as array instance knows about what kind of type it can hold and throws an exception. ArrayList allows you to use Generics to ensure type-safety and ArrayList can only store object instead of primitive data.

---

## ArrayList vs Linked List

They are two different implementations of the List interface

For **LinkedList<E>**
1. get(index) is O(N)
2. add(element) is O(1)
3. add(index, element) is O(N)
4. remove(index) is O(N)
5. Iterator.remove() is O(1) <--- main benefit of LinkedList<E>
6. Iterator.add(element) is O(1) <--- main benefit of LinkedList<E>

For **ArrayList<E>**
1. get(index) is O(N) <--- main benefit of ArrayList<E>
2. add(element) is O(1) mortized, but O(N) worst-case since the array must be resizeed and copied
3. add(index, element) is O(N-index) mortized, but O(N) worst-case since the array must be resizeed and copied
4. remove(index) is O(N-index) remove last O(1)
5. Iterator.remove() is O(N-index)
6. Iterator.add(element) is O(N-index)

**1. Memory Usage:**
If you have large lists, each element of a LinkedList has more overhead since pointers to the next and previous elements are stored. ArrayLists don't have this overhead.

**2. Access:Random/Sequential**
See above (Array vs LinkedList)

**3. Insertion and Deletion**
LinkedList<E> allows for O(1) insertions or removals using iterators

**It's highly recommended to use ArrayList instead of LinkedList in terms of performance in a Big-O notation.**

---

##Linked List

**List Properties:**

**1.** Each node contains one or more data fields that we can store.

**2.** Each node contains a pointer to one or more other nodes, which means much of its space used in link structure devoted to be pointers not data.

**3.** One of the pointers has to be the head of the structure so we know where to access.

---

**1. Singly Linked List**

```
x = 1 # 整数
x = 4.483958 # 浮点数
x = 'hello, world' # 字符串，单引号可以用双引号替换
x = [1, 2, 3] # 数组 (List)
x = {'a': 1, 'b', 2} # 哈希表
```
<file_sep>/Data-Structure/Array-and-List/LeeCode/Q206-Reverse-Linked-List/README.md
Reverse a singly linked list
----------------------------

**1. Reverse a singly Linked List Iteratively:**
Time Complexity: O(n)
Space Complexity: O(1)

1) Initially take three pointers: PrevNode, CurrNode, NextNode.
2) Let CurrNode point to HeaderNode of the list. And let PrevNode and NextNode points to null.
3) Now iterate through the linked list until CurrNode is null.
4) In the loop, we need to change NextNode to PrevNode, PrevNode to CurrNode and CurrNode to NextNode.

With this approach, we get O(n) time complexity as we need visit each element in the list once, and O(1) memory complexity as we are storing one extra "next" variable.

**2. Reverse a singly Linked List Recursively:**
1) Divide the list in two parts – first node and rest of the linked list.
2) Call reverse for the rest of the linked list.
3) Link rest to first.
4) Fix head pointer.
Time Complexity: O(n)
Space Complexity: O(n) for recursive stack.

The advantage that we have with recursion is the fact that we can go to the very end of the linked list and work backwards to reverse the list starting from the every end.

The reason we can do this in recursion is because of the fact that the stack frames for each function call are saved until we get to the very end of the list, where each stack frame essentially represents a node in the linked list.

This approach would give us the linear time and memory complexity which is O(n) in both the cases. The memory is O(n) because of the  recursive call stack.

Here, lets go step by step.

 How do we reveres a list with no items: we just return null (if(current == null) return current;)
 How do we reverse a list with one item: we just return the one item (it is already reversed)(if(current.next == null) return current;)
 How do we reverse a list with two items: Lets say our initial list 10 -> 20 -> null
 We need to reach to the end (recursive) (Node reversed = reverseRecursive(current.next);)
 Now in the stack, we have current as 10, current.next is 20
 Here we need to set 20.next = 10 correct? so current.next.next = current;
 Also, we need to remove the link between 10 and 20, that's why current.next = null;
 Last, but not least, we need to return the 'reversed', because that is our new head.

<file_sep>/Data-Structure/Array-and-List/LeeCode/Q169-Majority-Element/README.md
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

**1. HashTable -- Runtime: O(n), Space: O(n):** Maintain a hash table of the counts of each element, then find the most common one.

**2. Sorting -- Runtime: O(n log n):** As we know more than half of the array are elements of the same value, we can sort the array and all majority elements will be grouped into one contiguous chunk. Therefore, the middle (n/2th) element must also be the majority element.

**3. Boyer-Moore voting algorithm -- Runtime: O(n):** —  We maintain a current candidate and a counter initialized to 0. As we iterate the array, we look at the current element x:
If the counter is 0, we set the current candidate to x and the counter to 1.
If the counter is not 0, we increment or decrement the counter based on whether x is the current candidate.
After one pass, the current candidate is the majority element. Runtime complexity = O(n).

languages: Java Markdown


text:
<file_sep>#!/usr/bin/perl -w

# $Id: sqlpp,v 1.13 2006/05/16 11:03:54 dk Exp $

use strict;
use vars qw($input $output @inc @context $context $sigdie %defines %macros $debug $VERSION);
use vars qw(%global); # for perldef

$VERSION = '0.05';

# special predefined macros
%defines = (
	__LINE__ => {
		code => sub { $context->{line} },
	},
	__FILE__ => {
		code => sub { $context->{file} },
	},
	__VERSION__ => {
		code => sub { $VERSION },
	},
	'#' => {
		num	=> 1,
		name	=> '#',
		code	=> sub {
			my $x = $_[0];
			$x =~ s/([\\'])/\\$1/gs;
			"'$x'";
		},
	},
);

use constant MACRO_OFF     => 0; # none
use constant MACRO_SIMPLE  => 1; # #defines with no-parameters only
use constant MACRO_COMPLEX => 2; # #defines with parameters only
use constant MACRO_ALL     => 3; # all #defines

# run
$debug = 0;

$context = new_context( file => 'command line', macro => MACRO_OFF );
parse_argv();

$context = new_context();
parse_input();

# used for serving 'defined' call from #if, which is basically perl code
sub is_defined { exists ($defines{$_[0]}) ? 1 : 0 }

$SIG{__DIE__} = sub {
	# avoid multiple wrappings by perl's "use" - careful when recovering from an eval!
	die @_ if $sigdie++;

	die "error in `$context->{file}', line #$context->{line}: ", @_, "\n";
};
parse_file(1);
exit;

# a context defines state of parser in a file
sub new_context
{
	{
		line       => 0,
		buf        => '',
		in_comment => 0,
		ifdef      => [{state => 1,passive=>[]}],
		in_sql     => 0,
		macro      => MACRO_ALL,
		strip      => 1,
		@_
	}
}

# does buffered input
sub getline
{
	my $undef_if_eof = $_[0];
	if ( length $context->{buf}) {
		my $ret = $context->{buf};
		$context->{buf} = '';
		return $ret;
	}
	my $ret;
	unless ( defined ($ret = <$input>)) {
		die "Unexpected end of input\n" unless $undef_if_eof;
	} else {
		$context->{line}++;
	}
	$ret;
}

# skips input until the EOL
sub eatline { $context->{buf} = '' }

# returns next token from input stream
sub gettok
{
	while ( 1) {
		unless ( length $context->{buf}) {
			unless ( defined ($context->{buf} = <$input>)) {
				die "Unexpected end of input\n";
			}
			chomp $context->{buf};
			$context->{line}++;
		}

		$context->{buf} =~ s/^\s+//;

		return $1
			if $context-> {buf} =~ s/^(\w+|\S)//;
	}
}

# returns ID from input stream
sub getid
{
	my $tok = gettok;
	die "Identificator expected\n" unless $tok =~ /^\w+$/;
	$tok;
}

# Line handle is a state of the parser as it progresses through input .
# The idea is to avoid accumultaion of input until the end of input, and
# spew processed data as soon as possible. The calling routing thus is
# begin_line / while( not parse_line) / print end_line, with different
# variations.
#
# Currently, parse_line returns 0 ( a signal to call end_line ) when
# bracket balance is achieved - but there's a bug with macro
# call MACRO\n() where MACRO and () are on different lines.

sub new_line_handle { {} }

sub begin_line
{
	my $k = $_[0] || new_line_handle;
	$k-> {var}	= '';		 # text to parse
	$k-> {ids}	= [];		 # stack of IDs met, f.ex. if var="A(b,C(d,", then ids=(A,C)
	$k-> {last_id}	= '';		 # a candidate to ids
	$k-> {last_pos}	= 0;		 # stores pos(var) between calls
	$k-> {storage}	= [ 'copy', 0 ]; # accululates parsed info, to be run throung substitute_parameters later
	$k-> {run_stack}= [];		 # stack of macro calls
	$k-> {run}	= $k-> {storage};# current macro call context
	$k;
}

sub parse_line
{
	my $k = $_[0];
	$k-> {last_pos} = pos( $k-> {var}) || 0;
	$k-> {var} .= $_[1];
	my $full   = $context-> {macro} & MACRO_COMPLEX;
	my $simple = $context-> {macro} & MACRO_SIMPLE;
	pos( $k-> {var}) = $k-> {last_pos};
	{
		# do comments
		$context->{multiline_comment} and $k-> {var} =~ m/\G.*?(\*\/)?/gcs and do {
			$context-> {multiline_comment} = 0 if $1;
			redo;
		};
		( $k-> {var} =~ m/\G--/ or (
			not $k-> {macro} and $k-> {var} =~ m/\G#/
		)) and do {
			if ( $context->{strip}) {
				my $savepos = pos( $k-> {var});
				$k-> {var} =~ s/\G.*$//g;
				pos( $k-> {var}) = $savepos;
			} elsif ( $k-> {macro}) {
				$k-> {var} =~ m/\G--/gc;
			} else {
				$k-> {var} =~ m/\G(--|#)/gc;
			}
			redo;
		};
		$k-> {var} =~ m/\G\/\*/gcs and do {
			$context-> {multiline_comment} = 1;
			redo;
		};
		$k-> {var} =~ m/\G-+/gc and redo;

		# do identifiers
		$k-> {var} =~ m/\G(\w+)/gcs and do {
			if ( $k->{parameters} and exists $k->{parameters}->{$1}) {
				$k-> {last_id} = '';
				push @{$k->{run}},
					pos( $k->{var}) - length($1),
					'parameter', $k->{parameters}->{$1},
					'copy', pos( $k->{var});
			} elsif ( $simple and exists $defines{$1}) {
				my ( $l1, $d, $p) = ( length( $1), $defines{$1}, pos($k->{var}));
				$k-> {last_id} = '';
				push @{$k->{run}},
					$p - $l1,
					'define', $defines{$1},
					'copy', $p;
			} else {
				$k-> {last_id} = $1;
				$k-> {last_id_pos_start} = pos($k-> {var}) - length($1);
			}
			print "- id $k->{last_id}\n" if $debug;
			redo;
		};

		# do opening bracket
		$full and $k-> {var} =~ m/\G\(\s*/gcs and do {
			push @{$k-> {ids}}, [ $k-> {last_id}, $context->{line}];
			if ( length $k->{last_id} and $macros{$k->{last_id}}) {
				push @{$k->{run_stack}}, $k->{run};
				push @{$k->{run}},
					$k-> {last_id_pos_start},
					'macro', $macros{$k->{last_id}},
					[
						'copy', pos($k->{var}),
					];
				$k->{run} = $k->{run}->[-1];
			}
			$k-> {last_id} = '';
			print "- open\n" if $debug;
			redo;
		};

		# nulling ID after right after comments and IDs are processed is basically
		# a grammar rule that states that in a macro call nothing except a comment
		# and whitespace can be present between a macro ID and an opening bracket
		$k-> {var} =~ m/\G\s+/gcs and redo;
		$k-> {last_id} = '';

		# do closing bracket
		$full and $k-> {var} =~ m/\G(\s*\))/gcs and do {
			die "Brackets mismatch at character ", pos($k-> {var})-$k-> {last_pos}, "\n"
				unless @{$k-> {ids}};
			my $id = (pop @{$k->{ids}})->[0];
			print "- close [$id]\n" if $debug;

			if ( length $id and $macros{$id}) {
				push @{$k->{run}}, pos($k->{var}) - length($1);
				$k->{run} = pop @{$k->{run_stack}};
				push @{$k->{run}}, 'copy', pos($k->{var});
			}
			redo;
		};

		# do next param
		$full and $k-> {var} =~ m/\G(\s*,\s*)/gcs and do {
			redo unless @{$k->{ids}};

			if ( length($k->{ids}->[-1]->[0]) and
				$macros{$k->{ids}->[-1]->[0]} and @{$k->{run_stack}}) {
				push @{$k->{run}},
					pos($k-> {var}) - length($1),
					'next',
					'copy', pos($k-> {var})
			}
			redo;
		};

		# special # and ## operators
		$k->{macro} and $k->{var} =~ /\G\#(?:(\#\s*)|(\s*)(\w+)|(.*))/gcs and do {
			if ( defined $1) {
				# concatenation
				my $minus = 1 + length($1);
				$minus++ while
					$minus < pos($k->{var}) and
					substr( $k->{var}, pos($k->{var}) - $minus - 1, 1) eq ' ';
				push @{$k->{run}},
					pos($k->{var}) - $minus,
					'copy', pos($k->{var});
			} elsif ( defined $3 and exists $k->{parameters}->{$3}) {
				# stringification
				push @{$k->{run}},
					pos($k->{var}) - 1 - length($2) - length($3),
					'macro', $defines{'#'},
						[ 'parameter', $k->{parameters}->{$3} ],
					'copy', pos($k->{var});
			} else {
				die "'#' is not followed by a macro parameter (",
					(( defined $3) ? $3 : $4),
					")\n";
			}
			redo;
		};

		# we do ''-only strings
		$full and $k-> {var} =~ m/\G'[^']*'/gcs and redo;

		# everything else
		if ( $full) {
			$k-> {var} =~ m/\G[^\w\(\)\'\-\,\#]+/gcs and redo;
		} else {
			$k-> {var} =~ m/\G[^\w\-\#]+/gcs and redo;
		}
		!$full and $k-> {var} =~ m/\G[\(\)\']+/gcs and redo;

		print "? stop at ", pos($k-> {var}), "\n" if $debug;
		print +('.' x (pos($k-> {var})-1)), "v\n$k->{var}\n" if $debug;
	}

	return scalar(@{$k-> {ids}}) ? 0 : 1;
}

sub end_parse_line
{
	my $k = $_[0];
	die "Brackets don't match at character ", pos($k->{var}) - $k-> {last_pos}, ", line $k->{ids}->[-1]->[1]\n"
		if @{$k-> {ids}};
	push @{$k->{run}}, length($k->{var});
	delete @$k{qw(run run_stack last_id last_pos last_id_pos_start ids)};
}

# input:
#     k - text reference object
#     v - set of commands, where 'copy' referes to text chunks in k
#     p - set of actual parameters to be substututed
# output:
#     text with parameters substituted
sub substitute_parameters
{
	my ( $k, $v, $parameters) = @_;

	my @output = ('');

	for ( my $i = 0; $i < @$v; ) {
		my $cmd = $v->[$i++];
		if ( $cmd eq 'copy') {
			$output[-1] .= substr( $k->{var}, $v->[$i], $v->[$i+1] - $v->[$i]);
			$i += 2;
		} elsif ( $cmd eq 'parameter') {
			$output[-1] .= $parameters->[ $v->[$i++] ];
		} elsif ( $cmd eq 'next') {
			push @output, '';
		} elsif ( $cmd eq 'macro') {
			$output[-1] .= execute_macro(
				$v->[$i],
				substitute_parameters( $k, $v->[$i+1], $parameters)
			);
			$i += 2;
		} elsif ( $cmd eq 'define') {
			$output[-1] .= execute_macro( $v->[$i++]);
		} else {
			die "Internal error: unknown directive `$cmd' (i=$i, stack=@$v)\n";
		}
	}

	# XXX special case - zero parameters
	return if 1 == @output and $output[0] eq '';

	return @output;
}

sub execute_macro
{
	my ( $handle, @params) = @_;

	die sprintf "Macro `%s' requires %d argument%s, %d %s passed\n",
		$handle->{name},
		$handle->{num},  ( $handle->{num} == 1) ? '' : 's',
		scalar(@params), (scalar(@params) == 1) ? 'was' : 'were'
			unless $handle->{ellipsis} or
				!defined($handle->{num}) or
				$handle->{num} == scalar(@params);

	return join($", $handle->{code}->(@params)) if $handle-> {code};

	return join('', substitute_parameters(
		$handle,
		$handle->{storage},
		\@params
	));
}

sub end_line
{
	my $k = $_[0];
	end_parse_line($k);
	return join('', substitute_parameters( $k, $k->{storage}, [] ));
}

# begin_macro/end_macro pairs are same as begin_line/end_line, but for macro declaration purposes
sub begin_macro
{
	my ( $name, $parametric, @params ) = @_;

	my %p;
	my $pno = 0;
	for my $p ( @params) {
		die "Error in macros `$name' definition: argument `$p' is used twice\n"
			if $p{$p};
		die "Error in macros `$name' definition: argument name `$p' is not a valid identifier\n"
			if $p =~ /\'\(\)\#/;
		$p{$p} = $pno++;
	}

	return begin_line {
		parametric => $parametric,
		parameters => \%p,
		name       => $name,
		macro      => 1,
		line       => $context->{line},
		file       => $context->{file},
	};
}

sub end_macro
{
	my $handle = $_[0];
	end_parse_line( $handle);

	if ( $handle->{parametric}) {
		$macros{ $handle->{name} } = $handle;
		$handle->{num} = scalar keys %{$handle->{parameters}};
	} else {
		$defines{ $handle->{name} } = $handle;
		$handle->{num} = 0;
	}
	delete @$handle{qw(parametric macro)};
}

sub parse_pragma
{
	my ( $pragma, $param) = @_;
	if ( $pragma eq 'macro') {
		if ( $param eq 'simple') {
			$context->{macro} = MACRO_SIMPLE;
		} elsif ( $param eq 'all') {
			$context->{macro} = MACRO_ALL;
		} elsif ( $param eq 'off') {
			$context->{macro} = MACRO_OFF;
		} else {
			die "Invalid '#pragma macro($param)': should be 'all', 'simple', or 'off'\n";
		}
	} elsif ( $pragma eq 'comment') {
		if ( $param eq 'strip') {
			$context->{strip} = 1;
		} elsif ( $param eq 'leave') {
			$context->{strip} = 0;
		} else {
			die "Invalid '#pragma comments($param)': should be 'strip' or 'leave'\n";
		}
	} elsif ( $pragma eq 'lang') {
		if ( $param eq 'sql') {
			parse_pragma(qw(macro all));
			parse_pragma(qw(comment strip));
		} elsif ( $param eq 'leave') {
			parse_pragma(qw(macro simple));
			parse_pragma(qw(comment leave));
		} else {
			die "Invalid '#pragma lang($param)': should be 'sql' or 'perl'\n";
		}
	} else {
		die "Unknown #pragma $pragma\n";
	}
}

# if a line begins with #, then parse_comment checks it first
sub parse_comment
{
	my $eatline = 1;
	my $what;

	if ( $context->{buf} !~ s/^(\w+)\s+//) {
		# a comment
		eatline;
		return;
	} else {
		$what = $1;
	}

	# parse if/else/elif/endif in the passive code less heavily
	unless ( $context->{ifdef}->[-1]->{state}) {
		if ( $what =~ /^if(n?def)?$/) {
			push @{$context->{ifdef}->[-1]->{passive}}, 1; # flipsleft
		} elsif ( $what eq 'else') {
			goto NORMAL unless @{$context->{ifdef}->[-1]->{passive}};
			die "Too many #else\n" unless $context->{ifdef}->[-1]->{passive}->[-1]--;
		} elsif ( $what eq 'elif') {
			goto NORMAL unless @{$context->{ifdef}->[-1]->{passive}};
		} elsif ( $what eq 'endif') {
			goto NORMAL unless @{$context->{ifdef}->[-1]->{passive}};
			pop @{$context->{ifdef}->[-1]->{passive}};
		}
		eatline;
		return;
	}

	# normal '#' pragmas
NORMAL:
	if ( $what eq 'define') {
		my $heredoc = $context->{buf} =~ s/^<<//;
		my $def = getid();

		my @params;
		my $parametric = 0;
 		if ( $context->{buf} =~ s/^\(([^\)]*)\)//) {
			@params = map {
				s/^\s*//;
				s/\s*$//;
				die "`$1' may not appear in macro parameter list\n"
					if m/(\W)/;
				$_
			} split ',', $1;
			$parametric = 1;
		}
		$context->{buf} =~ s/^\s*//;

		$eatline = 0;
		if ( $heredoc or length $context->{buf}) {
			my $v = begin_macro( $def, $parametric, @params);

			my $do_ml = 1;
			while ( $do_ml) {
				my $l = getline;
				chomp $l;
				if ( $heredoc) {
					last if $l eq $def;
				} else {
					$do_ml = $l =~ s/\\\s*$//;
				}
				parse_line( $v, $l . ( $do_ml ? "\n" : ''));
			}

			# check if macro already exists by comparing with the macro body
			my $ref = $parametric ? $macros{$def} : $defines{$def};
			if ( defined $ref) {
				my $fail;
				if ( !defined $ref->{var}) {
					$fail = 1;
				} else {
					$fail = (
						join(':', keys %{$ref->{parameters}})
						ne
						join(':', @params)
					) || (
						$ref->{var}
						ne
						$v->{var}
					);
				}
				warn "`$def' redefined, previous declaration in $ref->{file}:$ref->{line}\n"
					if $fail;
			}

			# register the macro
			end_macro( $v);
		} elsif ( $parametric) { # special macro
			warn "`$def' redefined, previous declaration in $macros{$def}->{file}:$macros{$def}->{line}\n"
				if exists $macros{$def} and defined $macros{$def}->{var};
			$macros{$def} = {
				name    => $def,
				num     => scalar(@params),
				storage => [],
				line    => $context->{line},
				file    => $context->{file},
			}
		} else { # special define
			warn "`$def' redefined, previous declaration in $defines{$def}->{file}:$defines{$def}->{line}\n"
				if exists $defines{$def} and defined $defines{$def}->{var};
			$defines{$def} = {
				name    => $def,
				num     => 0,
				storage => [],
				line    => $context->{line},
				file    => $context->{file},
			}
		}
	} elsif ( $what eq 'undef') {
		my $def = getid();
		delete $defines{$def};
		delete $macros{$def};
	} elsif ( $what =~ /if(n?)def/) {
		my $def = getid();
		my $notdef = length($1) ? 1 : 0;
		push @{$context->{ifdef}}, {
			state => exists($defines{$def}) ? !$notdef : $notdef,
			flipsleft => 1,
			passive => [],
			do_else => exists($defines{$def}) ? $notdef : !$notdef,
		};
	} elsif ( $what eq 'if') {
		my $do_ml = 1;
		my $v = begin_line;
		while ( $do_ml) {
			my $l = getline;
			chomp $l;
			$do_ml = $l =~ s/\\\s*$//;
			$l =~ s/defined\s*\(([^\)\s]+)\s*\)\s*/is_defined($1)/ge; # XXX a hack
			parse_line( $v, $l . ( $do_ml ? "\n" : ''));
		}
		my $if = end_line($v);
		my $ret = eval $if;
		die $@ if $@;
		push @{$context->{ifdef}}, {
			state => $ret ? 1 : 0,
			flipsleft => 1,
			passive => [],
			do_else => ( $ret ? 0 : 1),
		};
		$eatline = 0;
	} elsif ( $what eq 'elif') {
		die "Runaway #elif\n" if
			0 == $#{$context->{ifdef}} or
			@{$context->{ifdef}->[-1]->{passive}};
		my $do_ml = 1;
		my $v = begin_line;
		while ( $do_ml) {
			my $l = getline;
			chomp $l;
			$do_ml = $l =~ s/\\\s*$//;
			$l =~ s/defined\s*\(([^\)\s]+)\s*\)\s*/is_defined($1)/ge; # XXX a hack
			parse_line( $v, $l . ( $do_ml ? "\n" : ''));
		}
		my $if = end_line($v);
		if ( $context->{ifdef}->[-1]->{do_else}) {
			my $ret = eval $if;
			die $@ if $@;
			$context->{ifdef}->[-1]->{state} = ($ret ? 1 : 0);
			$context->{ifdef}->[-1]->{do_else} = 0 if $ret;
		} else {
			$context->{ifdef}->[-1]->{state} = 0;
		}
		$eatline = 0;
	} elsif ( $what eq 'else') {
		die "Runaway #else\n" if
			0 == $#{$context->{ifdef}} or
			@{$context->{ifdef}->[-1]->{passive}};
		die "Too many #else\n" unless $context->{ifdef}->[-1]->{flipsleft}--;
		$context->{ifdef}->[-1]->{state} = $context->{ifdef}->[-1]->{state} ?
			0 :
			$context->{ifdef}->[-1]->{do_else};
	} elsif ( $what eq 'endif') {
		die "Runaway #endif\n" if
			0 == $#{$context->{ifdef}} or
			@{$context->{ifdef}->[-1]->{passive}};
		pop @{$context->{ifdef}};
	} elsif ( $what eq 'error') {
		die getline;
	} elsif ( $what eq 'include') {
		my $bracket = gettok();
		die "format #include <file> or #include \"file\"\n"
			unless $bracket =~ /^["<]$/;
		my $file;
		my @local_inc;
		if ( $bracket eq '<') {
			@local_inc = ( @inc, '.');
			die "format #include <file>\n" unless $context->{buf} =~ s/([^>]*)>//;
			$file = $1;
		} else {
			@local_inc = ( '.');
			die "format #include \"file\"\n" unless $context->{buf} =~ s/([^"]*)"//;
			$file = $1;
		}
		my $found;
		for my $inc ( @local_inc) {
			next unless -f "$inc/$file";
			$found = "$inc/$file";
			last;
		}
		die "Cannot find file `$file' in path [@local_inc]\n" unless $found;
		$file = $found;

		local $input;
		open $input, "< $file" or die "Cannot open $file\n";
		push @context, $context;
		$context = new_context( file => $file);
		parse_file(1);
		$context = pop @context;
		close $input;
	} elsif ( $what eq 'pragma') {
		my $pragma = gettok();
		my $param = length($context->{buf}) ? getline() : '';
		$param =~ s/^[\s\(]*(\w+)[\s\)\#]*$/$1/m;

		parse_pragma( $pragma, $param);
	} elsif ( $what eq 'perldef') {
		$eatline = 0;
		my $heredoc = $context->{buf} =~ s/^<<//;
		my $def = getid();

		my ( $ellipsis, @params);
		my $parametric = 0;
 		if ( $context->{buf} =~ s/^\(([^\)]*)\)//) {
			if ( $1 eq '...') {
				$ellipsis = 1;
			} else {
				@params = map {
					s/^\s*//;
					s/\s*$//;
					die "`$_' is not a valid Perl scalar declaration (must begin with \$)\n"
						unless m/^\$\w+$/;
					$_
				} split ',', $1;
			}
			$parametric = 1;
		}
		$context->{buf} =~ s/^\s*//;
		die "Empty #perldef declaration `$def'\n"
			unless $heredoc or length $context->{buf};

		my $perlcode = "sub {\n";
		$perlcode .= "my (" . join( ', ', @params) . ") = \@_;\n"
			if !$ellipsis and @params;

		my $do_ml = 1;
		while ( $do_ml) {
			my $l = getline;
			chomp $l;
			if ( $heredoc) {
				last if $l eq $def;
			} else {
				$do_ml = $l =~ s/\\\s*$//;
			}
			$perlcode .= $l . ( $do_ml ? "\n" : '');
		}
		$perlcode .= "\n}";
		my $p = eval $perlcode;
		unless ( defined $p) {
			$@ =~ s/at \(eval \d+\) line (\d+), //gs;
			$@ =~ s/<\$ih>\s+//gs;
			die "$@\n";
		}
		( $parametric ? $macros{$def} : $defines{$def} ) = {
			name		=> $def,
			num		=> scalar(@params),
			storage		=> [],
			ellipsis	=> $ellipsis,
			code		=> $p,
		};
	} elsif ( $what =~ /^([\w\d_]+)/) {
		die "Invalid preprocessor directive '$1'\n";
	} else {
		# a true comment
	}

	eatline if $eatline;
}

sub parse_file
{
	my $do_output = $_[0];
	my $l;
	my $h = begin_line;
	while ( defined ( $l = getline(1))) {
		if ( !$context->{multiline_comment} and $l =~ s/^#//) {
			$context->{buf} = $l;
			parse_comment( $l);
		} elsif ( $context->{ifdef}->[-1]->{state} and parse_line( $h, $l)) {
			$l = end_line($h);
			print $l if $do_output;
			begin_line($h);
		}
	}
	end_line($h);
	die "Runaway #ifdef\n" if $#{$context->{ifdef}};
}

sub parse_input
{
	my $ih;

	if ( $input eq '-') {
		$input = \*STDIN;
		$context->{file} = 'stdin';
	} elsif ( ! open $ih, "< $input") {
		die "Cannot open $input:$!\n";
	} else {
		$context->{file} = $input;
		$input = $ih;
	}

	if ( defined $output) {
		open OUT, "> $output" or die "Cannot open $output:$!\n";
		select OUT;
	}
}

sub parse_argv
{
	my $dominus = 1;
	for ( my $i = 0; $i < @ARGV; $i++) {

		die "Too many arguments\n" if $input;

		my $d = $ARGV[$i];
		if ( $dominus and $d =~ s/^-//) {
			if ( $d =~ /^I(.+)/ or
				( $d eq 'I' and
					( defined $ARGV[$i+1] or die "Argument required\n") and
					$ARGV[++$i] =~ /(.*)/
				)) {
				push @inc, $1;
			} elsif ( $d =~ /^D(.+)/ or
				( $d eq 'D' and
					( defined $ARGV[$i+1] or die "Argument required\n") and
					$ARGV[++$i] =~ /(.*)/
				)) {
				$d = $1;
				die "Invalid define $d\n" unless $d =~ m/^([^\=]+)(?:\=(.*))?$/;
				my ( $def, $body) = ( $1, $2);
				my $v = begin_macro( $def );
				parse_line( $v, defined($2) ? $2 : '');
				end_macro( $v);
			} elsif ( $d =~ /^o(.+)/ or
				( $d eq 'o' and
					( defined $ARGV[$i+1] or die "Argument required\n") and
					$ARGV[++$i] =~ /(.*)/
				)) {
				die "Output is already defined\n" if defined $output;
				$output = $1;
			} elsif ( $d eq '?' or $d eq 'h' or $d eq '-help') {
				print <<USAGE;
sqlpp - simple SQL preprocessor v$VERSION

sqlpp [options] filename

options:

  -I path   - include path
  -D var[=value] - define variable
  -o output - output to file ( default to stdout )
  -h,--help - display this text
  -hh       - display man page

USAGE
				exit;
			} elsif ( $d eq 'hh') {
				system 'perldoc', $0;
				exit;
			} elsif ( $d eq '-') {
				$dominus = 0;
			} elsif ( $d eq '') {
				$input = '-';
			} else {
				die "Unknown or invalid argument -$d\n";
			}
		} else {
			$input = $d;
		}
	}

	die "No input file\n" unless defined $input;
}

__DATA__

=pod

=head1 NAME

sqlpp - SQL preprocessor

=head1 DESCRIPTION

C<sqlpp> is a conventional cpp-alike preprocessor taught to understand SQL ( PgSQL, in particular)
syntax specificities. In addition to the standard #define/#ifdef/#else/#endif cohort, provides
also #perldef for calling arbitrary perl code.

=head1 SYNOPSIS

sqlpp [options] filename

options:

  -I path   - include path
  -D var[=value] - define variable
  -o output - output to file ( default to stdout )
  -h,--help - display this text
  -hh       - display man page

=head1 COPYRIGHT

Copyright (c) 2005 catpipe Systems ApS. All rights reserved.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=head1 SYNTAX

=over

=item #define TAG

Identical to cpp

=item #define TAG([PARAMETERS]) MACRO

Not fully identical to cpp, the behavior is slightly different. Concatenation
( a ## b ) and stringification ( # a ) behave similar to as in cpp.

The multiline macro can be declared either tranditionally via CPP backslash
line continuation, or a perl's heredoc style. In the latter case, TAG must be prepended
with C<< << >>.

=item #if EXPRESSION

Analogous to cpp.

Note: EXPRESSION is evaluated via perl runtime engine, and although can execute
arbitrary perl code, it is recommended to use simple arithmetic operators. To
operate with defines as strings, use double quotes.

The C<defined()> function works like in cpp, not like in perl.

=item #ifdef, #ifndef, #else, #elif, #endif, #undef, #include, #error

Identical to cpp

=item #pragma macro(simple|all|off)

Pragma C<macro> defines how defines and macros should be tracked and
substituted.  The reason is that SQL code may contain non-SQL code that is so
complicated that would confuse the macro parser. Such sections can be guarded
with C<#pragma macro(simple)>/C<#pragma macro(all)> brackets, for example.

There are three C<macro> modes:

=over

=item off

Neither defines nor macros are substituted.

=item simple

Defines are substituted, macros are not substituted.

=item all

Both defines are macros are substituted.

=back

=item #pragma comments(strip|leave)

Pragma C<comments> tells what to do with C<#> and C<--> comments. The default
is C<strip> these from the output, however, the parts of input that are not
SQL, can be guarded from incorrect parsing by C<#pragma comments(leave)>/
C<#pragma comments(strip)> macros. Note that C<#> comments are
ineffectual in macro definitions, because C<#> is a macro concatenation symbol.

=item #pragma lang(sql|perl)

A combination of existing pragmas.

=over

=item sql

Same as C<#pragma macro(all)> and C<#pragma comments(strip)>. These are defaults settings.

=item perl

Same as C<#pragma macro(simple)> and C<#pragma comments(leave)>.
Useful if perl code is embedded.

=back

=item #perldef TAG [(PARAMETERS)] CODE

Creates a special define or a macro, where CODE is perl code. PARAMETERS is either a list
of perl scalar names ( dollar sign included ), then the code may access the
parameters directly. Or, PARAMETERS is the ellipsis (...) string, in which case
the code must parse C<@_> by itself.

The multiline perl code can be declared either tranditionally via CPP backslash
line continuation, or a perl's heredoc style. In the latter case, TAG must be prepended
with C<< << >>.

The perl code is executed in the anonymous subroutine context, and the return
values are passed to further processing. Perl C<print> and C<printf>
statements may be used to produce direct output into the program output,
bypassign the preprocessing.

For the shared storage the code can use C<%global>; for accessing contents of
defines and macros, C<%defines> and C<%macros> internal hashes may be used.

=item Predefined macros

=over

=item __LINE__

=item __FILE__

=item VERSION

=back

=back

=head1 AUTHOR

<NAME> <<EMAIL>>

=cut
<file_sep># $Id: Makefile.PL,v 1.2 2006/05/16 11:10:39 dk Exp $
use ExtUtils::MakeMaker;
WriteMakefile(
	'NAME'		=> 'sqlpp',
	'VERSION_FROM'	=> 'bin/sqlpp',
	'dist'		=> {
		COMPRESS => 'gzip -9f',
		SUFFIX   => '.gz',
		DIST_DEFAULT => 'all tardist',
	},
	'DISTNAME'	=> 'sqlpp',
	'EXE_FILES'	=> ['bin/sqlpp'],
	'ABSTRACT'	=> 'cpp-like SQL preprocessor',
	'AUTHOR'	=> '<NAME> <<EMAIL>>',
);
<file_sep># $Id: test.t,v 1.5 2006/05/16 11:03:54 dk Exp $
# yes, this is somewhat strange -- but if this fails, everything will as well
1..23
#if $global{num} = 1;
#endif

#perldef test($a,$b) \
	my $ret = ($a eq $b) ? "ok $global{num}\n" : "fail $global{num} ('$a' vs '$b', line $context->{line})\n";\
	$global{num}++;\
	$ret;
#perldef ok \
	sprintf "ok %d\n", $global{num}++;
#perldef fail \
	sprintf "fail %d ( line %d )\n", $global{num}++, $context->{line};

# -- 1
#define a
#ifdef a
ok
#else
fail
#endif

# -- 2
#ifndef a
fail
#else
ok
#endif

# -- 3
#undef a
#ifdef a
fail
#else
ok
#endif

# -- 4
#ifndef a
ok
#else
fail
#endif

# -- 5
#ifdef b
fail
#else
ok
#endif

# -- 6
#ifndef b
ok
#else
fail
#endif

# -- 7
#define p00()
test( p00(), )

# -- 8
#define p01() p01
test( p01(), p01)

# -- 9
# check if a single-line define is not mistaken for a multi-line
#define p_line_a line_a
#define p_line_b line_b
test(p_line_b, line_b)
#undef p_line_a
#undef p_line_b

# -- 10
#define p10(a) a+1
#define p11(a) 1+p10(a)
test(p11(3), 1+3+1)

# -- 11
test(p11((1,2)), 1+(1,2)+1)

# -- 12
#define p20(a,b) a+b
#define p21(a,b,c) p20(a,b)+c
test(p21(1,2,3), 1+2+3)

# -- 13
# check joins
#define j01(a) k ## a ## m
#define j02(a) j ## j01(a)
test(j02(l), jklm)

# -- 14
# check stringification
#define s01(a) # a
#define s02(a) s01(a)
test(s02(l), 'l')

# -- 15
#perldef x3(...) sprintf '%s', join('', @_, @_, @_)
test(x3(1,2), 121212)

# -- 16
#perldef abc "1\n2\n3\n"
#define <<heredoc
1
2
3
heredoc
test( heredoc, abc)

# -- 17
#perldef <<hereperl($a,$b,$c)
"$a\n$b\n$c\n"
hereperl
test( hereperl(1,2,3), abc)

# -- 18
test( hereperl    (1,2,3), abc)

# -- 19
#define A B--comment that should be stripped
test(A,B)
#undef A

#pragma comment(leave)

# -- 20
#define A B--C
test(A,B--C)
#undef A

# -- 21
#perldef A 'B#C'
test(A,B#C)
#undef A

# -- 22
#define A 1
#define B 0
#if 0
#elif A
ok
#elif A
fail
#else
fail
#endif

# --23
#if 0
#elif B
fail
#elif B
fail
#elif B
fail
#else
ok
#endif

#pragma comment(strip)
<file_sep>#!perl
system './blib/script/sqlpp', 'test.t'

languages: Raku Perl

repo_language: Raku

repo_name: gitpan/sqlpp