PageRenderTime 104ms CodeModel.GetById 40ms app.highlight 15ms RepoModel.GetById 25ms app.codeStats 21ms

/hphp/system/idl/schema.php

http://github.com/facebook/hiphop-php
PHP | 348 lines | 214 code | 52 blank | 82 comment | 44 complexity | 0c2ed1e7d0c88f5302e7f5756da1fff8 MD5 | raw file
  1<?php
  2
  3require_once 'base.php';
  4
  5$ext = $argv[1];
  6if (file_exists($ext) || preg_match('/\.idl\.php/', $ext)) {
  7  require_once $ext;
  8  $ext = preg_replace('/\.idl\.php/', '', $ext);
  9} else {
 10  require_once "$ext.idl.php";
 11}
 12
 13$net = isset($argv[2]) ? $argv[2] : -1; // 1: always phpnet; 0; auto; -1; no
 14
 15///////////////////////////////////////////////////////////////////////////////
 16
 17$output = <<<CODE
 18<?php
 19/**
 20 * Automatically generated by running "php schema.php $ext".
 21 *
 22 * You may modify the file, but re-running schema.php against this file will
 23 * standardize the format without losing your schema changes. It does lose
 24 * any changes that are not part of schema. Use "note" field to comment on
 25 * schema itself, and "note" fields are not used in any code generation but
 26 * only staying within this file.
 27 *
 28 * @nolint
 29 */
 30///////////////////////////////////////////////////////////////////////////////
 31// Preamble: C++ code inserted at beginning of ext_{name}.h
 32
 33DefinePreamble(<<<CPP
 34$preamble
 35CPP
 36);
 37
 38///////////////////////////////////////////////////////////////////////////////
 39// Constants
 40//
 41// array (
 42//   'name' => name of the constant
 43//   'type' => type of the constant
 44//   'note' => additional note about this constant's schema
 45// )
 46
 47
 48CODE;
 49
 50define_constants($constants);
 51
 52$output .= <<<CODE
 53
 54///////////////////////////////////////////////////////////////////////////////
 55// Functions
 56//
 57// array (
 58//   'name'   => name of the function
 59//   'desc'   => description of the function's purpose
 60//   'flags'  => attributes of the function, see base.php for possible values
 61//   'opt'    => optimization callback function's name for compiler
 62//   'note'   => additional note about this function's schema
 63//   'return' =>
 64//      array (
 65//        'type'  => return type, use Reference for ref return
 66//        'desc'  => description of the return value
 67//      )
 68//   'args'   => arguments
 69//      array (
 70//        'name'  => name of the argument
 71//        'type'  => type of the argument, use Reference for output parameter
 72//        'value' => default value of the argument
 73//        'desc'  => description of the argument
 74//      )
 75// )
 76
 77
 78CODE;
 79
 80foreach ($funcs as $func) {
 81  define_function($func);
 82}
 83
 84$output .= <<<CODE
 85
 86///////////////////////////////////////////////////////////////////////////////
 87// Classes
 88//
 89// BeginClass
 90// array (
 91//   'name'   => name of the class
 92//   'desc'   => description of the class's purpose
 93//   'flags'  => attributes of the class, see base.php for possible values
 94//   'note'   => additional note about this class's schema
 95//   'parent' => parent class name, if any
 96//   'ifaces' => array of interfaces tihs class implements
 97//   'bases'  => extra internal and special base classes this class requires
 98//   'footer' => extra C++ inserted at end of class declaration
 99// )
