Ignore:
Timestamp:
Nov 30, 2012, 6:40:43 PM (8 years ago)
Author:
sam
Message:

vslol: add licensing information to important files.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/vslol/MenuGenerateCompilers.cs

    r2118 r2123  
     1//
     2// Lol Engine - VsLol add-in for Visual Studio
     3//
     4// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
     5//   This program is free software; you can redistribute it and/or
     6//   modify it under the terms of the Do What The Fuck You Want To
     7//   Public License, Version 2, as published by Sam Hocevar. See
     8//   http://www.wtfpl.net/ for more details.
     9//
     10
    111using System;
    212using System.Collections;
     
    1626using VSConstants = Microsoft.VisualStudio.VSConstants;
    1727
    18 namespace Lol.VisualStudio.Plugin
     28namespace lol
    1929{
    20     internal class MenuGenerateCompilers : OleMenuCommand
    21     {
    22         public MenuGenerateCompilers(ServiceProvider sp, CommandID id) :
    23             base(new EventHandler(ClickCallback), id, VsLol.ResourceManager.GetString("GenerateCompilersText"))
    24         {
    25             this.sp = sp;
    26             this.projects = new List<Project>();
    27             this.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus);
    28         }
    29 
    30         private void OnBeforeQueryStatus(object sender, EventArgs e)
    31         {
    32             projects.Clear();
    33 
    34             var cmd = sender as OleMenuCommand;
    35             if (cmd == null)
    36                 return;
    37 
    38             IVsMonitorSelection monitorSelection = sp.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection;
    39             if (monitorSelection == null)
    40                 return;
    41 
    42             IntPtr hier = IntPtr.Zero;
    43             UInt32 itemid;
    44             IVsMultiItemSelect multiitem = null;
    45             IntPtr container = IntPtr.Zero;
    46 
     30
     31internal class MenuGenerateCompilers : OleMenuCommand
     32{
     33    public MenuGenerateCompilers(ServiceProvider sp, CommandID id) :
     34        base(new EventHandler(ClickCallback), id, VsLol.ResourceManager.GetString("GenerateCompilersText"))
     35    {
     36        this.sp = sp;
     37        this.projects = new List<Project>();
     38        this.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus);
     39    }
     40
     41    private void OnBeforeQueryStatus(object sender, EventArgs e)
     42    {
     43        projects.Clear();
     44
     45        var cmd = sender as OleMenuCommand;
     46        if (cmd == null)
     47            return;
     48
     49        IVsMonitorSelection monitorSelection = sp.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection;
     50        if (monitorSelection == null)
     51            return;
     52
     53        IntPtr hier = IntPtr.Zero;
     54        UInt32 itemid;
     55        IVsMultiItemSelect multiitem = null;
     56        IntPtr container = IntPtr.Zero;
     57
     58        try
     59        {
     60            monitorSelection.GetCurrentSelection(out hier, out itemid, out multiitem, out container);
     61
     62            /* Bail out if nothing is selected */
     63            if (itemid != VSConstants.VSITEMID_SELECTION && itemid != VSConstants.VSITEMID_NIL)
     64            {
     65                if (hier == IntPtr.Zero)
     66                {
     67                    /* FIXME: parse the whole solution */
     68                }
     69                else
     70                {
     71                    object project = null;
     72
     73                    IVsHierarchy hierarchy = (IVsHierarchy)Marshal.GetObjectForIUnknown(hier);
     74                    hierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out project);
     75                    projects.Add(project as Project);
     76                }
     77            }
     78        }
     79        finally
     80        {
     81            if (hier != IntPtr.Zero)
     82                Marshal.Release(hier);
     83
     84            if (container != IntPtr.Zero)
     85                Marshal.Release(container);
     86        }
     87
     88        // If there are .l or .y files in this project, display the context menu
     89        Visible = false;
     90        foreach (Project project in projects)
     91            foreach (ProjectItem item in ParseProjectItems(project))
     92            {
     93                if (item.Name.EndsWith("-scanner.l")
     94                     || item.Name.EndsWith("-parser.y"))
     95                    Visible = true;
     96            }
     97    }
     98
     99    private static void ClickCallback(object sender, EventArgs args)
     100    {
     101        MenuGenerateCompilers cmd = sender as MenuGenerateCompilers;
     102        if (cmd == null)
     103            return;
     104
     105        Logger.Clear();
     106        Logger.Info("------ Build started: Generating Compilers ------\n");
     107
     108        int scanner_count = 0, parser_count = 0, error_count = 0;
     109
     110        foreach (Project project in cmd.projects)
     111        {
     112            Logger.Info("Project " + project.Name + "\n");
     113
     114            string project_path = Path.GetDirectoryName(project.FullName);
     115
     116            /* FIXME: find this using the solution globals! */
     117            string external_path = project_path;
     118            for (int i = 0; i < 10; ++i)
     119            {
     120                external_path += "\\..";
     121                if (Directory.Exists(external_path + "\\external"))
     122                    break;
     123            }
     124
     125            /* FIXME: do not hardcode shit! */
     126            string flex_path = external_path + "\\external\\flex-2.5.35";
     127            string bison_path = external_path + "\\external\\bison-2.4.2";
     128
     129            /* Workaround for an MSYS bug. If these directories don't
     130             * exist, fork() will fail. Yeah, wtf. */
    47131            try
    48132            {
    49                 monitorSelection.GetCurrentSelection(out hier, out itemid, out multiitem, out container);
    50 
    51                 /* Bail out if nothing is selected */
    52                 if (itemid != VSConstants.VSITEMID_SELECTION && itemid != VSConstants.VSITEMID_NIL)
    53                 {
    54                     if (hier == IntPtr.Zero)
    55                     {
    56                         /* FIXME: parse the whole solution */
    57                     }
    58                     else
    59                     {
    60                         object project = null;
    61 
    62                         IVsHierarchy hierarchy = (IVsHierarchy)Marshal.GetObjectForIUnknown(hier);
    63                         hierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out project);
    64                         projects.Add(project as Project);
    65                     }
    66                 }
    67             }
    68             finally
    69             {
    70                 if (hier != IntPtr.Zero)
    71                     Marshal.Release(hier);
    72 
    73                 if (container != IntPtr.Zero)
    74                     Marshal.Release(container);
    75             }
    76 
    77             // If there are .l or .y files in this project, display the context menu
    78             Visible = false;
    79             foreach (Project project in projects)
    80                 foreach (ProjectItem item in ParseProjectItems(project))
    81                 {
    82                     if (item.Name.EndsWith("-scanner.l")
    83                          || item.Name.EndsWith("-parser.y"))
    84                         Visible = true;
    85                 }
    86         }
    87 
    88         private static void ClickCallback(object sender, EventArgs args)
    89         {
    90             MenuGenerateCompilers cmd = sender as MenuGenerateCompilers;
    91             if (cmd == null)
    92                 return;
    93 
    94             Logger.Clear();
    95             Logger.Info("------ Build started: Generating Compilers ------\n");
    96 
    97             int scanner_count = 0, parser_count = 0, error_count = 0;
    98 
    99             foreach (Project project in cmd.projects)
    100             {
    101                 Logger.Info("Project " + project.Name + "\n");
    102 
    103                 string project_path = Path.GetDirectoryName(project.FullName);
    104 
    105                 /* FIXME: find this using the solution globals! */
    106                 string external_path = project_path;
    107                 for (int i = 0; i < 10; ++i)
    108                 {
    109                     external_path += "\\..";
    110                     if (Directory.Exists(external_path + "\\external"))
    111                         break;
    112                 }
    113 
    114                 /* FIXME: do not hardcode shit! */
    115                 string flex_path = external_path + "\\external\\flex-2.5.35";
    116                 string bison_path = external_path + "\\external\\bison-2.4.2";
    117 
    118                 /* Workaround for an MSYS bug. If these directories don't
    119                  * exist, fork() will fail. Yeah, wtf. */
    120                 try
    121                 {
    122                     Directory.CreateDirectory(flex_path + "\\etc");
    123                     Directory.CreateDirectory(bison_path + "\\etc");
    124                 }
    125                 catch (Exception e) { }
    126 
    127                 // Run flex on all the .l files
    128                 foreach (ProjectItem item in ParseProjectItems(project))
    129                 {
    130                     string filename = item.get_FileNames(0);
    131 
    132                     if (filename.StartsWith(project_path + "\\"))
    133                     {
    134                         filename = filename.Substring(project_path.Length + 1);
    135                         filename = filename.Replace("\\", "/");
    136                     }
    137 
    138                     if (item.Name.EndsWith("-scanner.l"))
    139                     {
    140                         Logger.Info("flex.exe " + filename + "\n");
    141 
    142                         string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-scanner.l")));
    143                         if (!cmd.Run(project_path,
    144                                      flex_path + "\\bin\\flex.exe",
    145                                      "-v -o "
    146                                       + "generated/" + basename + "-scanner.cpp "
    147                                       + filename,
    148                                      ""))
    149                             ++error_count;
    150 
    151                         ++scanner_count;
    152                     }
    153 
    154                     if (item.Name.EndsWith("-parser.y"))
    155                     {
    156                         Logger.Info("bison.exe " + filename + "\n");
    157 
    158                         string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-parser.y")));
    159                         if (!cmd.Run(project_path,
    160                                      bison_path + "\\bin\\bison.exe",
    161                                      "-v -o "
    162                                       + "generated/" + basename + "-parser.cpp "
    163                                       + "--defines=generated/" + basename + "-parser.h "
    164                                       + "-d "
    165                                       + "-b "
    166                                       + "generated/" + basename + " "
    167                                       + filename,
    168                                      "BISON_PKGDATADIR=" + bison_path + "\\share\\bison"))
    169                             ++error_count;
    170 
    171                         ++parser_count;
    172                     }
    173                 }
    174             }
    175 
    176             Logger.Info(string.Format("========== Done: {0} scanner(s), {1} parser(s), {2} error(s) ==========\n",
    177                                   scanner_count, parser_count, error_count));
    178         }
    179 
    180         bool Run(string directory, string executable, string arguments, string env)
    181         {
    182             System.Diagnostics.Process p = new System.Diagnostics.Process();
    183             p.StartInfo.FileName = executable;
    184             p.StartInfo.Arguments = arguments;
    185             foreach (string s in env.Split(new char[]{'\n'}, StringSplitOptions.RemoveEmptyEntries))
    186             {
    187                 int i = s.IndexOf("=");
    188                 if (i > 0 && i < s.Length - 1)
    189                     p.StartInfo.EnvironmentVariables[s.Substring(0, i - 1)] = s.Substring(i + 1);
    190             }
    191             p.StartInfo.WorkingDirectory = directory;
    192             p.StartInfo.CreateNoWindow = true;
    193             p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    194             p.StartInfo.RedirectStandardError = true;
    195             p.StartInfo.RedirectStandardOutput = true;
    196             p.StartInfo.RedirectStandardInput = true;
    197             p.StartInfo.UseShellExecute = false;
    198 
    199             try
    200             {
    201                 p.Start();
    202                 string output = p.StandardError.ReadToEnd()
    203                               + p.StandardOutput.ReadToEnd();
    204                 p.WaitForExit();
    205                 Logger.Info(output);
    206                 if (p.ExitCode != 0)
    207                 {
    208                     Logger.Info("Error: " + executable + " exited with code " + p.ExitCode + "\n");
    209                     if (arguments != "")
    210                         Logger.Info("Error: args: " + arguments + "\n");
    211                     if (env != "")
    212                         Logger.Info("Error: env: " + env + "\n");
    213                     return false;
    214                 }
    215             }
    216             catch (Exception e)
    217             {
    218                 Logger.Info("Error: failed to launch " + executable + "\n");
     133                Directory.CreateDirectory(flex_path + "\\etc");
     134                Directory.CreateDirectory(bison_path + "\\etc");
     135            }
     136            catch (Exception e) { }
     137
     138            // Run flex on all the .l files
     139            foreach (ProjectItem item in ParseProjectItems(project))
     140            {
     141                string filename = item.get_FileNames(0);
     142
     143                if (filename.StartsWith(project_path + "\\"))
     144                {
     145                    filename = filename.Substring(project_path.Length + 1);
     146                    filename = filename.Replace("\\", "/");
     147                }
     148
     149                if (item.Name.EndsWith("-scanner.l"))
     150                {
     151                    Logger.Info("flex.exe " + filename + "\n");
     152
     153                    string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-scanner.l")));
     154                    if (!cmd.Run(project_path,
     155                                 flex_path + "\\bin\\flex.exe",
     156                                 "-v -o "
     157                                  + "generated/" + basename + "-scanner.cpp "
     158                                  + filename,
     159                                 ""))
     160                        ++error_count;
     161
     162                    ++scanner_count;
     163                }
     164
     165                if (item.Name.EndsWith("-parser.y"))
     166                {
     167                    Logger.Info("bison.exe " + filename + "\n");
     168
     169                    string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-parser.y")));
     170                    if (!cmd.Run(project_path,
     171                                 bison_path + "\\bin\\bison.exe",
     172                                 "-v -o "
     173                                  + "generated/" + basename + "-parser.cpp "
     174                                  + "--defines=generated/" + basename + "-parser.h "
     175                                  + "-d "
     176                                  + "-b "
     177                                  + "generated/" + basename + " "
     178                                  + filename,
     179                                 "BISON_PKGDATADIR=" + bison_path + "\\share\\bison"))
     180                        ++error_count;
     181
     182                    ++parser_count;
     183                }
     184            }
     185        }
     186
     187        Logger.Info(string.Format("========== Done: {0} scanner(s), {1} parser(s), {2} error(s) ==========\n",
     188                              scanner_count, parser_count, error_count));
     189    }
     190
     191    bool Run(string directory, string executable, string arguments, string env)
     192    {
     193        System.Diagnostics.Process p = new System.Diagnostics.Process();
     194        p.StartInfo.FileName = executable;
     195        p.StartInfo.Arguments = arguments;
     196        foreach (string s in env.Split(new char[]{'\n'}, StringSplitOptions.RemoveEmptyEntries))
     197        {
     198            int i = s.IndexOf("=");
     199            if (i > 0 && i < s.Length - 1)
     200                p.StartInfo.EnvironmentVariables[s.Substring(0, i - 1)] = s.Substring(i + 1);
     201        }
     202        p.StartInfo.WorkingDirectory = directory;
     203        p.StartInfo.CreateNoWindow = true;
     204        p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
     205        p.StartInfo.RedirectStandardError = true;
     206        p.StartInfo.RedirectStandardOutput = true;
     207        p.StartInfo.RedirectStandardInput = true;
     208        p.StartInfo.UseShellExecute = false;
     209
     210        try
     211        {
     212            p.Start();
     213            string output = p.StandardError.ReadToEnd()
     214                          + p.StandardOutput.ReadToEnd();
     215            p.WaitForExit();
     216            Logger.Info(output);
     217            if (p.ExitCode != 0)
     218            {
     219                Logger.Info("Error: " + executable + " exited with code " + p.ExitCode + "\n");
     220                if (arguments != "")
     221                    Logger.Info("Error: args: " + arguments + "\n");
     222                if (env != "")
     223                    Logger.Info("Error: env: " + env + "\n");
    219224                return false;
    220225            }
    221 
    222             return true;
    223         }
    224 
    225         private static IEnumerable<ProjectItem> ParseProjectItems(object o)
    226         {
    227             ProjectItems subitems;
    228             if (o is Project)
    229             {
    230                 subitems = (o as Project).ProjectItems;
    231             }
    232             else
    233             {
    234                 yield return (o as ProjectItem);
    235                 subitems = (o as ProjectItem).ProjectItems;
    236             }
    237 
    238             foreach (ProjectItem item in subitems)
    239                 foreach (ProjectItem i in ParseProjectItems(item))
    240                     yield return i;
    241         }
    242 
    243         private ServiceProvider sp;
    244 
    245         private List<Project> projects;
    246     }
     226        }
     227        catch (Exception e)
     228        {
     229            Logger.Info("Error: failed to launch " + executable + "\n");
     230            return false;
     231        }
     232
     233        return true;
     234    }
     235
     236    private static IEnumerable<ProjectItem> ParseProjectItems(object o)
     237    {
     238        ProjectItems subitems;
     239        if (o is Project)
     240        {
     241            subitems = (o as Project).ProjectItems;
     242        }
     243        else
     244        {
     245            yield return (o as ProjectItem);
     246            subitems = (o as ProjectItem).ProjectItems;
     247        }
     248
     249        foreach (ProjectItem item in subitems)
     250            foreach (ProjectItem i in ParseProjectItems(item))
     251                yield return i;
     252    }
     253
     254    private ServiceProvider sp;
     255
     256    private List<Project> projects;
    247257}
    248258
     259} /* namespace lol */
Note: See TracChangeset for help on using the changeset viewer.