Skip to content

Commit

Permalink
Actually starting to generate code
Browse files Browse the repository at this point in the history
I'm committing the generated glib for now until
the generator gets to be working properly even
in updated mode
  • Loading branch information
auroraeosrose committed Aug 23, 2012
1 parent 3bdbb27 commit 9cc3ec9
Show file tree
Hide file tree
Showing 10 changed files with 1,354 additions and 8 deletions.
10 changes: 4 additions & 6 deletions TODO.md
Expand Up @@ -21,14 +21,12 @@ Far Future
// 3. actual output location for generation
// 4. logging behavior/location
// 6. do generation
// 4.setup specification
// 1. spec format and location

set up writing
// 2. templates format and location
// 3. what to generate
// 2. parse specification
// 1. choose and load parser format
// 2. parse into array/load
// 3. format check


// 3.a. new - writing
// 1. using spec data, write C files
// 2. using spec data, write test files
Expand Down
1 change: 1 addition & 0 deletions include.php
Expand Up @@ -18,5 +18,6 @@
include $libpath . 'getopt.php';
include $libpath . 'cli.php';
include $libpath . 'extwriter.php';
include $libpath . 'output.php';

unset($libpath);
26 changes: 24 additions & 2 deletions lib/extwriter.php
Expand Up @@ -79,8 +79,13 @@ public function run() {
// load our config - maybe
$config = $this->loadConfig($filename);

// hurray, we have config!
// load our spec file
$spec = $this->loadSpec($config);

// load our output mechanism
$output = $this->loadWriter($config);

$output->writeModule($spec);
}

/**
Expand Down Expand Up @@ -225,7 +230,24 @@ protected function loadSpec($config) {
}
$this->printMessage('Parser loaded for spec type ' . $type);

return new $class($config['specification']);
$spec = new $class($config['specification']);
return $spec->parse();
}

/**
* Starts up a writer instance to use to output our parsed information
*
* @param array $config configuration values
* @return object instanceof writer
*/
protected function loadWriter($config) {

// writer configuration information
if (!isset($config['output'])) {
trigger_error('Writer output settings missing from configuration file', E_USER_ERROR);
}

return new Output($config['output']);
}

/**
Expand Down
195 changes: 195 additions & 0 deletions lib/output.php
@@ -0,0 +1,195 @@
<?php
/**
* output.php - G\Generator\Output class
*
* This is released under the MIT, see LICENSE for details
*
* @author Elizabeth M Smith <auroraeosrose@php.net>
* @copyright Elizabeth M Smith (c) 2012
* @link http://gtkforphp.net
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @since Php 5.4.0
* @package g\generator
* @subpackage lib
*/

/**
* Namespace for the tool
*/
namespace G\Generator;