100//
101// DefineConstant(..)
102// DefineConstant(..)
103// ...
104// DefineFunction(..)
105// DefineFunction(..)
106// ...
107// DefineProperty
108// DefineProperty
109//
110// array (
111//   'name'  => name of the property
112//   'type'  => type of the property
113//   'flags' => attributes of the property
114//   'desc'  => description of the property
115//   'note'  => additional note about this property's schema
116// )
117//
118// EndClass()
119
120
121CODE;
122
123foreach ($classes as $class) {
124  define_class($class);
125}
126
127///////////////////////////////////////////////////////////////////////////////
128
129print $output;
130
131///////////////////////////////////////////////////////////////////////////////
132// output helpers
133
134function idx_flags($arr, $name, $global_function) {
135  return get_flag_names($arr, $name, $global_function);
136}
137
138function idx_type($arr, $name) {
139  return !empty($arr[$name]) ? get_idl_name($arr[$name]) : '';
140}
141
142function idx_string($arr, $name) {
143  // not empty() testing to allow a string of '0'
144  return array_key_exists($name, $arr) ? $arr[$name] : '';
145}
146
147function idx_array($arr, $name) {
148  if (!empty($arr[$name])) {
149    return "array('" . implode("', '", $arr[$name]) . "')";
150  }
151  return '';
152}
153
154function begin_function($name) {
155  global $indent, $output;
156  $output .= str_repeat(' ', $indent) . "$name(\n";
157  $indent += 2;
158}
159
160function end_function() {
161  global $indent, $output;
162  $indent -= 2;
163  $output .= str_repeat(' ', $indent) . ");\n\n";
164}
165
166function begin_array($leading = true) {
167  global $indent, $output;
168  if ($leading) {
169    $output .= str_repeat(' ', $indent);
170  }
171  $output .= "array(\n";
172  $indent += 2;
173}
174
175function end_array($trailing_comma=true) {
176  global $indent, $output;
177  $indent -= 2;
178  $output .= str_repeat(' ', $indent) . ")";
179  if ($trailing_comma) $output .= ",\n";
180}
181
182function push_globals($inc=4) {
183  global $indent, $output, $saved;
184  $saved = $output; $output = '';
185  $indent += $inc;
186}
187
188function pop_globals($dec=4) {
189  global $indent, $output, $saved;
190  $ret = $output; $output = $saved;
191  $indent -= $dec;
192  return $ret;
193}
194
195function out_str($name, $var, $required=false, $formatted=false, $doc=false) {
196  global $indent, $output;
197
198  if ($required && ($var === null || $var === '')) {
199    throw new Exception("missing definition for $name");
200  }
201  if ($required || !($var === null || $var === '')) {
202    $name = str_pad("'$name'", 8);
203    if (!$formatted) {
204      $var = '"'.escape_php($var).'"';
205    }
206    $output .= str_repeat(' ', $indent) . "$name => ";
207    if ($doc) {
208      $output .= "<<<EOT\n$var\nEOT\n,\n";
209    } else {
210      $output .= "$var,\n";
211    }
212  }
213}
214
215function out_fmt($name, $var, $required=false) {
216  return out_str($name, $var, $required, true);
217}
218
219function out_doc($name, $var, $required=false) {
220  return out_str($name, $var, $required, true, true);
221}
222
223function define_class($class) {
224  global $output, $net;
225
226  $name = $class['name'];
227
228  $desc = idx_string($class, 'desc');
229  if ((empty($desc) || $net == 1) && $net != -1) {
230    $desc = phpnet_get_class_desc($name);
231  }
232
233  $output .= "////////////////////////////////////////".
234    "///////////////////////////////////////\n\n";
235  begin_function('BeginClass');
236  begin_array();
237  out_str('name',   $name, true);
238  out_str('parent', $class['parent']);
239  out_fmt('ifaces', idx_array ($class, 'ifaces'));
240  out_fmt('bases',  idx_array ($class, 'bases'));
241  out_str('desc',   $desc);
242  out_fmt('flags',  idx_flags ($class, 'flags', false));
243  out_str('note',   idx_string($class, 'note'));
244  out_doc('footer', idx_string($class, 'footer'));
245  end_array(false);
246  end_function();
247
248  define_constants($class['consts']);
249
250  foreach ($class['methods'] as $func) {
251    define_function($func, $name);
252  }
253
254  define_properties($class['properties']);
255
256  begin_function('EndClass');
257  end_function();
258}
259
260function define_function($func, $clsname = 'function') {
261  global $net;
262
263  $phpnet = false;
264  $desc = idx_string($func, 'desc');
265  if ((empty($desc) || $net == 1) && $net != -1) {
266    $phpnet = phpnet_get_function_info($func['name'], $clsname);
267    if (!empty($phpnet['desc'])) $desc = ($phpnet['desc']);
268  }
269
270  // prepare return type
271  $ret_desc = idx_string($func, 'ret_desc');
272  if ((empty($ret_desc) || $net == 1) && $net != -1) {
273    if (!empty($phpnet['ret'])) $ret_desc = $phpnet['ret'];
274  }
275  push_globals();
276  begin_array(false);
277  out_fmt('type', get_idl_name($func['return'], 'null'));
278  out_str('desc', $ret_desc);
279  end_array(false);
280  $return = pop_globals();
281
282  if ($func['args']) {
283    push_globals();
284    begin_array(false);
285    $i = -1;
286    foreach ($func['args'] as $arg) {
287      $i++;
288      $arg_desc = idx_string($arg, 'desc');
289      if ((empty($arg_desc) || $net == 1) && $net != -1) {
290        if (!empty($phpnet['params'][$i])) {
291          $arg_desc = $phpnet['params'][$i];
292        }
293      }
294      begin_array();
295      out_str('name',  $arg['name'], true);
296      out_fmt('type',  idx_type($arg, 'type'));
297      out_str('value', idx_string($arg, 'default'));
298      out_str('desc',  $arg_desc);
299      end_array();
300    }
301    end_array(false);
302    $args = pop_globals();
303  } else {
304    $args = '';
305  }
306
307  begin_function('DefineFunction');
308  begin_array();
309  out_str('name',   $func['name'], true);
310  out_str('desc',   $desc);
311  out_fmt('flags',  idx_flags($func, 'flags', $clsname == 'function'));
312  out_str('opt',    idx_string($func, 'opt'));
313  out_fmt('return', $return);
314  out_fmt('args',   $args);
315  out_str('note',   idx_string($func, 'note'));
316  end_array(false);
317  end_function();
318}
319
320function define_constants($consts) {
321  foreach ($consts as $constant) {
322    begin_function('DefineConstant');
323    begin_array();
324    out_str('name', $constant['name'], true);
325    if (array_key_exists('value', $constant)) {
326      out_fmt('value', php_escape_val($constant['value'], true), false);
327    } else {
328      out_fmt('type', idx_type($constant, 'type'), true);
329    }
330    out_str('note', idx_string($constant, 'note'));
331    end_array(false);
332    end_function();
333  }
334}
335
336function define_properties($properties) {
337  foreach ($properties as $property) {
338    begin_function('DefineProperty');
339    begin_array();
340    out_str('name',  $property['name'], true);
341    out_fmt('type',  idx_type  ($property, 'type'));
342    out_fmt('flags', idx_flags ($property, 'flags', false));
343    out_str('desc',  idx_string($property, 'desc'));
344    out_str('note',  idx_string($property, 'note'));
345    end_array(false);
346    end_function();
347  }
348}