/**
* Takes information about a module and writes it out using the template
* chosen
*/
class Output {

/**
* our repository
* @var object
*/
protected $repository;

/**
* namespace to modularize
* @var string
*/
protected $namespace;

/**
* version to modularize
* @var string
*/
protected $version;

/**
* module name
* @var string
*/
protected $module;

/**
* authors
* @var array
*/
protected $authors = array();

/**
* Checks for the extension and attempts to require the proper typelib
*
* @return void
*/
public function __construct($config) {

// module name
if (!isset($config['module'])) {
trigger_error('Module name missing in configuration file', E_USER_ERROR);
}
$this->module = $config['module'];

// template location
if (!isset($config['templates'])) {
trigger_error('Template location missing in configuration file', E_USER_ERROR);
}
$templates = realpath($config['templates']);
if (!file_exists($templates)) {
$templates = realpath(__DIR__ . '/../') . DIRECTORY_SEPARATOR . 'templates'
. DIRECTORY_SEPARATOR . $config['templates'] . DIRECTORY_SEPARATOR;
if (!file_exists($templates)) {
trigger_error('Template ' . $templates . ' does not exist', E_USER_ERROR);
}
}
$this->templates = $templates;

// output location
if (!isset($config['location'])) {
trigger_error('Output location missing in configuration file', E_USER_ERROR);
}
$location = $config['location'];

$this->deleteDir($location);
mkdir($location);
$location = realpath($location);
// for now we always generate new
trigger_error('Output will write to ' . $location, E_USER_WARNING);

$this->location = $location . DIRECTORY_SEPARATOR;

if (isset($config['authors'])) {
$this->authors = $config['authors'];
}
}

/**
* Writes out our module
*
* @return void
*/
public function writeModule($spec) {
$classes = array();

// each class gets it's own file class.c
// each class.c file has a boilerplate template with an init

// check for enums
if (isset($spec['enums'])) {
$this->writeEnumFile($spec['enums']);
$classes[] = 'Enums';
}

// finally write out module
$this->writeModuleFile($classes);
}

/**
* Enum File
*
* @return void
*/
protected function writeEnumFile($enums) {
$authors = $this->authors;
$module = strtolower($this->module);
$module_uc = strtoupper($this->module);

ob_start();
include $this->templates . 'enum.c.tpl';
$file = ob_get_clean();
$filename = $this->location . 'enums.c';

file_put_contents($filename, $file);
}

/**
* Module File
*
* @return void
*/
protected function writeModuleFile($raw_classes) {
$year = date('Y');
$authors = $this->authors;
$module = strtolower($this->module);
$module_uc = strtoupper($this->module);
$module_pretty = $this->module;
$generator_version = \G\Generator\ExtWriter::VERSION;
$classes = array();
foreach($raw_classes as $name => $def) {
$classes[] = $this->mangleClassName($name);
}
unset($raw_classes, $name, $def);

ob_start();
include $this->templates . 'module.c.tpl';
$file = ob_get_clean();
$filename = $this->location . 'php_' . $module . '.c';

file_put_contents($filename, $file);
}

/**
* Cleans up our environment
*
* @return void
*/
protected function deleteDir($dir) {
if (!file_exists($dir)) {
return;
}
foreach(glob($dir . '/*') as $file) {
if(is_dir($file)) {
$this->deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dir);
}

/**
* TODO: make this do something
*
* @return void
*/
protected function mangleClassname($name) {
return $name;
}
}
59 changes: 59 additions & 0 deletions parsers/spec/gintrospection.php
Expand Up @@ -24,6 +24,24 @@
*/
class Gintrospection {

/**
* our repository
* @var object
*/
protected $repository;

/**
* namespace to modularize
* @var string
*/
protected $namespace;

/**
* version to modularize
* @var string
*/
protected $version;

/**
* Checks for the extension and attempts to require the proper typelib
*
Expand All @@ -47,5 +65,46 @@ public function __construct($config) {

$this->repository = \G\Introspection\Repository::getDefault();
$this->repository->require($namespace, $version);
$this->namespace = $namespace;
$this->version = $version;
}

/**
* Returns an array? of information about the extension specification?
*
* @return void
*/
public function parse() {
$module = array('enums' => array(), 'classes' => array());
$typelibs = $this->repository->getInfos($this->namespace);

foreach($typelibs as $info) {
if($info instanceof \G\Introspection\EnumInfo) {
$enum = array();
$values = $info->getValues();
foreach($values as $item) {
$enum[$item->getName()] = $item->getAttribute('c:identifier');
}
$module['enums'][$info->getName()] = $enum;
unset($enum, $values, $item);
} elseif (($info instanceof \G\Introspection\StructInfo) ||
($info instanceof \G\Introspection\UnionInfo)) {
$class = array('methods' => array(), 'properties' => array());
$methods = $info->getMethods();
foreach($methods as $method) {
$class['methods'][] = $method->getName();
}
$fields = $info->getFields();
foreach($fields as $field) {
$class['fields'][] = $field->getName();
}

$module['classes'][$info->getName()] = $class;
unset($class, $fields, $field, $methods, $method);
}
}
unset($typelibs, $info);

return $module;
}
}
File renamed without changes.

0 comments on commit 9cc3ec9

Please sign in to comment.